總和的 A/B 測試比率
語境
考慮一家在線銷售商品的公司的以下場景。一個用戶可以購買多個項目(即一籃子項目),其中一些特別重要並且被專門跟踪(我們稱它們為明星項目)。
我們希望測試算法的變化(例如推薦、風險評估、添加目標等等……),這可能會影響明星商品的銷售數量和總銷售額。
- 這是一個標準的 A/B 測試設置 -隨機化單元位於用戶級別。
- A/B測試的目的是比較算法變化的影響:對照組有原始算法,變體有新算法
- 一個關鍵的興趣指標被定義為明星商品銷售額與總銷售額的比率。這是每個 A 或 B 組範圍內所有用戶的所有事務的總和。
- 這意味著分析單元處於事務級別,與隨機化單元不同
- 在整個測試期間(例如 2 週)計算指標
所用指標的詳細信息
給定組 A 和一組用戶 $ U_A = {u_1,u_2,…,u_{N_A} } $ ,每個用戶都參與了一個數字 $ t_{u_n} $ 的交易。套裝 $ T_A $ 在測試期間,A 組中所有用戶的所有交易是 $ T_A = { t_{u_{11}}, t_{u_{12}}, … t_{u_{nm} } } $ .
組 A 感興趣的度量是針對組 A 範圍內的所有事務定義的。總和是在事務級別,而不是用戶級別。
$$ \text{Metric}A = \frac{\sum{t_{i} \in T_A} \text{sales star items }$}{\sum_{t_{i} \in T_A} \text{sales }$ } $$
當然,我們可以修改定義來計算用戶級別的平均值,這將簡化一切,但這不是正在使用的指標。
問題
什麼樣的統計檢驗可以用於這樣的度量?另一個考慮因素是,儘管我們可以安全地假設用戶是 iid,但假設單個購買籃對於同一用戶來說是 iid 很可能是錯誤的。
以下是我遇到的一些想法,過去是否有任何 A/B 測試從業者遇到過類似的指標?
- 比例 z 檢驗
- 自舉和折刀
- 增量法
- 更改指標(最後的手段)
https://en.wikipedia.org/wiki/Ratio_estimator
編輯 - 一些說明
這個問題背後的原因是我經常看到在這種情況下使用比例的 z 檢驗。用於 A/B 測試的流行工具通常默認使用比例測試,業務用戶很少檢查測試有效所需的基本假設。@dnqxt 下面的答案就是一個很好的例子:“只需使用 z 比例檢驗!” - 但我希望看到一個嚴格的統計理由來說明為什麼(或為什麼不)這個測試可以在這種情況下使用。
我個人認為使用比例 z 檢驗在這裡不起作用,因為購買事件的銷售不是伯努利試驗。我認為我們不能說以分母出售的每一美元都可以被視為伯努利試驗,導致分子出售 0 或 1 個星項目美元。此外,由於隨機化單元處於用戶級別,同一用戶的購買事件不是獨立的(但我認為這是次要問題)。我在這裡可能是錯的,所以請隨時證明這一點!
我們還可以更改度量,使其成為伯努利/二項式,通過使用計數收斂到正常,但這將是最後的解決方案
$$ \frac{# \text{sales with star items} }{# \text{sales}} $$
- 比例 z 檢驗
當您有二元結果時,這適用於不同的情況。比例的 z 檢驗比較了這些二元結果的比例。
(下面的一些論點是您將能夠進行 t 檢驗,對於大數而言,這與 z 檢驗大致相同。對於比例,您可以進行 z 檢驗,因為二項式分佈有一個參數來確定方差和均值,與正態分佈不同)
- 自舉
這將是可能的,但並不是真正必要的,因為 Delta 方法可以更直接地提供您觀察到的統計數據的錯誤。
- 增量法
您對兩個可能相關的變量的比率感興趣:1. 總銷售額和 2. 明星商品的銷售額。
這些變量可能是漸近正態分佈的,因為它們是來自許多個人的銷售額的總和(測試過程可以被認為是一個過程,例如從個人用戶的銷售額分佈中挑選個人用戶的銷售額樣本)。因此,您可以使用 Delta 方法。
此處描述了使用 Delta 方法估計比率的方法。Delta 方法的這種應用的結果實際上與Hinkley 的結果的近似值一致,這是兩個相關正態分佈變量的比率的精確表達式(Hinkley DV,1969,關於兩個相關正態隨機變量的比率,Biometrica vol. 56第 3 號)。
(旁注:正如西安在評論中所指出的,George Marsaglia 1965 年在JASA 第 60 卷第 309 期中給出了更早的準確表達描述。2006 年在Jstatsoft 第 16 卷第 4 期中給出了簡單的現代描述)
為了 $ Z = \frac{X}{Y} $ 和$$ \begin{bmatrix}X\Y\end{bmatrix} \sim N\left(\begin{bmatrix} \mu_x \ \mu_y \end{bmatrix} , \begin{bmatrix} \sigma_x^2 & \rho \sigma_x \sigma_y \ \rho \sigma_x \sigma_y & \sigma_y^2 \end{bmatrix} \right) $$ 確切的結果是: $$ f(z) = \frac{b(z)d(z)}{a(z)^3} \frac{1}{\sqrt{2\pi} \sigma_X\sigma_Y} \left[ \Phi \left( \frac{b(z)}{\sqrt{1-\rho^2}a(z)} \right) - \Phi \left( - \frac{b(z)}{\sqrt{1-\rho^2}a(z)} \right) \right] + \frac{\sqrt{1-\rho^2}}{\pi \sigma_X \sigma_Y a(z)^2} \exp \left( -\frac{c}{2(1-\rho^2)}\right) $$和$$ \begin{array}{} a(z) &=& \left( \frac{z^2}{\sigma_X^2} - \frac{2 \rho z}{\sigma_X \sigma_Y} + \frac{1}{\sigma_Y^2} \right) ^{\frac{1}{2}} \ b(z) &=& \frac{\mu_X z}{ \sigma_X^2} - \frac{\rho (\mu_X+ \mu_Y z)}{ \sigma_X \sigma_Y} + \frac{\mu_Y}{\sigma_Y^2} \ c &=& \frac{\mu_X^2}{\sigma_Y^2} - \frac{2 \rho \mu_X \mu_Y + }{\sigma_X \sigma_Y} + \frac{\mu_Y^2}{\sigma_Y^2}\ d(z) &=& \text{exp} \left( \frac {b(z)^2 - c a(z) ^2}{2(1-\rho^2)a(z)^2}\right) \end{array} $$ 基於漸近行為的近似值是:(對於 $ \mu_Y/\sigma_Y \to \infty $ ):$$ F(z) \to \Phi\left( \frac{z - \mu_X/\mu_Y}{\sigma_X \sigma_Y a(z)/\mu_Y} \right) $$ 當您插入近似值時,您最終會得到 Delta 方法的結果 $ a(z) = a(\mu_X/\mu_Y) $ $$ a(z) \sigma_X \sigma_Y /\mu_Y \approx a(\mu_X/\mu_Y) \sigma_X \sigma_Y /\mu_Y = \left( \frac{\mu_X^2\sigma_Y^2}{\mu_Y^4} - \frac{2 \mu_X \rho \sigma_X \sigma_Y}{\mu_Y^3} + \frac{\sigma_X^2}{\mu_Y^2} \right) ^{\frac{1}{2}} $$
的值 $ \mu_X,\mu_Y,\sigma_X,\sigma_Y,\rho $ 可以從您的觀察中估計,這允許您估計單個用戶的分佈的方差和均值,並且與此相關的是多個用戶總和的樣本分佈的方差和均值。
- 更改指標
我相信至少對單個用戶的銷售額(而不是比率)分佈進行初步繪圖是很有趣的。最終您可能會遇到 A 組和 B 組中的用戶之間存在差異的情況*,*但是當您考慮比率的單個變量時,它恰好並不顯著(這有點類似於 MANOVA更強大比單一的方差分析測試)。
雖然了解組間差異,但您感興趣的指標沒有顯著差異,可能對您做出決策沒有太大幫助,但它確實有助於您理解基礎理論,並可能在下次設計更好的更改/實驗。
插圖
下面是一個簡單的說明:
讓來自用戶的銷售的假設分佈分佈為分數 $ a,b,c,d $ 這表明有多少用戶屬於特定情況(實際上這種分佈會更複雜):
star item sales 0$ 40$ other item sales 0$ a b 10$ c d
然後是具有 10000 個用戶的組的總數的樣本分佈,使用一種算法$$ a=0.190,b=0.001,c=0.800,d=0.009 $$和其他算法$$ a=0.170,b=0.001,c=0.820,d=0.009 $$看起來像:
其中顯示 10000 次運行吸引新用戶併計算銷售額和比率。直方圖用於比率的分佈。這些線是使用來自 Hinkley 的函數進行的計算。
- 您可以看到兩個總銷售額的分佈近似為多元正態分佈。比率的等值線表明,您可以很好地估計比率作為線性和(如前面提到的/鏈接的線性化 Delta 方法),並且高斯分佈的近似值應該可以很好地工作(然後您可以使用 t-測試大數字就像 z 測試一樣)。
- 您還可以看到,與僅使用直方圖相比,這樣的散點圖可能會為您提供更多信息和洞察力。
用於計算圖形的 R 代碼:
set.seed(1) # # # function to sampling hypothetic n users # which will buy star items and/or regular items # # star item sales # 0$ 40$ # # regular item sales 0$ a b # 10$ c d # # sample_users <- function(n,a,b,c,d) { # sampling q <- sample(1:4, n, replace=TRUE, prob=c(a,b,c,d)) # total dolar value of items dri = (sum(q==3)+sum(q==4))*10 dsi = (sum(q==2)+sum(q==4))*40 # output list(dri=dri,dsi=dsi,dti=dri+dsi, q=q) } # # function for drawing those blocks for the tilted histogram # block <- function(phi=0.045+0.001/2, r=100, col=1) { if (col == 1) { bgs <- rgb(0,0,1,1/4) cols <- rgb(0,0,1,1/4) } else { bgs <- rgb(1,0,0,1/4) cols <- rgb(1,0,0,1/4) } angle <- c(atan(phi+0.001/2),atan(phi+0.001/2),atan(phi-0.001/2),atan(phi-0.001/2)) rr <- c(90000,90000+r,90000+r,90000) x <- cos(angle)*rr y <- sin(angle)*rr polygon(x,y,col=cols,bg=bgs) } block <- Vectorize(block) # # function to compute Hinkley's density formula # fw <- function(w,mu1,mu2,sig1,sig2,rho) { #several parameters aw <- sqrt(w^2/sig1^2 - 2*rho*w/(sig1*sig2) + 1/sig2^2) bw <- w*mu1/sig1^2 - rho*(mu1+mu2*w)/(sig1*sig2)+ mu2/sig2^2 c <- mu1^2/sig1^2 - 2 * rho * mu1 * mu2 / (sig1*sig2) + mu2^2/sig2^2 dw <- exp((bw^2 - c*aw^2)/(2*(1-rho^2)*aw^2)) # output from Hinkley's density formula out <- (bw*dw / ( sqrt(2*pi) * sig1 * sig2 * aw^3)) * (pnorm(bw/aw/sqrt(1-rho^2),0,1) - pnorm(-bw/aw/sqrt(1-rho^2),0,1)) + sqrt(1-rho^2)/(pi*sig1*sig2*aw^2) * exp(-c/(2*(1-rho^2))) out } fw <- Vectorize(fw) # # function to compute # theoretic distribution for sample with parameters (a,b,c,d) # lazy way to compute the mean and variance of the theoretic distribution fwusers <- function(na,nb,nc,nd,n=10000) { users <- c(rep(1,na),rep(2,nb),rep(3,nc),rep(4,nd)) dsi <- c(0,40,0,40)[users] dri <- c(0,0,10,10)[users] dti <- dsi+dri sig1 <- sqrt(var(dsi))*sqrt(n) sig2 <- sqrt(var(dti))*sqrt(n) cor <- cor(dti,dsi) mu1 <- mean(dsi)*n mu2 <- mean(dti)*n w <- seq(0,1,0.001) f <- fw(w,mu1,mu2,sig1,sig2,cor) list(w=w,f=f,sig1 = sig1, sig2=sig2, cor = cor, mu1= mu1, mu2 = mu2) } # sample many ntr time to display sample distribution of experiment outcome ntr <- 10^4 # sample A dsi1 <- rep(0,ntr) dti1 <- rep(0,ntr) for (i in 1:ntr) { users <- sample_users(10000,0.19,0.001,0.8,0.009) dsi1[i] <- users$dsi dti1[i] <- users$dti } # sample B dsi2 <- rep(0,ntr) dti2 <- rep(0,ntr) for (i in 1:ntr) { users <- sample_users(10000,0.19-0.02,0.001,0.8+0.02,0.009) dsi2[i] <- users$dsi dti2[i] <- users$dti } # hiostograms for ratio ratio1 <- dsi1/dti1 ratio2 <- dsi2/dti2 h1<-hist(ratio1, breaks = seq(0, round(max(ratio2+0.04),2), 0.001)) h2<-hist(ratio2, breaks = seq(0, round(max(ratio2+0.04),2), 0.001)) # plotting plot(0, 0, xlab = "sum of total sales", ylab = "sum of star item sales", xlim = c(82000,92000), ylim = c(2500,6000), pch=21, col = rgb(0,0,1,1/10), bg = rgb(0,0,1,1/10)) title("sample distribution for sum of 10 000 users") # isolines brks <- seq(0, round(max(ratio2+0.02),2), 0.001) for (ls in 1:length(brks)) { col=rgb(0,0,0,0.25+0.25*(ls%%5==1)) lines(c(0,10000000),c(0,10000000)*brks[ls],lty=2,col=col) } # scatter points points(dti1, dsi1, pch=21, col = rgb(0,0,1,1/10), bg = rgb(0,0,1,1/10)) points(dti2, dsi2, pch=21, col = rgb(1,0,0,1/10), bg = rgb(1,0,0,1/10)) # diagonal axis phi <- atan(h1$breaks) r <- 90000 lines(cos(phi)*r,sin(phi)*r,col=1) # histograms phi <- h1$mids r <- h1$density*10 block(phi,r,col=1) phi <- h2$mids r <- h2$density*10 block(phi,r,col=2) # labels for histogram axis phi <- atan(h1$breaks)[1+10*c(1:7)] r <- 90000 text(cos(phi)*r-130,sin(phi)*r,h1$breaks[1+10*c(1:7)],srt=-87.5,cex=0.9) text(cos(atan(0.045))*r-400,sin(atan(0.045))*r,"ratio of sum of star items and sum of total items", srt=-87.5,cex=0.9) # plotting functions for Hinkley densities using variance and means estimated from theoretic samples distribution wf1 <- fwusers(190,1,800,9,10000) wf2 <- fwusers(170,1,820,9,10000) rf1 <- 90000+10*wf1$f phi1 <- atan(wf1$w) lines(cos(phi1)*rf1,sin(phi1)*rf1,col=4) rf2 <- 90000+10*wf2$f phi2 <- atan(wf2$w) lines(cos(phi2)*rf2,sin(phi2)*rf2,col=2)