一个电子商务网站正在测试结帐页面的两种不同设计。访问结帐页面的客户会随机看到两种设计中的一种。
第一个感兴趣的指标,销售提升,可以通过比较两种设计中每一种的最终完成销售(二元结果)的客户比例来衡量。
使用两个比例的测试来比较这些是相当简单的。
第二个感兴趣的指标是美元兑换率。这是销售的最终美元价值,作为传入购物车的初始美元价值的一部分。
例如:一位顾客带着购物车中价值 160 美元的商品(初始值)来到结帐页面。客户从购物车中取出一些物品并最终以价值40 美元的物品(最终价值)进行销售。销售转化率是 100%(我们还是卖给客户一些东西),但美元转化率只有 25%。
如何根据没有差异的零假设正确测试两组的美元转换差异?
有关指定问题的一些 R 代码,请参见下文:
# 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"])
需要考虑的一些事项:
- 初始值和最终值相关
- 初值和终值都服从长尾分布,例如负指数分布
- 有时最终价值会大于初始价值,例如客户在完成销售之前向购物车添加了更多
- 销售成功和初始值是相关的,但我没有在示例代码中指定这一点
更新 1:Brumar 建议可以使用 Wilcoxon 秩和检验来比较那些最终完成销售的客户的客户行为变化:
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)
我仍然很想知道是否有任何方法可以比较整体美元转换的差异,即最终值的总和与初始值的总和?
更新 2:由 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))