A/B 测试

Python 中的贝叶斯数据分析

Michal Oleszak

Machine Learning Engineer

A/B 测试

  • 随机化实验:将用户分成两组(A 与 B)

 

 

两组用户。

1 图片:改编自 https://commons.wikimedia.org/wiki/File:A-B_testing_simple_example.png
Python 中的贝叶斯数据分析

A/B 测试

  • 随机化实验:将用户分成两组(A 与 B)
  • 让每组接触不同版本(如网站布局)

 

两组用户分别看到两个不同的网站布局。

1 图片:改编自 https://commons.wikimedia.org/wiki/File:A-B_testing_simple_example.png
Python 中的贝叶斯数据分析

A/B 测试

  • 随机化实验:将用户分成两组(A 与 B)
  • 让每组接触不同版本(如网站布局)
  • 比较哪组在某指标上更好(如点击率)

两组用户分别看到两个不同的网站布局,其中一组点击率更高。

1 图片:改编自 https://commons.wikimedia.org/wiki/File:A-B_testing_simple_example.png
Python 中的贝叶斯数据分析

A/B 测试:频率学派方法

  • 基于假设检验
  • 检查 A 与 B 是否表现相同
  • 不能说明 A 比 B 好多少
Python 中的贝叶斯数据分析

A/B 测试:贝叶斯方法

  • 计算布局 A 与 B 的点击率后验并比较
  • 直接计算 A 优于 B 的概率
  • 量化好多少
  • 估计决策出错时的期望损失
Python 中的贝叶斯数据分析

A/B 测试:贝叶斯方法

  • 用户进入网站时有两种结果:
    • 点击(成功)
    • 未点击(失败)
  • 使用二项分布!(成功概率 = 点击率)
Python 中的贝叶斯数据分析

模拟 Beta 后验

已知先验为 $Beta(a, b)$,则后验为 $Beta(x, y)$,其中:

$x = \text{NumberOfSuccesses} + a$

$y = \text{NumberOfObservations} - \text{NumberOfSuccesses} + b$

def simulate_beta_posterior(trials, beta_prior_a, beta_prior_b):
    num_successes = np.sum(trials)
    posterior_draws = np.random.beta(
      num_successes + beta_prior_a, 
      len(trials) - num_successes + beta_prior_b, 
      10000
    )
    return posterior_draws
Python 中的贝叶斯数据分析

比较后验分布

由 1 表示点击、0 表示未点击的列表:

print(A_clicks)
print(B_clicks)
[0 1 1 0 0 0 0 0 0 0 1 ... ]
[0 0 0 1 0 0 0 1 1 0 1 ... ]

 

为各布局模拟后验样本:

A_posterior = simulate_beta_posterior(A_clicks, 1, 1)
B_posterior = simulate_beta_posterior(B_clicks, 1, 1)

绘制后验分布:

sns.kdeplot(A_posterior, shade=True, label="A")
sns.kdeplot(B_posterior, shade=True, label="B")
plt.show()

两个部分重叠的后验密度图。

Python 中的贝叶斯数据分析

比较后验分布

B 与 A 的后验差值:

diff = B_posterior - A_posterior

sns.kdeplot(diff, shade=True, label="difference: A-B")
plt.show()

几乎全部概率质量在零以上的密度图。

B 更好的概率:

(diff > 0).mean()
0.9639
Python 中的贝叶斯数据分析

期望损失

若上线了更差的版本,会少多少次点击?

# 当 A 更好时的差值(B-A)
loss = diff[diff < 0]


# 期望(平均)损失 expected_loss = loss.mean() print(expected_loss)
-0.0077850237030215215
Python 中的贝叶斯数据分析

广告数据

print(ads)
                               user_id   product site_version                 time  banner_clicked
0     f500b9f27ac611426935de6f7a52b71f   clothes      desktop  2019-01-28 16:47:08               0
1     cb4347c030a063c63a555a354984562f  sneakers       mobile  2019-03-31 17:34:59               0
2     89cec38a654319548af585f4c1c76b51   clothes       mobile  2019-02-06 09:22:50               0
3     1d4ea406d45686bdbb49476576a1a985  sneakers       mobile  2019-05-23 08:07:07               0
4     d14b9468a1f9a405fa801a64920367fe   clothes       mobile  2019-01-28 08:16:37               0
...                                ...       ...          ...                  ...             ...
9995  7ca28ccde263a675d7ab7060e9ed0eca   clothes       mobile  2019-02-02 08:19:39               0
9996  7e2ec2631332c6c4527a1b78c7ede789   clothes       mobile  2019-04-04 03:27:05               0
9997  3b828da744e5785f1e67b5df3fda5571   clothes       mobile  2019-04-15 15:59:06               0
9998  6cce0527245bcc8519d698af2224c04a   clothes       mobile  2019-05-21 20:43:21               0
9999  8cf87a02f96327a1a8a93814f34d0d0c  sneakers       mobile  2019-03-02 21:27:57               0
Python 中的贝叶斯数据分析

让我们做 A/B 测试!

Python 中的贝叶斯数据分析

Preparing Video For Download...