用R编程进行AB测试

用R编程进行AB测试

分割测试是A/B测试的另一个名称,它是一种常见的或一般的方法。当人们想测试一个新的功能或产品时,它被用于网上。这里的主要议程是设计一个实验,提供可重复的结果和强大的功能,以做出一个明智的决定,推出或不推出。一般来说,这个测试包括通过代表变体A和B对两个网页进行比较,由于访问者的数量相似,变体给出的转换率变得更好。总的来说,这是一个实验,同一网页的两个或多个变体通过向实时访问者展示来进行比较,并通过这种方式确定哪一个对给定的目标表现得更好。A/B测试不仅用于或仅限于网页,它还可以用于电子邮件、弹出式窗口、注册表格、应用程序等。让我们 **** ,看一下案例研究的例子。因此,让我们在R语言中实现AB测试。

案例研究

让我们想象一下,我们有两个酒店预订网站的A/B测试结果,(注意:这些数据不是真实的)。首先,我们需要对数据进行测试分析;其次,我们需要从第一步获得的数据中得出结论,在最后一步,我们向产品或管理团队提出建议或意见。

数据集摘要

从这里下载数据集。

  • 变体A是来自于控制组,它讲述了网站上现有的功能或产品。
  • 变体B来自实验组,检查新版本的功能或产品,看看用户是否喜欢它,或者它是否增加了转化率(预订量)。
  • 转换率是基于给定的数据集,有两个类别由逻辑值定义。当客户完成预订时,它将显示为真,当客户访问网站但没有进行预订时,它将显示为假。

测试假设

  • 无效假设: 版本A和B都有相同的转换或推动客户预订的概率。换句话说,A和B版本之间没有区别或没有影响。
  • 备选假设: A和B版本拥有不同的转换或驱动客户预订的概率,并且A和B版本之间存在差异。B版在推动客户预订方面比A版更好。 PExp_B! = Pcont_A.

在R中的分析

1.准备好数据集并加载tidyverse库,其中包含用于分析的相关包

# load the library
library(tidyverse)
  
# set up your own directory
setwd(“~egot_\\Projects\\ABTest”) 
  
# Using read.csv base import function  
ABTest <- read.csv("Website Results.csv", 
                   header = TRUE)
  
# save in your own directory
save(ABTest, file = "~rda\\ABTest.rda")

2.让我们过滤变体A和B的转换,并计算其相应的转换率

# Let's filter out conversions for variant_A  
conversion_subset_A <- ABTest %>% 
    filter(variant == "A" & converted == "TRUE")
  
# Total Number of Conversions for variant_A
conversions_A <- nrow(conversion_subset_A)
  
# Number of Visitors for variant_A
visitors_A <- nrow(ABTest %>% 
    filter(variant == "A"))
  
# Conversion_rate_A
conv_rate_A <- (conversions_A/visitors_A)  
print(conv_rate_A) # 0.02773925
  
# Let's take a subset of conversions for variant_B
conversion_subset_B <- ABTest %>% 
    filter(variant == "B" & converted == "TRUE")
  
# Number of Conversions for variant_B
conversions_B <- nrow(conversion_subset_B)
  
# Number of Visitors for variant_B
visitors_B <- nrow(ABTest %>% 
    filter(variant == "B"))
  
# Conversion_rate_B
conv_rate_B <- (conversions_B/visitors_B)  
print(conv_rate_B) # 0.05068493

输出

0.02773925
0.05068493

3. 让我们用转换率A和B来计算相对提升。

uplift <- (conv_rate_B - conv_rate_A) / conv_rate_A * 100
uplift # 82.72%

输出

82.72%

B比A好83%。这已经高到足以决定胜负。

4.让我们计算一下A和B的集合概率、标准误差、误差率和比例差(点估计)

# Pooled sample proportion for variants A & B
p_pool <- (conversions_A + conversions_B) / (visitors_A +
                                             visitors_B)
print(p_pool) # 0.03928325
  
