Wie kann man den Unterschied in zwei Proportionen testen, wenn die Ergebnisse nicht binär sind?

7

Eine E-Commerce-Website testet zwei verschiedene Designs für eine Checkout-Seite. Kunden, die die Checkout-Seite besuchen, erhalten zufällig eines der beiden Designs.

Die erste Metrik von Interesse, die Umsatzsteigerung, kann gemessen werden, indem der Anteil der Kunden, die den Verkauf abgeschlossen haben (ein binäres Ergebnis), für jedes der beiden Designs verglichen wird.

Es ist ziemlich einfach, diese mit einem Test für zwei Anteile zu vergleichen.

Eine zweite Zinsmetrik ist die Dollarumrechnung. Dies ist der endgültige Dollarwert des Verkaufs als Anteil am anfänglichen Dollarwert des eingehenden Einkaufswagens.

Beispiel: Ein Kunde kommt zur Kasse mit Artikeln im Wert von 160 USD im Warenkorb (Anfangswert). Der Kunde nimmt einige Artikel aus dem Warenkorb und schließt den Verkauf für Artikel im Wert von 40 USD ab (Endwert). Die Umsatzumrechnung beträgt 100% (wir haben dem Kunden noch etwas verkauft ), aber die Dollarumrechnung beträgt nur 25%.

Wie kann ich den Unterschied in der Dollarumrechnung für die beiden Gruppen gegen eine Nullhypothese ohne Unterschied testen?

Im Folgenden finden Sie einen R-Code, der das Problem spezifiziert:

# example data
set.seed(1)
total_customers <- 1000
target_control <- rbinom(total_customers, 1, 0.5)
sale_success <- rbinom(total_customers, 1, 0.1)
initial_value <- rexp(total_customers, rate=0.1) 
final_value <- runif(total_customers, 0, 1.1) * initial_value * sale_success
sales_data <- data.frame(target_control, sale_success, initial_value, final_value)

# sales conversion - test for two proportions (two-tailed)
n1 <- sum(target_control)
n2 <- sum(!target_control)
p1 <- sum(sales_data[target_control==1,"sale_success"])/n1
p2 <- sum(sales_data[target_control==0,"sale_success"])/n2
pbar <- (p1*n1+p2*n2)/(n1+n2)
z <- (p1-p2)/sqrt(pbar*(1-pbar)/n1+pbar*(1-pbar)/n2)
pval <- 2*(1-pnorm(abs(z)))

# dollar conversion - ??
p1 <- sum(sales_data[target_control==1,"final_value"])/sum(sales_data[target_control==1,"initial_value"])
p2 <- sum(sales_data[target_control==0,"final_value"])/sum(sales_data[target_control==0,"initial_value"])

Einige Dinge zu beachten:

  • Anfangswert und Endwert sind korreliert
  • Anfangs- und Endwert folgen beide einer Long-Tail-Verteilung, z. B. der negativen Exponentialverteilung
  • Manchmal ist der Endwert größer als der Anfangswert, z. B. fügt der Kunde dem Warenkorb mehr hinzu, bevor er den Verkauf abschließt
  • Verkaufserfolg und Anfangswert sind korreliert, aber ich habe dies im Beispielcode nicht angegeben

Update 1: Brumar hat vorgeschlagen, dass die Verhaltensänderung auf Kundenebene für diejenigen Kunden, die einen Verkauf abschließen, mit einem Wilcoxon-Rang-Summen-Test verglichen werden kann:

sales_data\$ratios=final_value/initial_value
ratios_A=sales_data\$ratios[sale_success==1 & target_control==0]
ratios_B=sales_data\$ratios[sale_success==1 & target_control==1]
wilcox.test(ratios_A,ratios_B)

Ich bin immer noch daran interessiert zu wissen, ob es eine Möglichkeit gibt, den Unterschied in der gesamten Dollarumrechnung zu vergleichen, dh die Summe der Endwerte über die Summe der Anfangswerte.


Update 2: Gelöst von Brumar.