# Let's compute Standard error for variants A & B (SE_pool)
SE_pool <- sqrt(p_pool * (1 - p_pool) * ((1 / visitors_A) + 
                                         (1 / visitors_B)))
print(SE_pool) # 0.01020014
  
# Let's compute the margin of error for the pool
MOE <- SE_pool * qnorm(0.975)
print(MOE) # 0.0199919
  
# Point Estimate or Difference in proportion
d_hat <- conv_rate_B - conv_rate_A

输出

0.03928325
0.01020014
0.0199919

5.让我们来计算一下z-score

# Compute the Z-score so we
# can determine the p-value
z_score <- d_hat / SE_pool
print(z_score) # 2.249546

输出

2.249546

6.使用这个z分数,我们可以通过查询表,或使用下面的代码快速确定p值

# Let's compute p_value 
# using the z_score value
p_value <- pnorm(q = -z_score, 
                 mean = 0, 
                 sd = 1) * 2
print(p_value) # 0.02447777

输出

0.02447777

7.让我们计算一下水池的置信区间

# Let's compute Confidence interval for the 
# pool using pre-calculated results
ci <- c(d_hat - MOE, d_hat + MOE) 
ci # 0.002953777 0.042937584
  
# Using same steps as already shown, 
# let's compute the confidence 
# interval for variants A separately
X_hat_A <- conversions_A / visitors_A
se_hat_A <- sqrt(X_hat_A * (1 - X_hat_A) / visitors_A) 
ci_A <- c(X_hat_A - qnorm(0.975) * se_hat_A, X_hat_A
          + qnorm(0.975) * se_hat_A) 
print(ci_A) # 0.01575201 0.03972649
  
# Using same steps as already shown, 
# let's compute the confidence 
# interval for variants B separately                                 
X_hat_B <- conversions_B / visitors_B
se_hat_B <- sqrt(X_hat_B * (1 - X_hat_B) / visitors_B) 
ci_B <- c(X_hat_B - qnorm(0.975) * se_hat_B, 
          X_hat_B + qnorm(0.975) * se_hat_B) 
print(ci_B) # 0.03477269 0.06659717

输出

0.002953777 0.042937584
0.01575201 0.03972649
0.03477269 0.06659717

8.让我们在一个数据框架(表格)中直观地看到迄今为止计算的结果。

vis_result_pool <- data.frame(
  metric = c(
    'Estimated Difference',
    'Relative Uplift(%)',
    'pooled sample proportion',
    'Standard Error of Difference',
    'z_score',
    'p-value',
    'Margin of Error',
    'CI-lower',
    'CI-upper'),
  value = c(
    conv_rate_B - conv_rate_A,
    uplift,
    p_pool,
    SE_pool,
    z_score,
    p_value,
    MOE,
    ci_lower,
    ci_upper
  ))
vis_result_pool

输出

                     metric       value
1         Estimated Difference  0.02294568
2           Relative Uplift(%) 82.71917808
3     pooled sample proportion  0.03928325
4 Standard Error of Difference  0.01020014
5                      z_score  2.24954609
6                      p-value  0.02447777
7              Margin of Error  0.01999190
8                     CI-lower  0.00000000
9                     CI-upper  0.04589136

建议和结论

  • 变体A有20次转换和721次点击,而变体B有37次转换和730次点击。
  • 基于变体A的转换率为2.77%,B的转换率为5.07%,相对提升了82.72%。因此,变体B比A好82.72%。
  • 对于这项分析,计算出的P值为0.02448。因此,测试结果有很强的统计学意义。
  • 从上述结果来看,显示了强烈的统计学意义。你应该拒绝无效假设,并继续进行启动。
  • 因此,接受变体B,你可以向用户100%地推出它。

如果你想知道完整的分析和数据集的细节,请点击这个Github链接。

局限性

它是转换优化的工具之一,它不是一个独立的解决方案,它不能解决我们所有的转换问题,它不能解决你得到的混乱数据的问题,你需要执行更多的A/B测试来提高转换率。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程