# permutation test (two-tailed)
p1 <- sum(sales_data[target_control==1 & sale_success==1,"final_value"])/sum(sales_data[target_control==1 & 
p2 <- sum(sales_data[target_control==0 & sale_success==1,"final_value"])/sum(sales_data[target_control==0 & 
yourGap<-p1-p2
L<-sales_data[,"target_control"]==1
LfilterOnlyBuyers<-sales_data[,"sale_success"]==1

nulldist <- vector(mode="numeric", length=10000)
for ( i in 1:10000) {
    Lperm <- sample(L) 
    LpermInv <- !Lperm & LfilterOnlyBuyers
    Lperm <- Lperm & LfilterOnlyBuyers

    p1_perm <- sum(sales_data[Lperm,"final_value"])/sum(sales_data[Lperm,"initial_value"])
    p2_perm <- sum(sales_data[LpermInv,"final_value"])/sum(sales_data[LpermInv,"initial_value"]    )
    nulldist[i] = p1_perm-p2_perm
}
pvalue=sum(abs(nulldist) > yourGap)/10000
alpha=0.05
ci_upper <- yourGap + quantile(nulldist, (1-alpha/2))
ci_lower <- yourGap - quantile(nulldist, (1-alpha/2))
logworthy
quelle

Antworten:

4

Der erste Teil erscheint in der Tat vernünftig.
In Bezug auf den zweiten Teil denke ich, dass diese Verhältnisse nicht als Proportionen behandelt werden können, da sie nicht mit binären Ereignissen zusammenhängen. Dies bedeutet, dass wir keine Ahnung haben, wie diese Verhältnisse verteilt sind, was den Z-Test ausschließt (naja, es sei denn, Sie haben Glück empirische Normalverteilung, aber Sie haben erwähnt, nicht zu haben).

Erster Vorschlag: Wilcoxon-Test.
Mein Vorschlag wäre, diese Verhältnisse einfach durch einen Wilcoxon-Test zu vergleichen.

>sales_data$ratios=final_value/initial_value
>ratios_A=sales_data$ratios[sale_success==1 & target_control==0]
>ratios_B=sales_data$ratios[sale_success==1 & target_control==1]
>wilcox.test(ratios_A,ratios_B)

Wenn Sie zweimal darüber nachdenken, wird bei diesem Test "1 Dollar für 5 Dollar gekauft" das gleiche ausgewählt wie "100 Dollar für 500 Dollar gekauft". Ich kann verstehen, warum Sie es vermeiden und Ihr Gesamtverhältnis bevorzugen wollen.

Zweiter Satz: Permutationstest.

Um Ihr Maß zu halten, würde ich dann vorschlagen, "Ihren eigenen Test" mit einem Permutationstest zu erstellen . Unter der Nullhypothese macht es keinen Unterschied, ob es sich um eine Zufalls- oder eine Behandlungsgruppe handelt. Dann besteht die Idee darin, zufällig neu zu kennzeichnen, welche Probanden in der Kontroll- oder Behandlungsgruppe sind, und zu zählen, wie oft eine randomisierte Permutation eine gleiche oder bessere Lücke zwischen Kontroll- und Behandlungsgruppe ergibt als die, die Sie ursprünglich messen. Diese Lücke wird anhand der Differenz Ihres Verhältnisses zwischen den beiden Gruppen gemessen. Wenn Sie diese Anzahl der Erfolge durch die Anzahl der Versuche teilen, erhalten Sie einen p-Wert.

p1 <- sum(sales_data[target_control==1,"final_value"])/sum(sales_data[target_control==1,"initial_value"])
p2 <- sum(sales_data[target_control==0,"final_value"])/sum(sales_data[target_control==0,"initial_value"])
yourGap<-abs(p1-p2)
L<-sales_data["target_control"]==1
LfilterOnlyBuyers<-sales_data["sale_success"]==1

count=0
for ( i in 1:10000) {
  Lperm=sample(L)
  p1_perm <- sum(sales_data[Lperm,"final_value"])/sum(sales_data[Lperm & LfilterOnlyBuyers,"initial_value"])
  p2_perm <- sum(sales_data[!Lperm,"final_value"])/sum(sales_data[!Lperm & LfilterOnlyBuyers,"initial_value"])
  if (abs(p1_perm-p2_perm)>=yourGap) {
    count=count+1
  }
}
pvalue=count/10000

Verwenden Sie absolute Werte, wenn Sie Ihre Lücke berechnen, wenn Sie einen Zwei-Schwanz-Test durchführen möchten.

In diesem Permutationstest habe ich, wie im von mir vorgeschlagenen Wilcoxon, Nichtkäufer herausgefiltert. Die Idee dahinter ist, dass Sie nicht wollen, dass die erste Hypothese, die Sie getestet haben, hier ins Spiel kommt. Sie können es vorziehen, beide Annahmen zu trennen 1) sie kaufen weniger / häufiger 2) wenn sie kaufen, ist es näher / weiter als der ursprünglich ausgewählte Betrag.

brumar
quelle
Vielen Dank für Ihre Antwort. Wenn ich das richtig verstehe, trennt dieser Ansatz diejenigen Kunden, die den Verkauf abgeschlossen haben, und fragt, ob sich das Verhalten dieser Kunden geändert hat. Dies ist eine nützliche Methode, um das Problem zu betrachten, und etwas, über das ich nicht richtig nachgedacht hatte. Es wäre immer noch interessant zu wissen, ob es eine Möglichkeit gibt, den Unterschied in der gesamten Dollarumrechnung zu testen. Das heißt, die Summe der endgültigen Verkäufe über die Summe der Anfangswerte?
Logworthy
Vielen Dank für Ihren Kommentar. Ich habe Ihre Frage noch einmal angeschaut und meine Antwort mit einer neuen Lösung bearbeitet. Ich erkläre auch, warum ich Käufer ausgewählt habe, auch wenn ich sehe, dass Sie das richtig aufgenommen haben.
Brumar
Oh! Sehr interessant :) Ich habe einige Änderungen vorgenommen und den aktualisierten Code zur Frage hinzugefügt - 1. p1 & p2 müssen auch nur für Käufer filtern; 2. Ihre Syntax zum Festlegen von L und LfilterOnlyBuyers hat bei mir nicht funktioniert. 3. Die Filterung für Käufer muss nach der Inversion von Lperm erfolgen. Wenn ich das richtig verstehe, kann ich auch die Verteilung speichern und die Quantile der Verteilung verwenden, um ein Konifdenzintervall zu erstellen.
Logworthy
Oh ! in der Tat, danke, dass du meine Fehler aufgegriffen hast. Ich habe dann auch meine Antwort aktualisiert. Ich glaube nicht, dass Sie die Verteilung der Null um Ihren Wert legen können. Vielleicht haben Sie die Dinge mit dem Bootstraping-Verfahren verwechselt, das tatsächlich die Berechnung eines Konfidenzintervalls ermöglichen könnte. Noch ein Hinweis: Ich denke, dass für einen zweiseitigen Test yourGap auch ein absoluter Wert sein muss (wenn er negativ ist, haben Sie keine Chance, die Null abzulehnen).
Brumar
@brumar könntest du hier einen Blick darauf werfen? Danke ! stats.stackexchange.com/questions/398436/…
Xavier Bourret Sicotte