This commit is contained in:
louzefeng
2024-07-11 05:50:32 +00:00
parent bf99793fd0
commit d3828a7aee
6071 changed files with 0 additions and 0 deletions

View File

@@ -0,0 +1,185 @@
<audio id="audio" title="09 |测试结果不显著,要怎么改善?" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/6d/d3/6d8984b70d6547585e308a2ae6e098d3.mp3"></audio>
你好,我是博伟。
通过“基础篇”的学习你已经掌握了A/B测试的整体流程那就可以参照这些流程设计一次A/B测试了。不过在具体实施的过程中你会因为业务的复杂性、没有严格遵守规范的流程或者数据本身的属性等不可避免地遇到一些问题。
没错儿这就是我在开篇词中和你说的A/B测试的实践性非常强你需要能够识别那些潜在的坑并找到相应的解决方法。所以在接下来的三节课里我会带你去看看我积累的经验曾经踩过的坑让你在实践时能提前规避少出错。
今天我们就先从一个很痛的问题开始吧。在第7节课我们学习如何得到可信赖的测试结果以及如何分析测试结果时非常顺利地得出了对照组和实验组指标显著不同的结果。不知道你脑海中会不会一直萦绕着这么一个问题我也是按照这个流程来设计A/B测试的啊为什么我的实验结果不显著呢我应该据此得出“两组指标事实上是相同的”结论吗
今天这节课,我们就来深入剖析“测试结果如何不显著怎么办”这个大家经常遇到的问题。
## **为什么会<strong><strong>出现“<strong><strong>实验结果不显著**</strong>”</strong></strong></strong>
首先我们要搞清楚,为什么会出现“实验结果不显著”?有两方面原因。
- A/B测试中的变化确实没有效果所以两组的指标在事实上是相同的。
- A/B测试中的变化有效果所以两组的指标在事实上是不同的。但是由于变化的程度很小测试的灵敏度也就是Power不足所以并没有检测到两组指标的不同。
如果是第一种原因,就证明这个变化对产品/业务优化没有效果。那我们要考虑放弃这个变化,或者去测试新的变化。
如果是第二种原因那我们可以从A/B测试的角度进行一些优化和调整。具体来说就是通过提高Power来提高A/B测试检测到实验结果不同的概率。在第6节课我讲过了Power越大越能够准确地检测出实验组与对照组的不同。所以当我们提高了Power之后如果仍然发现测试结果不显著这样才能得出“两组指标事实上是相同的”的结论。
有什么方法可以提高Power呢
我们再来回顾下第6节课讲到的样本量估算公式<br>
$\mathrm{n}=\frac{\left(Z_{1-\frac{\alpha}{2}}+Z_{1-\beta}\right)^{2}}{\left(\frac{\delta}{\sigma_{\text {pooled}}}\right)^{2}}=\frac{\left(Z_{1-\frac{\alpha}{2}}+Z_{\text {power}}\right)^{2}}{\left(\frac{\delta}{\sigma_{\text {pooled}}}\right)^{2}}$<br>
其中:<br>
$Z_{1-\frac{\alpha}{2}}$ 为 $\left(1-\frac{\alpha}{2}\right)$ 对应的 $Z$ Score。<br>
$Z_{\text {Power}}$ 为 Power 对应的 $Z$ Score。<br>
$\delta$ 为实验组和对照组评价指标的差值。<br>
$\sigma_{\text {pooled}}^{2}$ 为实验组和对照组的综合方差 (Pooled Variance)。
在公式里我们找出影响Power的因素也就是样本量和方差。其中
- 样本量和Power成正比。即通过增大样本量就可以提高Power。
- 方差和Power成反比。即通过减小方差就可以提高Power。
具体来说实践中在有条件获得更大样本量的情况下可以选择增大样本量的方法来提高Power相对简单易操作。如果受流量或时间限制没有条件获得更多的样本量此时可以通过减小方差来提高Power。
接下来我就分别从增大样本量和减小方差这两个维度来讲解6种提高Power的具体方法。
## **如何通过增加样本量来提高Power**
实践中,用来增加样本量的方法主要有三种:**延长测试时间,增加测试使用流量在总流量中的占比,以及多个测试共用同一个对照组。**
### **延长测试时间**
对于延长测试时间你肯定不陌生我在第6节课讲样本量估算时就讲过。每天产生的可以测试的流量是固定的那么测试时间越长样本量也就越大。所以在条件允许的情况下可以延长测试的时间。
### **增加测试使用流量在总流量中的占比**
假设某个产品每天有1万流量如果我要做A/B测试并不会用100%的流量一般会用总流量的一部分比如10%,也就是测试使用流量在总流量中的占比。
为什么不使用全部流量呢?
一方面A/B测试有试错成本虽然出现的概率较低但是我们在测试中做出的任何改变都有可能对业务造成损害。所以使用的流量越少试错成本越低也就越保险。
另一方面,在大数据时代,对于互联网巨头来说,由于本身就拥有巨大的流量,那么产品本身做出的任何比较明显的改变,都有可能成为新闻。
比如要测试是否要增加一个新功能时公司并不想在测试阶段就把这个新功能泄露给用户以免给用户造成困扰。所以它们一般会先使用很小比例的流量来做A/B测试比如1%确定得到显著结果后再把A/B测试中的变化慢慢推广到100%的流量。
所以,在保持测试时间不变的情况下,还可以通过增加测试使用流量在总流量中的占比,来达到增加样本量的目的。
### **多个测试共用同一个对照组**
有时我们会在同一个产品上同时跑多个A/B测试比如我们想要提升推送的点击率就会在原推送的基础上改变推送的标题、推送的内容、推送的时间、推送的受众等等。
对于这四个不同的影响因素事实上改变每一个因素都是一个独立的A/B测试。那理论上我们就需要设计4个实验需要有4个实验组和4个对照组。
假设我们现在的可用流量一共是8万那么每组就有1万流量。但是你会发现这样流量的利用率太低了因为每个实验的对照组其实都是一样的原推送。但如果我们把4个对照组合并成一个这样的话就变成了4个实验组和1个对照组每组就有1.6万流量。
你看在同一个基础上想同时验证多个变化也就是跑多个A/B测试有相同的对照组的时候我们可以把对照组合并减少分组数量这样每组的样本量也会增加。这种测试又叫做A/B/n测试。
总结来说,在实践中:
- 如果时间允许,最常用的是延长测试时间的方法,因为操作起来最简单。
- 如果时间不充足的,可以优先选择增加测试使用流量在总流量中的占比,因为可以节省时间。
- 当有多个测试同时进行,而且对照组又相同的情况下,就可以把多个对照组合并成一个。
通过增加样本量来提高Power是实践中最常见的方法但是业务场景千变万化虽然不常见但有时候确实没有办法获得更多的样本比如时间紧迫同时已经使用了100%的总流量结果还是不显著那这个时候就要通过减少方差来提高Power了。
## **如何通过减<strong><strong>小**</strong>方差来提高Power</strong>
实践中常用的减少方差的方法也有三种:**减小指标的方差,倾向评分匹配,以及在触发阶段计算指标**。
### **减小指标的方差**
减小指标的方差有两种方式。
**第一种方式:<strong><strong>保持原指标不变通过剔除离群值Outlier的方法来减小方差**</strong></strong>
如果我们通过指标的直方图发现实验的指标分布中有很明显的离群值就可以通过设定封顶阈值Capping Threshold的方法把离群值剔除掉。
比如可以根据指标的分布只选取95%的取值范围然后把剩下的5%的离群值剔除掉。常见的指标比如电商中的人均花费或者音乐App中的人均收听时间由于会有些极少热衷于线上购物的用户花费居多或者音乐发烧友一直在听歌那么这些极少部分的用户就可能变成离群值从而增加方差。
**第二种方式:选用方差较小的指标。**
取值范围窄的指标比取值范围广的指标方差要小。比如点击者量比点击量的方差小(因为一个点击者可以产生多个点击,点击比点击者多,取值范围广);购买率比人均花费的方差小(因为购买率是表征买或不买的二元事件,只有两个取值,人均花费则可以是任何数量的金钱,理论上有无限的取值范围);收听率比人均收听时间的方差小;等等。
可以看到,对于表征类似的行为(比如买买买,听音乐,看视频,等等),概率类指标要比均值类指标的方差小。所以在满足业务需求的情况下,如果我们想要减少方差,就可以把均值类的指标转化成表征相似行为的概率类指标,也就是修改原定指标,选用取值范围窄的指标。
### **倾向评分匹配Propensity Score Matching**
倾向评分匹配简称PSM是因果推断的一种方法目的是解决实验组和对照组分布不均匀的问题。
你一定还记得我们在第7节课中学习过分析结果前要进行合理性检验那么它和PSM是什么关系呢
我来总结下。如果说合理性检验是帮我们确定两组分布是否相似的方法那么PSM就是帮我们找出两组中相似部分的回溯性分析方法。简单来说**两组的各个特征越相似,就说明两组的方差越小。**
PSM的基本原理就是把一组中的数据点找到在另一组和它们相似的数据点进行一对一的匹配这个相似性是通过比较每个数据点的倾向评分Propensity Score得到的。如果不理解倾向评分也没关系你只需要知道这一点就够了倾向评分越接近说明两个数据点越相似。这里的一个数据点指的就是A/B测试中的一个实验单位。
PSM的具体做法如下。
1. 首先,把我们要匹配的两组中每个数据点的各个特征(比如用户的性别,年龄,地理位置,使用产品/服务的特征等)放进一个[逻辑回归](https://en.wikipedia.org/wiki/Logistic_regression)Logistics Regression中。
1. 然后,算出每个数据点的倾向评分,然后再用诸如[最邻近](https://en.wikipedia.org/wiki/Nearest_neighbor_search)Nearest Neighbor等方法进行匹配。
1. 最后我们只需要比较匹配后的两组相似的部分即可。
[PSM](https://en.wikipedia.org/wiki/Propensity_score_matching)的原理有些复杂我放了一些资料链接你可以查看。不过幸运的是在主要的编程语言Python和R中都有相应的库比如Python中的[pymatch](https://github.com/benmiroglio/pymatch)和R中的[Matching](https://cran.r-project.org/web/packages/Matching/Matching.pdf),让我们的实施变得相对容易些。
在倾向评分匹配这个部分,你只需要记住一个结论就可以了,那就是:**PSM能够有效<strong><strong>地**</strong>减少两组的方差</strong>**。****通过比较倾向评分匹配后的两组的相似部分,我们可以来查看结果是否显著。**
### **在触发阶段计算指标**
在A/B测试中我们把实验单位进行随机分组的这个过程叫做分配Assignment 同时你要知道在有些A/B测试中比如在第8节课的案例中我们要测试的变化是需要满足一定条件才能触发的。
所以从分配和触发的关系来看A/B测试可以分为两种。
<li>
变化不需要条件触发。所有用户在被分配到实验组后就都可以体验到A/B测试中的变化。
</li>
<li>
变化需要条件触发。在被分配到实验组的所有用户中只有满足一定条件的用户才会触发A/B测试中的变化。
</li>
<img src="https://static001.geekbang.org/resource/image/a9/10/a9e72fb1a7cfdff6232974146f31a410.png" alt="">
实践中大部分的A/B测试都属于第一种而且也比较好理解。
但是要注意了我们这里讲的减小方差的方法只适用于第二种A/B测试简单来说就是在计算指标时只考虑每组符合触发条件黄圆圈的用户而不是考虑每组中的所有用户绿圆圈。这个不是很好理解我来举例说明下。
还记得第8节课中我们讲到可以利用弹窗的形式来告知用户“把喜欢的音乐加入收藏夹”新功能的A/B测试吗在A/B测试的设计中并不是在实验组的所有用户都会收到弹窗提醒的。
所以为了避免打扰到不相关的用户,把弹窗发送给需要这个功能的用户,我们事先规定了触发弹窗的规则:
1. 该用户从来没用过“把喜欢的音乐加入收藏夹”这个功能。
1. 该用户已经对某首歌听了4次当播放第5次时触发弹窗。
那么当我们计算案例中的评价指标时,各组中“把喜欢的音乐加入收藏夹”功能的使用率 = 各组中使用了“把喜欢的音乐加入收藏夹”的用户总数 / 实验中各组的用户总数。
这里的分母“实验中各组的用户总数”就只算满足弹窗触发规则的用户,而不是算所有被分配到实验中各组的用户,这就是在触发阶段计算指标。
这里要注意的是,在对照组也会有用户满足弹窗触发规则的,只不过因为他们在对照组,所以即使他们满足了弹窗触发规则,我们也不会给这些用户发弹窗,我们还是要统计这些人因为要用他们做分母来计算评价指标。
这里对数据埋点熟悉的小伙伴可能要问了:这些符合弹窗触发规则的对照组用户并没有触发弹窗,在数据中并没有相关的记录,我怎么在数据中去记录他们呢?
在工程实现上其实是有一个小技巧的:对于对照组的用户,如果他们符合触发规则,我们就给他们发送一个只有一个像素点的看不见的隐形弹窗,这样的话我们在数据中会有相关记录,方便之后的指标计算,同时又保证了对照组不会受到弹窗的影响。
通过把评价指标的分母变为满足弹窗触发规则的用户,在计算指标时就会排除掉数据中的噪音(那些被分配到实验中但是没有触发弹窗的用户),从而减小方差。
这种需要触发的A/B测试多出现在有固定的用户使用路径的业务中比如电商。在电商中用户一般有较明确的多层级的使用路径进入网站/App —&gt; 浏览商品列表 —&gt; 查看具体商品 —&gt; 加入购物车 —&gt; 购买。
在电商的A/B测试中一般是在用户进入网站/App时就被分配到实验组或者对照组如果我们测试之后的环节比如在“购物车”页面测试新功能这时候只有进入到“购物车”页面的用户才能触发A/B测试中的变化。
总体而言通过减少方差来提高Power的情况不多常见的是通过增加样本量来提高Power。如果真的遇到这种情况那么比较简单快速的方法就是减小指标的方差。当然如果有条件的话我还是推荐更加科学的倾向评分匹配PSM。那么对于在A/B测试中的变化存在触发的情况下就一定要在触发阶段计算指标。
## **小结**
为了解决A/B测试结果不显著的问题这节课我们主要讲解了提高A/B测试Power的6种方法我把它们从原理上分成了两大类
<img src="https://static001.geekbang.org/resource/image/3f/2c/3f9540dc32354f5539d7439cda32b72c.png" alt="">
你可以根据我对每种方法的介绍,以及在什么情况下选用哪种方法,灵活应用。
如果在尝试过这些方法后重新跑实验得出的测试结果还不显著那就说明两组的指标事实上是相同的我们就要放弃这个A/B测试中的变化用其他的变化来优化业务和产品。
最后再强调一下做出一个能真正提升业务的改变并不容易。从美国FLAG这些大厂披露出来的实验数据来看A/B测试得到真正显著的结果并最终实施变化的概率还不到三分之一。
所以也不要气馁,虽然不是每次实验都会有显著的结果,但是你可以从每次实验中学到新的知识(比如变化到底对业务有没有效果),沉淀新的方法论,还能从中发现业务、数据或者工程上潜在的一些问题。这些个人技能上的成长、业务流程上的完善,都是非常宝贵的。
## **思考题**
在某次A/B测试中你是不是也遇到过没能得到显著结果的情况你当时是怎么处理的有没有从实验中获得一些宝贵的经验
欢迎在评论区留言、讨论,也欢迎点击“请朋友读”,把今天的内容分享给你的同事、好友,和他一起学习、成长。好,感谢你的收听,我们下节课再见。

View File

@@ -0,0 +1,163 @@
<audio id="audio" title="10常见误区及解决方法多重检验问题和学习效应" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/6e/b1/6e54b44331883d408d252509191967b1.mp3"></audio>
你好,我是博伟。
上节课我们讲了一个在做A/B测试时普遍存在的一个问题那么接下来我就根据自己这些年做A/B测试的经验精选了一些在实际业务中会经常遭遇的误区主要是多重检验问题、学习效应、辛普森悖论和实验/对照组的独立性这四大误区。
这四个误区,其实也可以被看作在实际业务中经常出现的几个问题。不过我在题目中之所以强调说这是误区,是因为你很可能会在这些问题的理解上产生一些偏差。
所以接下来我在讲这两节课时,会按照“问题阐述—问题解析—总结引申—课后思考”的范式来给你讲。也就是说,我会先带你深入剖析问题的成因,然后再举例分析这些问题在实践中的表现形式,最后给出对应的解决方法。
毕竟,在搞清楚问题原理的前提下,再学习问题的表现形式和解决方法,不仅你的学习效果会事半功倍,而且在实际应用时,你也能根据变化多端的业务场景,随机应变,灵活运用。
## **多重检验问题Multiple Testing Problem**
多重检验问题又叫多重测试问题或多重比较问题Multiple Comparison Problem指的是当同时比较多个检验时第一类错误率α就会增大而结果的准确性就会受到影响这个问题。我在基础篇讲A/B测试流程时就多次提到过它比如[第4节课](https://time.geekbang.org/column/article/321007)讲OEC的好处时还有[第7节课](https://time.geekbang.org/column/article/323696)讲什么时间才能查看测试结果时。
### **多重检验为什么会是一个问题?**
要搞清楚多重检验为什么会是一个问题我们还得先从第一类错误率α又叫假阳性率显著水平是测试前的预设值一般为5%说起。我在第2节课也讲过第一类错误率指的就是当事实上两组指标是相同的时候假设检验推断出两组指标不同的概率或者说由于偶然得到显著结果的概率。而且它在统计上的约定俗成是5%。
5%看上去是个小概率事件但是如果我们同时比较20个检验测试你可以先思考一下如果每个检验出现第一类错误的概率是5%那么在这20个检验中至少出现一个第一类错误的概率是多少呢
要直接求出这个事件的概率不太容易我们可以先求出这个事件发生情况的反面也就是在这20个检验中完全没有出现第一类错误的概率然后再用100%减去这个反面事件的概率。
这里我们用PA来表示出现事件A的概率。P每个检验出现第一类错误=5%那么P每个检验不出现第一类错误 = 1-5%=95%所以P20个检验中完全没有第一类错误= 95%的20次方。
这样我们就可以求得这个概率:<br>
<img src="https://static001.geekbang.org/resource/image/d2/74/d2cfa2e855ca2d90815e5a00c8deb374.png" alt=""><br>
这里的 P至少出现一个第一类错误的概率又叫做 FWER Family-wise Error Rate<br>
通过计算得出来的概率是64%。这就意味着当同时比较20个检验时在这20个结果中至少出现一个第一类错误的概率是64%。看看,这是不是个很大的概率了呢?事实上,随着检验次数的增加,这个概率会越来越大,你看看下面这个图就明白了。
<img src="https://static001.geekbang.org/resource/image/5e/1e/5e933ae0b496b062295a26304d8ac51e.png" alt="">
图中的蓝线和橙线分别表示当α=5%和1%时FWER的变化情况。根据这个图我们可以得出两个结论
<li>
随着检验次数的增加FWER也就是出现第一类错误的概率会显著升高。
</li>
<li>
α越小时FWER会越小上升的速度也越慢。
</li>
第一个结论讲的就是多重检验带来的问题。第二个结论其实为我们提供了一种潜在的解决方法:降低α。
这就意味着当我们同时比较多个检验时就增加了得到第一类错误的概率FWER这就变成了一个潜在的多重检验问题。
### **什么时候会遇到多重检验问题?**
你可能会说我平时都是一个测试一个测试去跑不会同时跑多个测试是不是就不会遇到这个问题了呢其实不是的实践中出现多重检验问题比你想象的要普遍得多它在实践中主要以4种形式出现。
**第一种形式当A/B测试有不止一个实验组时。**
当我们想要改变不止一个变量且样本量充足时,我们可以不必等测试完一个变量后再去测试下一个,而是可以同时测试这些变量,把它们分在不同的实验组当中。
每个实验组只变化一个变量在分析结果时分别用每个实验组和共同的对照组进行比较这种测试方法也叫做A/B/n测试。比如我想要改变广告来提升其效果那么想要改变的变量包括内容、背景颜色、字体大小等等这个时候我就要有相对应的3个实验组然后把它们分别和对照组进行比较。
这就相当于同时进行了3个检验就会出现多重检验问题。
**第二种形式当A/B测试有不止一个评价指标时。**
这个很好理解,因为我们分析测试结果,其实就是比较实验组和对照组的评价指标。如果有多个评价指标的话,就会进行多次检验,产生多重检验问题。
**第三种形式当你在分析A/B测试结果按照不同的维度去做细分分析Segmentation Analysis时。**
当我们分析测试结果时,根据业务需求,有时我们并不满足于只把实验组和对照组进行总体比较。
比如对于一个跨国公司来说很多A/B测试会在全球多个国家同时进行这时候如果我们想要看A/B测试中的变化对于各个国家的具体影响时就会以国家为维度来做细分的分析会分别比较单个国家中的两组指标大小那么此时分析每个国家的测试结果就是一个检验多个国家则是多个检验。
**第四种形式当A/B测试在进行过程中你不断去查看实验结果时。**
这种情况我在[第7节课](https://time.geekbang.org/column/article/323696)中提到过,因为当测试还在进行中,所以每次查看的测试都和上一次的不一样,每查看一次结果都算是一次检验,这样也会产生多重检验问题。
了解了多重检验问题在实践中的表现形式,那么在实践中该如何解决它呢?
### **如何解决多重检验问题?**
首先我要提前说明的是接下来我介绍的解决方法只适用于前3种表现形式。对于第4种表现形式的解决办法我已经在第7节课介绍了那就是不要在A/B测试还在进行时就过早地去查看结果一定要等样本量达到要求后再去计算结果所以这里就不再赘述。
鉴于多重检验问题的普遍性,在统计上有很多学者提出了自己的解决方法,大致分为两类:
<li>
保持每个检验的P值不变调整α
</li>
<li>
保持α不变调整每个检验的P值。
</li>
为什么会做这两种调整呢?
在[第2节课](https://time.geekbang.org/column/article/318454)我们介绍了用P值来判断假设检验的结果是否显著时是用检验中计算出的P值和α进行比较的。当P值&lt;α时,我们才说结果显著。
所以我们要么调整α要么调整P值。前面我也说了降低α是一种解决办法最常用的调整α的方法是[Bonferroni校正](https://en.wikipedia.org/wiki/Bonferroni_correction)Bonferroni Correction其实很简单就是把α变成α/n。
其中n是检验的个数。比如α=5%那当我们比较20个检验时校正之后的α=5%/20 = 0.25%此时的FWER =$1-(1-0.25 \%)^{20}$ = 4.88% ,和我们最初设定的α=5%差不多。
Bonferroni校正由于操作简单在A/B测试的实践中十分流行但是这种方法只是调整了α对于不同的P值都采取了一刀切的办法所以显得有些保守检测次数较少时还可以适用。
根据实践经验在检测次数较大时比如上百次这种情况在A/B测试中出现的情况一般是做不同维度的细分分析时比如对于跨国公司来说有时会有上百个markets Bonferroni校正会显著增加第二类错误率β这时候一个比较好的解决办法就是去调整P值常用的方法就是通过控制[FDR](https://en.wikipedia.org/wiki/False_discovery_rate)False Discovery Rate来实现。
控制FDR的原理比较复杂我就不展开讲了你只需要记住它指的是一类方法其中最常用的是[BH法](https://www.statisticshowto.com/benjamini-hochberg-procedure/)Benjamini-Hochberg Procedure就行了。BH法会考虑到每个P值的大小然后做不同程度的调整。大致的调整方法就是把各个检验计算出的P值从小到大排序然后根据排序来分别调整不同的P值最后再用调整后的P值和α进行比较。
实践中我们一般会借助像Python这样的工具来计算Python中的[multipletests](https://www.statsmodels.org/dev/generated/statsmodels.stats.multitest.multipletests.html)函数很强大里面有各种校正多重检验的方法其中就包括我们今天讲的Bonferroni校正和BH法我们使用时只需要把不同的P值输入选取校正方法这个函数就会给我们输出校正后的P值。
这里我总结一下虽然Bonferroni校正十分简单但由于过于严格和保守所以在实践中我会更推荐使用BH法来矫正P值。
聊完了多重检验问题我们再聊一下A/B测试中另一个常见问题——学习效应。
## **学习效应(Learning Effect)**
当我们想通过A/B测试检验非常明显的变化时比如改变网站或者产品的交互界面和功能那些网站或者产品的老客户往往适应了之前的交互界面和功能而新的交互界面和功能对他们来说需要一段时间来适应和学习。所以往往老用户在学习适应阶段的行为会跟平时有些不同这就是学习效应。
### **学习效应在实践中有哪些表现形式?**
根据不同的改变,老用户在学习适应期的反应也不同,一般分为两种。
第一种是积极的反应一般也叫做新奇效应Novelty Effect指的是老用户对于变化有很强的好奇心愿意去尝试。
比如把点击按钮的颜色,由之前的冷色调变成了非常艳丽的大红色,在短期内可能会使诸如点击率之类的指标提升,但是当用户适应了新的大红色后,长期的指标也可能回归到之前的水平。
第二种是消极的反应一般也叫做改变厌恶Change Aversion。指的是老用户对于变化比较困惑甚至产生抵触心理。
比如你经常光顾的电商网站,之前的加入购物车功能是在屏幕的左上方,但是交互界面改变后加入购物车的位置变到了屏幕的右下方,这个时候你可能就需要在屏幕上找一阵子才能找到,甚至找了一圈没找到,因为烦躁就关掉了页面,那么这时候短期的指标就会下降。
可以想象这些在学习适应期的不同反应一般是短期的长期来看这些短期反应也是会慢慢消退的。但是要注意的是这些短期的学习效应确实会给A/B测试的结果带来干扰使结果变得过于好或者过于差。那么我们如何来及时发现学习效应从而剔除学习效应带来的干扰呢
### **学习效应该如何检测?**
在实践中,主要有两种方法可以用来检测学习效应。
**第一种方法是表征实验组的指标随着时间(以天为单位)的变化情况。**
在没有学习效应的情况下,实验组的指标随着时间的变化是相对稳定的。
但是当有学习效应时,因为学习效应是短期的,长期来看慢慢会消退,那么实验组(有变化的组)的指标就会有一个随着时间慢慢变化的过程,直到稳定。
- 如果是新奇效应,实验组的指标可能会由刚开始的迅速提升,到随着时间慢慢降低。
- 如果是改变厌恶,实验组的指标可能会由刚开始的迅速降低,到随着时间慢慢回升。
当然我们在使用这个方法时需要注意:随着时间表征实验组的指标变化,但并不是让你每天去比较实验组和对照组的大小。如果每天都去比较,就会出现我们刚才讲的多重检验的问题。一定要记住,只有达到样本量之后才可以去比较两组大小,分析测试结果。
**第二种方法是只比较实验组和对照组中的新用户。**
学习效应是老用户为了学习适应新的变化产生的,所以对于新用户,也就是在实验期间才第一次登录的用户来说,并不存在“学习适应新的变化”这个问题,那么我们可以先在两组找出新用户(如果是随机分组的话,两组中新用户的比例应该是相似的),然后只在两组的新用户中分别计算我们的指标,最后再比较这两个指标。
如果我们在新用户的比较中没有得出显著结果(在新用户样本量充足的情况下),但是在总体的比较中得出了显著结果,那就说明这个变化对于新用户没有影响,但是对于老用户有影响,那么大概率是出现了学习效应。
在实践中我们可以用以上方法检测出学习效应,不过要想真正排除学习效应的影响,得到准确的实验结果,还是要延长测试时间,等到实验组的学习效应消退再来比较两组的结果。
## **小结**
今天这节课我们重点讲解了A/B测试中两个常见的实验误区多重检验问题和学习效应。我把这两个问题出现的原理、在实践中的多种表现形式以及相应的解决方法都给你详细讲解了。
不过我还想特别强调一下多重检验问题。多重检验问题的表现形式多种多样所以在A/B测试中尤为常见。我在刚接触A/B测试时就已经知道了这个问题的存在不过当时了解到的是它会在A/B/n测试中出现但后来才发现原来在做细分分析时也会出现多重检验的问题。
幸好这个问题发现得及时,才没有让整个测试功亏一篑。现在再去复盘,主要还是因为当时只知道多重检验问题的存在,了解其中一两个表现形式。但对于为什么会出现多重检验问题,什么时候可能会出现多重检验问题,我都不清楚,所以在问题出现新的表现形式时就没有及时识别出来。
这也是我想要跟你强调的,**知道为什么会出现这个问题,并且发现问题,和解决问题同样重要。**
**思考题**
结合自己的经验想一想过去有没有在A/B测试中遇到多重检验问题和学习效应以及当时是如何处理的呢
欢迎在评论区写下你学习本节课的收获和深度思考,如果今天的内容能帮你解答了一些困惑问题,也欢迎点击“请朋友读”,和他一起学习、成长。感谢你的收听,我们下节课再见。

View File

@@ -0,0 +1,149 @@
<audio id="audio" title="11 | 常见误区及解决方法(下):辛普森悖论和实验组/对照组的独立性" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/4d/a0/4da4c9a41fd7aaf8821bb2b55ac7bca0.mp3"></audio>
你好我是博伟。这节课我们继续来学习A/B测试中的常见误区和解决方法。
今天我们要解决的问题,是辛普森悖论和实验/对照组的独立性。这两个问题在A/B测试的实践中也是常客。
对于辛普森悖论呢由于遇到的次数太多以至于我每次做A/B测试结果的细分分析时都要先检查该细分领域在两组的比例是否符合两组整体的比例来确保实验结果的准确。
对于实验/对照组独立性被破坏这个问题我在早期做营销预算固定的A/B测试时也经常遇到但是它的表现形式其实非常多变各个业务类型中都有它的身影所以就需要有针对性地进行分析。
听了我的经历你可能还是不太明白这两个问题到底是什么它们对A/B测试有什么影响不用担心今天我就会为你深度剖析带你在实践中去识别它们并解决它们
## **辛普森悖论**
听到“辛普森悖论”这个概念你可能会有点迷茫不知道它具体说的是什么问题。所以我还是先用音乐App来举个例子告诉你辛普森悖论是什么以及它在A/B测试中到底指的是什么。
一款音乐App优化了新用户的注册流程并且希望通过A/B测试在北京、上海这两个主要的市场来验证优化注册后的转化率是否有所提升。
- 实验组:使用优化后的注册流程。
- 对照组:使用原有的注册流程。
在设计好了实验之后实验组和对照组的样本量均分。等跑完实验获得了足够的实验样本之后结果得到实验组的转化率为1.44% 对照组的转化率为2.02%。
这就很让人意外了,为什么实验组(使用优化后的注册流程)的转化率,反而比对照组(使用原有的注册流程)的转化率要低呢?
而且更让人意外的是,当你在分别分析北京和上海这两个市场时,会发现它们的实验组转化率都比对照组的要高。
<img src="https://static001.geekbang.org/resource/image/48/5a/486e5fcb4e67a20b909e3620d107575a.png" alt="">
在确认了数据和计算没有错误后,你的本能反应可能会是:同样的数据,我在进行总体分析和细分分析时得出的结果却完全相反,这怎么可能呢!
这就是在数学理论中很有名的辛普森悖论,它是指当多组数据内部组成分布不均匀时,从总体上比较多组数据和分别在每个细分领域中比较多组数据可能会得出相反的结论。在数学上,它的形式要更加抽象:即使 $\frac{a}{b}&lt;\frac{A}{B}, \frac{c}{d}&lt;\frac{C}{D}$,那么$\frac{a+c}{b+d}&gt;\frac{A+C}{B+D}$也是可能成立的。
真是奇怪了这个有些反直觉的现象在数学上竟然是完全可以成立的。而这种不可思议的现象也出现在了A/B测试中。
究其原因,在这个例子当中,其实是因为实验组和对照组虽然在总体上实现了我们在设计实验时要求的样本量均分。但是在北京和上海这两个细分市场中却分布不均匀,没有实现样本量均分。<br>
<img src="https://static001.geekbang.org/resource/image/5b/fd/5b1257c8294e32688cd4b70a662b71fd.png" alt=""><br>
关于细分分析我也再补充一下。在A/B测试的实践中我们一般根据市场不同的城市、国家等设备类型手机、桌面、平板等用户的互动或者花费程度轻度、中度、重度等来进行细分分析。
好了还是回到我们的案例当中。如果你对基础篇的内容掌握得足够扎实就会发现我们在第7节课中讲分析结果前的合理性检验时其中有一项就是**检验实验/对照组中特征的分布,意思是说要检验两组中的特征分布是否相似,是否符合实验设计要求的比例分布。**
所以,咱们今天讲的辛普森悖论,实际上就是**由于实验中两组在不同细分领域中的分布不均造成的。**
当然在音乐App这个例子中只有两个细分领域。如果是多个细分领域比如要在全国几十个大城市进行A/B测试那么**只要是实验组和对照组在任何一个细分领域的分布与实验设计的不相符时,都有可能出现辛普森悖论。**
所以既然辛普森悖论是我们做A/B测试时需要规避的问题/现象,那有没有合适的解决方案呢?
**其实,解决一个问题的最好方法就是减少或者避免它的产生**。就像我刚才说的,辛普森悖论是两组在不同细分领域中的分布不均造成的。想想看,如果我们在分析测试结果前做好了合理性检验,那出现辛普森悖论的几率就会大大减小。
不过,如果在分析结果前我们没有做好合理性检验,那还有别的办法可以解决吗?
当然有,不过会比较麻烦。如果我们在进行总体分析和细分分析时发现了辛普森悖论,最好的解决办法就是重新跑实验,看看两组在不同细分领域的分布不均会不会消失。
如果分布不均的情况还是没有消失,那就说明这很可能不是偶然事件。这个时候就要检查看看是不是工程或者实施层面出现了问题,由此造成了分布的不均匀。如果是工程层面出现了问题,那就要有针对性地去解决。
当然如果时间比较紧迫,没有时间重新跑实验和检查问题的原因,那么就以细分领域的结果为准,因为总体结果出现了辛普森悖论会变得不准确。不过这里因为是比较细分领域,会出现多重检验问题,要用我们上节课讲的方式做相应的处理。
好啦,现在你对辛普森悖论的理解肯定比之前更深刻了,那么我们接下来聊聊实验组和对照组的独立性这个问题。
## **实验组和对照组要相互独立**
首先要说明的是A/B测试有一个前提**<strong>实验组和对照组的实验单位是要相互独立的,意思是说测试中各组实验单位的行为仅受本组体验的影响,不能受其他组的影响**</strong>。这个前提又叫做Stable Unit Treatment Value Assumption SUTVA
针对实验组与对照组保持独立的问题可能很多人都会觉得这有什么好说的都分成两个组了肯定是各自独立的啊在实践中还真不是这样的。我们在做A/B测试时经常会在不知不觉中因为实践中碰到了一些业务场景导致检验两组的独立性被破坏了而这就会破坏实验结果的准确性。
这还是因为A/B测试的本质是因果推断所以只有在实验组和对照组相互独立互不干扰的情况下如果测试结果有显著的不同那么才能把这个显著不同归因成实验组相对于对照组的变化否则就很难建立准确的因果关系。
这么说你可能理解得还不够深刻下面我就结合具体的业务场景来看下在A/B测试中两组实验单位的独立性都是如何被破坏的。
### **破坏两组独立性的表现形式有哪些?**
在A/B测试中两组的独立性被破坏主要表现在社交网络/通讯,共享经济以及共享资源这三类业务上,下面就让我来为你一一讲解。
**第一类业务是社交网络/通讯类业务。**
这类业务主要是用户之间的交流和信息交换典型代表包括微信、微博、领英Linkedin、语音/视频通讯、电子邮件,等等。
在这类业务中会存在网络效应。网络效应也就是网络中相邻的各个节点会相互影响。如果节点A在实验组而它相邻的节点B在对照组这时候两者就不是独立的。
我举个例子来帮助你理解。某社交App改进了信息流的推荐算法通过推荐给用户更相关的内容来增加用户的互动现在呢我们想通过A/B测试来检测算法改进的效果。
- 对照组:使用旧算法。
- 实验组:使用改进后的新算法。
- 评价指标:用户的平均使用时间。
这样我们就可以做个假设实验组的用户A体验到了改进后的新算法看到了更多喜欢的内容就花了更多的时间在这个App上同时也在App中分享了更多有趣的内容和朋友有了更多的互动。而他的好友用户B恰巧在对照组那么当B看到A分享的内容和互动后可能也会花更多的时间在App中浏览并且参与到和A的互动当中即使B并没有体验到改进后的算法。
这就是一个典型的A/B测试中网络效应的例子。在实验组的用户A会因为A/B测试中的变化而改变使用行为并且这个行为上的改变会通过网络效应传递给在对照组的好友B从而改变了用户B的使用行为这就使得对照组也间接受到了实验组中新算法的影响。
这显然违背了我们在对照组给用户旧算法体验的实验设计,所以测试结果很可能是两组的指标都升高,造成结果不准确。
**第二类业务是共享经济类业务。**
共享经济类业务一般是双边市场Two-Sided Market即公司只提供交易平台供给方和需求方均是用户。典型代表包括淘宝、滴滴、Uber、共享单车、共享租赁、爱彼迎(Airbnb),等等。在这类业务中,由于供需关系是动态平衡的,一方的变化必然会引起另一方的变化,从而造成实验中两组相互影响。
比如说我们在用A/B测试验证不同的优化是否有效时往往只能一次验证一个优化。如果我们用A/B测试检验一个需求侧的优化就要在需求侧分成实验组和对照组这样实验组由于受到了优化就会导致需求增加。那么在供给一定的情况下更多的供给流向了实验组就会造成对照组的供给减少对照组的用户体验会变得更差从而进一步打击对照组的需求。
我给你举个例子假设某共享打车服务优化了用户在App中的打车流程现在我们要通过A/B测试来验证这个优化是否有效果。
这里实验组依然是使用优化流程对照组则使用旧流程。实验组的用户因为流程的优化打车更加方便吸引了更多的司机。而由于司机的数量是稳定的这就会导致可供对照组选择的司机减少对照组的用户更难打到车用户体验变差那么通过A/B测试得出的流程优化的效果相比较对照组就会被高估。
**第三类业务是共享资源类业务。**
有些共享资源类业务有固定的资源或者预算,最常见的就是广告营销了。
在营销预算固定的情况下我们用A/B测试来验证不同广告的效果。如果发现我们在实验组改进后的广告效果更好点击率更高那么这就会造成对照组的广告预算减少从而影响到对照组的广告效果。因为线上的广告大部分是按点击次数付费的所以这时候实验组广告花的钱就越多在营销预算固定的情况下就会抢占对照组的预算。以此来看通过A/B测试得出的实验组的广告效果就会被高估。
### **如何避免破坏两组的独立性?**
那么,从我刚才讲的三类业务中你也能看出来,在实际业务场景中,由于违反两组实验单位独立性的表现形式和原因有很多,所以也会有不同的方法来解决,不过总的原则就是**通过不同形式的分离来排除两组之间的干扰****。**具体而言主要有以下4种分离方法
**第一种方法是从地理上进行分离。**
这类方法主要适用于受到地理位置影响的线下服务,比如共享出行和共享租赁,这种本地化的服务一般不同的地域之间不会有干扰,这时候就可以按照不同的市场来分类。
最常用的是从城市这个维度进行分类。比如把北京的用户作为实验组,把上海的用户作为对照组,这样就可以排除两组间的干扰。需要注意的是,这里选取的不同市场要尽量相似,具有可比较性。我所说的相似,包括但不限于:该项业务在当地的发展情况,当地的经济状况,人口分布情况等等。
**第二种方法是从资源上进行分离。**
这类方法主要适用于由于共享资源造成的两组之间的干扰。具体操作就是A/B测试中每组的资源分配比例要和每组样本量的比例一致。比如在做广告营销中如果通过A/B测试比较不同组的广告的效果那么每组分配的广告预算的比例要和每组的样本量比例相等比如两组样本量均分时广告预算也要均分这样两组之间的广告预算才能互不干扰。
**第三种方法是从时间上进行分离。**
这类方法主要适用于不易被用户察觉的变化上,比如算法的改进。这类方法的原理就是实验组和对照组都是同一组用户,在一段时间内实施变化,给他们实验组的体验,然后在另一段时间内不实施变化,给他们对照组的体验。
需要注意的是,这个时间段的单位可以是分钟、小时或者天,这样的话因为在同一时间内所有的实验单位都属于同一组,也就不存在不同组之间的干扰了。不过用这种方法时要特别注意用户的行为可能会在每天的不同时段,或者周中/周末有所波动。如果有周期性波动的话,就要在比较时尽量在不同周期的同一个阶段进行比较,比如只把周中和周中比较,周末和周末比较,但是不能把周中和周末比较。
**第四种方法是通过聚类Clustering的方法进行分离。**
这种方法主要适应于社交网络类业务。社交网络中用户之间的连接其实也不是均匀的有远近亲疏那就可以通过模型的方法根据不同用户之间交流的程度来分离出不同集群cluster每个cluster都会有不同的联系很紧密的用户我们可以把每个cluster作为实验单位随机分组这样就能从一定程度上减少不同组之间的干扰。
这种方法比较复杂,实施难度大,需要数据模型和工程团队的支持,有兴趣的话可以参考[Google](https://www.unofficialgoogledatascience.com/2018/01/designing-ab-tests-in-collaboration.html)和[Linkedin](https://engineering.linkedin.com/blog/2019/06/detecting-interference--an-a-b-test-of-a-b-tests)的经验。
## **小结**
在这节课,我具体讲解了辛普森悖论和实验/对照组的独立性这两个常见的实验误区,以及在实践中的常用解决办法。相信通过这节课的学习,你能够在实践中及时发现并解决它们。
另外啊,我把这两节误区系列的内容呢也总结成了一张图,放在了文稿里,你可以保存下来,方便之后的复习与巩固。<br>
<img src="https://static001.geekbang.org/resource/image/f1/60/f15c4e61a25649f4bd8316ec9edb1860.png" alt="">
到这里我们的常见实验误区系列就告一段落了通过这两节课的学习你也体会到了我在讲课时不断说的真实业务场景的复杂多变潜在的各种各样的坑这些误区和问题其实都是通过一次次A/B测试去积累试错得出的所以就更加体现出了实践在A/B测试中的重要性。
如果你能在A/B测试中及时识别和解决这些常见的潜在的误区不仅能为公司挽回潜在的损失获得持续的增长也是区别你和A/B测试新手的重要标志。
## **思考题**
结合自己的经验想一想过去有没有在A/B测试中遇到辛普森悖论和实验/对照组的独立性被破坏的情况?以及当时是如何处理的呢?
欢迎把你的思考和收获分享在留言区,我们一起学习、讨论。如果这两节的误区系列帮你解答了一些疑难问题,也欢迎你把课程分享给你的同事、好友。我们下节课再见。

View File

@@ -0,0 +1,120 @@
<audio id="audio" title="12什么情况下不适合做A/B测试" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/be/bc/bee88ebdca67f42bc58ee44701dfeebc.mp3"></audio>
你好,我是博伟。
我们知道A/B测试是帮助公司实现持续增长的利器。然而没有任何一种方法能解决所有的问题让我们一劳永逸。A/B测试也是如此。
A/B测试可以解决大部分因果推断的问题。但在有些因果推断的业务场景下A/B测试就不适用了。这个时候我们就需要另辟蹊径换一种思路和方法来解决问题。
所以今天这节课我们就来学习A/B测试在什么情况下不适用如果不适用的话有哪些相应的解决方法。
## **A/B测试在什么情况下不适用**
在实践中主要有3种情况下A/B测试不适用
### **当<strong><strong>没有办法控制想要测试的变量**</strong>时</strong>
A/B测试是控制变量实验它的一个前提就是我们必须可以控制想要测试的变量的变化这样才能人为地给实验组和对照组的实验单位不同的用户体验。但是在有些情况下我们就没有办法控制变量的变化。
你可能会有疑问,有这样的变量吗?
当然是有的,主要是用户个人的选择。我们能够控制的变量其实都是在产品和业务端,但是对于用户个人的选择,我们其实是没有办法、也不可能去控制的。毕竟用户都是有自由意志的,所以我们所有的营销方法都是努力去说服用户,但最终选择权还是在用户手里。
比如我们想要了解用户从QQ音乐换到网易云音乐后使用情况的变化那更换音乐App就是我们想要测试的变量。需要注意的是我们无法帮助用户决定是否要更换音乐App的行为因此我们也没有办法做到真正的随机分组。
你可能会说我们可以通过营销给用户优惠甚至付费让用户去更换音乐App这在实践上是可行的但是在实验中就会产生新的偏差。因为对于外界激励不同的用户会有不同的反应我们可能只研究了对外界激励有反应的用户而忽略了对外界激励没有反应的用户。这样得到的实验结果是不准确的。
### **当有重大事件发布时**
重大事件的发布,主要指的是新产品/业务的发布,或者涉及产品形象的一些改变,比如商标/代言人的改变我们往往是不能进行A/B测试的。因为凡是重大事件的发布会都想要让尽可能多的用户知道并且也花了大量营销的钱。在当下这个信息流通极度发达的互联网时代不存在我公开发布了一个新品只有一小部分用户知道这种情况即使是中小企业也是如此。
比如苹果公司每年的新品发布会并不会、也不可能事先去做大规模的用户A/B测试来看看新品的效果如何然后再决定是否要发布。
再比如,一个公司如果想要改变自己的商标,就不能事先把用户进行分组,让实验组的用户接触新商标,对照组的用户接触旧商标。因为商标是一个公司或者产品的形象,你想想看,如果把用户进行分组,就会出现同一个产品同时有多个商标在市场流通的情况,那就会对用户造成困惑,而且也不利于产品形象的打造。
### **当用户数量很少时**
这个其实很好理解如果我们没有一定的流量能让我们在短时间内达到所需要的样本量的情况下那么A/B测试也就不再适用了不过这种情况其实在大数据的互联网行业中比较少见这里我们就不展开讲解了。
## **当A/B测试不适用时有哪些替代方法**
当A/B测试不适用时我们通常会选用非实验的因果推断方法和用户研究两类方法来替代让你在想做因果推断却又不能进行A/B测试时有新的思路和方法。
### **倾向评分匹配(****Propensity Score Matching**
非实验的因果推断方法,又叫[观察性研究](https://en.wikipedia.org/wiki/Observational_study)这其中最常用的就是倾向评分匹配Propensity Score Matching简称PSM。我在第9节课已经介绍了PSM它的本质就是**在历史数据中,通过模型的方法,人为地(而不是像实验那样随机地)构建出相似的实验组和对照组,最后再<strong><strong>对两组**</strong>进行比较。</strong>
这里我会通过一个音乐App的案例来详细讲解下用PSM替代A/B测试时是怎么在因果推断中应用的。
这款音乐App是付费订阅模式有两种订阅方式
- 个人订阅每月10块钱只能供一个人使用。
- 家庭订阅每月20块钱最多可以5人同时使用。
此外不管是个人订阅还是家庭订阅只要是新用户都会有3个月的免费试用期。
数据分析师通过大量的数据分析发现,家庭订阅比个人订阅用户的长期留存率(即续订率)更高。仔细想想其实也很好理解,家庭订阅可以和他人分享,所以每个订阅中的用户会更多一些,一般不止一个。而订阅中的用户越多,就越不容易取消这个订阅,所以长期留存率会越高。
于是这位数据分析师就根据这个分析发现,向营销经理推荐:可以向个人订阅的用户发广告,宣传家庭订阅的好处,鼓励他们升级到家庭订阅。
不过营销经理却提出了不同的意见:选择家庭订阅的用户和选择个人订阅的用户,在本质上就是不同的。比如他们的用户画像、使用行为等,都存在很大差异。也就是说,并不是升级本身导致了用户留存的提高,而是由于他们本来就是不同的用户,所以留存才不同。
为了验证营销经理的想法,数据分析师详细地分析了两种订阅方式的用户画像和使用行为,发现果然如营销经理所说,从个人订阅升级到家庭订阅的用户和没有升级的用户差别很大,比如升级的用户平均年龄更大,使用的时间更长等等。<br>
<img src="https://static001.geekbang.org/resource/image/15/e0/1512f3c5fee200148e2673924b534be0.png" alt="">
看到这里,你大概已经知道了,个人订阅升级到家庭订阅是否会提升用户留存率,其实是一个因果推断的问题。
数据分析师的观点是“从个人订阅升级到家庭订阅”这个原因,可以导致“用户留存提升”这个结果。
但是营销经理的意见是影响用户留存的因素有很多,在用户升级这个情境下并不能排除其他因素,因为升级是用户自己的选择,那么很有可能升级和不升级的用户本来就是两类不同的人,所以在其他因素不相似的情况下就不能只比较升级这一个因素。
两者的观点看起来都很合理,那我们该通过什么方法来验证谁对谁错呢?
验证因果推断的最好方法当然是做A/B测试了但是在这个业务情景下由于是否升级这个变化因素是用户的自主选择我们并不能控制所以就并不能做随机分配的实验。那么这个时候非实验的因果推断方法PSM就可以派上用场啦。具体方法如下。
首先,我们从历史数据中选取在同一个时间范围内开始个人订阅的试用期用户。
在三个月试用期结束后还在付费的用户中有的依旧是个人订阅有的则升级成了家庭订阅。而在这自然形成的两类用户中我们通过PSM的方法对用户的画像和使用行为等因素进行匹配在没有升级的用户中选出和升级用户相似的用户然后在这些相似用户中比较长期的用户留存<br>
<img src="https://static001.geekbang.org/resource/image/03/a1/039bf75eb85b3ac53d0bb23b4a4c8ba1.png" alt=""><br>
接着进行完PSM后呢我们再来比较下个人订阅和家庭订阅各自的用户画像和使用行为。<br>
<img src="https://static001.geekbang.org/resource/image/0f/cc/0f022b49bdf629d2c6c97eda8f02fdcc.png" alt=""><br>
从数据中我们可以发现经过PSM处理后的没有升级的用户和升级的用户在各个特征上都已经非常相似了那么这个时候我们就可以进行比较了。当我们比较时因为已经控制了其他特征相似两组只有“是否升级”这一项不同所以如果用户留存有变化那就说明是升级这个变化因素造成的。
最后我们来看一下最终的比较结果。下图中的纵轴是用户留存率横轴是从试用期开始时的月份因为试用期是3个月且试用期内不存在续费问题所以留存率就是100% 那我们就从第4个月开始算用户留存率。<br>
<img src="https://static001.geekbang.org/resource/image/0f/c7/0f72d69608847c0d312e900e8af22ac7.png" alt=""><br>
从图中可以看到如果我们不做PSM的话就像最开始数据分析师发现的那样个人订阅升级到家庭订阅能够使一年的留存率提升28% 但这是在没有剔除其他因素的情况下所以28%这个结果就不够准确(营销经理的观点)。
那么经过PSM处理后我们得到了和升级用户相似的非升级用户结果发现升级确实能提升用户留存不过只能提高13%那就说明只有13%的用户留存率的提升可以归因于用户升级。
这里我们通过PSM在剔除了其他因素的影响之后模拟出了一个控制变量实验从而确定了个人订阅升级到家庭订阅对用户留存所带来的准确影响。
### **用户研究**
用户研究适用于A/B测试无法进行时比如新产品/业务发布前的测评,我们就可以通过直接或间接的方式,和用户交流沟通来获取信息,从而判断相应的变化会对用户产生什么影响。
用户研究的方法有很多种我们今天主要来聊一聊常用的几种深度用户体验研究Deep User Experience Research焦点小组Focus Group和调查问卷Survey
深度用户体验研究,指的是通过选取几个潜在用户进行深度的信息提取,比如通过用户眼球的运动来追踪用户的选择过程的[眼动研究](https://vwo.com/blog/eye-tracking-website-optimization/),或者用户自己记录的[日记研究](http://www.woshipm.com/user-research/3073582.html)。
- 眼动研究能让我们了解到用户的正常使用流程是什么样的,在哪些阶段会有卡顿或者退出。
- 日记研究通过用户自己记录的使用情况和意向,来了解他们的反馈。
[焦点小组](https://baike.baidu.com/item/%E7%84%A6%E7%82%B9%E5%B0%8F%E7%BB%84%E8%AE%BF%E8%B0%88%E6%B3%95/1054398)是有引导的小组讨论,由主持人把潜在的用户组织起来,引导大家讨论不同的话题,然后根据大家在讨论中发表的不同意见,综合得出反馈意见。从小组讨论这个形式就可以看出,每次焦点小组能够组织的用户一般要比深度用户体验研究的用户数量要多,但是比调查问卷的用户数量要少。
[调查问卷](https://baike.baidu.com/item/%E8%B0%83%E6%9F%A5%E9%97%AE%E5%8D%B7/10015839)就是通过事先设计好想要了解的问题,可以是选择题或者开放式的问题,比如对新品/新业务的想法和感受。然后把这些问题做成问卷发放给潜在的用户。交流方式可以是面对面、线上或者是电话等等,然后根据不同用户的回答结果,统计出大致的反馈结果。<br>
<img src="https://static001.geekbang.org/resource/image/e1/47/e1070c0834b76879c0578ba42c4b8247.png" alt=""><br>
从图中可以看出,从深度的用户体验研究,到焦点小组,再到调查问卷,虽然参与的用户越来越多,但是团队从每个用户身上获得的信息深度会越来越浅,所以选择何种方法也取决于你能招募到多少潜在用户,有没有相应的条件与设备(比如眼动研究需要眼动仪来完成),还有想要得到的信息深度。
## **小结**
今天这节课我们讲解了A/B测试的局限性通过案例介绍了非实验的因果推断方法-倾向评分匹配PSM也带你简单了解了用户研究的相关方法。实践中出现较多的还是我们没有办法控制的用户选择这种变量主要会用到PSM这种非实验的因果推断方法。那么用户研究在实践中不仅可以用于新产品/业务的测评还可以用于产生新指标的想法比如我在第3节课中讲到的定性+定量相结合的方法来确定指标)。
那么从开头到今天这节课呢我们的专栏讲解了A/B测试的统计原理标准的流程以及实践中各种常见问题及解决方法。说到应用这些经验和方法论呢工作场景自然是最佳场所不过还有另一个实践的好机会那就是在面试中。
那么在接下来的两节课我就会带你去过一遍面试中常考的A/B测试问题。同时我也建议你先梳理下自己面试时曾被问到的那些问题以及自己当时自己是怎么回答的。这样我们在学习后面两讲内容的时候也会更有针对性。
## **思考题**
结合自己的经验想一想你有没有见到过或经历过想进行因果推断相关的分析但是A/B测试却不适用的情况详细说一说原因和结果。
欢迎你把对本节课的思考和想法分享在留言区,我会在第一时间给你反馈。

View File

@@ -0,0 +1,163 @@
<audio id="audio" title="13融会贯通A/B测试面试必知必会" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/86/a5/86b9aeb6ca23c957ffd6cdba507588a5.mp3"></audio>
你好,我是博伟。
在接下来的两节课呢我们换换脑子来聊一个相对轻松点的话题与A/B测试相关的面试应用。
近几年随着A/B测试在互联网、电商、广告等各个行业的广泛应用已经成为数据、产品、增长等相关职位面试的一个重要组成部分。所以我就根据自己多年做面试官的经验帮你总结了常见的A/B测试相关面试考点一方面我会通过典型真题来讲解面试思路另一方面也会把我在面试中的一些沉淀与思考分享出来。
另外我还想强调的是,这两节课虽然是在讲面试题,但其实也是在以另一种方式考查你对所学知识的灵活运用。面试中考察的不仅是你对知识的掌握,更关注你在工作场景中要怎么运用。所以希望你能通过这两节面试课的学习,既能学会拆解题目,提高面试能力,同时也能把我们学过的知识融会贯通。
面试题目是无穷的,但考点是有限的。我把相关的考点总结成了一张图,方便你着重复习。接下来我们就开始正式的面试讲解吧。<br>
<img src="https://static001.geekbang.org/resource/image/3b/b6/3b83b40462ea671e5b42d16cfd08cab6.png" alt="">
## 面试应用一
某共享出行公司改进了司机使用App的用户界面希望能给司机更好的用户体验在提高司机使用App频率的同时也能提高司机的收入。那么问题就是请你设计一个A/B测试来验证新的司机App是否比旧的司机App体验要好。
**考点:**
- A/B测试的流程。
- 实验组/对照组的独立性。
**解题思路:**
很多同学遇到这个面试题首先想到的就是串一遍A/B测试的流程于是就按照以下流程开始回答。
**确定目标和假设**&gt; **确定指标**(说出评价指标和潜在的护栏指标)—&gt; **确定实验单位****—**&gt; **随机分组**(一般为均分) —&gt; **确定样本量**(这里注意,强调需要已知哪些统计量来确定样本量)—&gt; **实施测试**&gt; **合理性检验**(要说出具体的检验都有哪些)—&gt; **分析结果**注意说明P值法和置信区间法的判断标准
如果你只回答了设计流程这一点可能仅仅是个及格分因为题中还设置了至少1个隐藏的坑点这也恰恰就能拉开你与其他面试者的距离。
首先要注意在回答流程时一定要结合题目的具体内容展开讲解否则就是照本宣科会给面试官留下不能活学活用的印象。如果你不知道怎么回答比较好可以参照我在第8节课串讲案例的思路和方法。
不过这道题最大的坑点还不在这儿你需要再细心点儿。仔细看“共享出行”这个具体情境如果你对第11节课中两组独立性这个知识点掌握得足够牢固就会发现面试官在这道题中想考查你的绝不是串讲一遍流程这么简单。
面试现场也是工作的实际场景,那你就需要具体情境具体分析,洞察出设计实验时需要保持实验组和对照组的独立性。
我们来通过一个例子深度剖析一下。
假设我们选取在上海使用该共享出行的司机把他们随机分成实验组和对照组每组各占50%。其中在实验组司机使用新的司机App对照组则使用旧的司机App。
我们先来看实验组: 如果新App的确提升了司机的用户体验司机的使用频率提高这意味着实验组的订单量就会增加。因为订单总量需求是一定这样就会导致对照组的订单量减少。
与此相反的是如果新App降低了司机的用户体验司机使用App的频率降低那么实验组的订单量就会减少对照组的订单量则会增加。
这时你就会发现:**实验组和对照组不是独立的,而是相互影响的。**这就违背了A/B测试中实验组和对照组必须是相互独立的前提假设从而导致实验结果不准确。
在题目中的场景下比较好的解决方法是在不同的城市进行测试我们找到两个相似的城市A和B相似的目的是使两组具有可比性比如业务在当地的发展程度、经济发展程度、人们的出行习惯等实验组是城市A中的司机使用新App 对照组是城市B中的司机使用旧App。这样的话两组就不会相互影响。
所以针对这道题,完整且正确的回答方式应该是:先指出两组独立性被破坏的问题,通过举例分析说明两组是相互影响的;然后提出你的解决方案;最后结合实际情境串讲流程。
其实啊,如果你是个高手,就应该看出题中还有一个隐藏的考点:学习效应。
因为题目中是测试新的用户界面,所以还可能会有老用户的学习效应:新奇效应或改变厌恶。关于这个考点,你在这里简单提及,说明识别及解决方法即可,不需要长篇大论再进行展开。因为这道题考察的核心重点依旧是两组的独立性和设计流程,但是如果你能留心到潜在的学习效应问题这个坑,这就相当于你在优秀的回答之外,还给了面试官一个惊喜,证明你有填坑的能力。
## 面试应用二
在过去的实践中你有没有经历过这种情况A/B测试虽然得到了显著的结果比如P值小于5%),但最终还是决定不在业务/产品中实施测试中的变化。原因是什么呢?请举例说明。
**考点实施A/B测试中的变化要考虑的因素**
**解题思路:**
这道题很简短,乍看上去会觉得很容易,往往这个时候你就要小心谨慎了。仔细想想,面试官想通过这道题来考查什么知识点呢?考察你的什么能力呢?
在知识点上面试官主要考查的是在实践中实施A/B测试中的变化时需要考虑的因素有哪些。
这个问题其实是非常直接的,你很容易知道面试官在考察什么知识点。不过我想强调的是这类问题在面试中还有很多的变体,你需要在不同的变体中识别出本质问题。
- 核心问题:面试官会从结论出发(最终没有实施变化),问你可能会有哪些原因。
- 变体1面试官会给你测试结果的数据数据中的P值虽然小于5%但是十分接近5%比如4%。说明两组变量间的不同其实非常小,对实际业务的影响十分有限。
- 变体2面试官会直接问你实施A/B测试中变化的成本是什么。
无论怎么变化,归根结底都是一句话:结果是统计显著的,但是业务并不显著,因此在实践中没有实施变化。
在实践中统计上的显著结果只是最终实施变化的原因之一另一个方面还要考虑到实施变化的成本和收益。收益的话我们可以根据显著结果的差值来估算但是就成本而言我们需要考虑的因素是多方面的就像我在第7节课中讲的需要估算业务上的显著性。
所以在回答这类题目时,结合案例围绕着以上这些成本展开讲解,提出结果是统计显著,但是业务上不显著,所以最后才没有在实践中实施变化。
具体来说,在实践中实施变化主要有以下几种成本。
**人力成本**
指的是要实施变化的相关人员的时间成本,比如工程师需要花时间去实施具体的变化,编写相关代码。产品经理需要花时间去收集整理新的要求,组织相关会议,编写文档。如果变化会引起用户困惑的话,那么客服人员还要花时间去给用户答疑解惑。
**机会成本**
在实践中,时间和资源在业务/产品的不断迭代当中是永远不够用的请你想象一个场景在新版本上线前如果同时有A和B两个变化都具有统计显著性P值均小于5%),但我们的时间和资源有限,在上线前只能实施一个变化,那这个时候肯定会选择对业务影响较大的变化。
那你就会问了当这两个的P值都小于5%时,我该怎么比较哪个变化对业务产生的影响更大呢?
具体来说有两种方法。
第一种方法就是估算变化带来的业务影响。这种方法适用于不同变化有着不同的评价指标,或者不同的受众范围。
比如变化A使转化率提升了2%每年可以多带来10万的新用户。变化B使留存率提高了0.5%每年可以多留住5万的现有用户。此时我们就要衡量增加10万新用户和留住5万现有用户的价值哪个更大比如可以通过数据分析或者建模的方式确定新用户和现有用户的平均价值
当然这也和所处阶段的业务目标有很大关系,你需要看当时的业务重点是拉新还是留存。一旦我们量化估算出变化带来的业务影响,就可以决定该优先实施哪个变化了。
第二种方法是计算[效应值](https://www.simplypsychology.org/effect-size.html)Effect Size。这种方法适用于变化相似且评价指标相同时。
比如改进推荐算法的实验大都以点击率作为评价指标。那么现在有新算法A和新算法B和老算法相比都有提升那么这时就要计算每个实验的效应值
<img src="https://static001.geekbang.org/resource/image/ff/e5/ff979c4bdbc122a405832ebd196547e5.png" alt=""><br>
效应值在统计中是用来表示指标变化的幅度的,效应值越大,就说明两组指标越不同。
如果我们计算得到的新算法A的效应值比新算法B的大就说明A的改进效果幅度更大影响也更大那就可以决定优先实施A变化了。
计算效应值其实也是估算变化带来的影响,不过因为这些变化都有相同的评价指标,所以我们只需要算出效应值来进行比较即可。
**代码成本**
实施变化一般需要代码的改动,这种改动会潜在地增加代码出错的概率,同时随着代码库越来越复杂,也会增加未来代码改动的成本。
## 面试应用三
我们对公司网站进行了改版想要以此来提升用户参与度。通过A/B测试发现新版本的用户参与度确实显著提升了所以我们随后就对所有用户显示了新版网站。但是过了一段时间后用户参与度又回到了之前的水平。假设这个A/B测试本身没有技术上或者统计计算上的问题。你觉得导致这种情况的原因会是什么呢又该怎么解决呢
**考点:学习效应**
**解题思路:**
这道题在知识点上的难度并不高,主要考察的是学习效应的问题。不过你要是只回答了这一个原因,这其实是大多数面试者都容易想到的,也仅仅只是一个合格的分数。
我先把自己更推荐的回答方式写出来,然后再带你仔细分析这道面试题。
比较推荐的回答方式是:先列举导致这种情况可能的原因有哪些,再结合题目的具体场景进行一一排除,最后得出自己的结论,给出解决方法。
为什么要这么回答呢?主要是因为相比较仅仅回答一个原因,或者直接给出解决方法,这种回答方式更能体现你对问题的全面理解。我在之前的课程中也强调过,知道为什么会出现这个问题,并发现问题,有时候甚至比解决问题还要重要。所以面试官在这里重点想要考察的,就是你对出现问题的原因的探究。
变化实施后的实际效果和A/B测试的结果不一致其中的原因有很多种最常见的原因主要是两个
- 实施A/B测试中出现的技术Bug。
- 在计算测试结果时出现错误(比如还没到足够的样本量就去计算结果)。
接下来我们进行一一排除。
首先题目中明确说了技术上和统计计算上都没有问题那接下来就要排除A/B测试常见的误区。
其次,由于题目中的场景并不是社交网络或者像共享经济的双边市场,实验组和对照组不会相互干扰,所以也不存在实验/对照组独立性被破坏的情况。
接着,从测试本身的设置和对结果的描述来看,没有细分分析或者多个实验组,又不会有多重假设问题或者辛普森悖论。
最后,对于网站不同版本这种问题,其实最常见的问题是学习效应,就像我刚才分析的那样,把其他常见的原因都排除了,那么其实考察的知识点就是学习效应。考察学习效应的面试题形式有很多种,有的会直接问你学习效应,有的就会像是本题中,给你一个具体的场景,让你判断。
根据题目描述的情况,应该是学习效应中的新奇效应:用户刚开始对于新版本很好奇,所以参与度会上升。但随着时间的推移,慢慢又会回归到正常平均水平。
至于如何识别和解决学习效应如果你还不能顺利回答出来那就得再回去复习第10节课的内容了。
所以你看,在面试中,面试官考察你的不仅是知识点,更重要的是你对问题的发散理解,以及思考问题的方式。
## **小结**
在这节课里我主要讲了3道面试题通过我的详细分析你也能够发现拆解题目是一项很重要的能力。
很多人在面试前都会去刷题,刷题固然重要,但是在面试这种高压场景下,可能回出现大脑短暂空白的情况。其实面试题目也是有套路的,就像搏击中的双方,你需要猜测对方可能会出什么招式,如果你能在对方出招前反应出他的下一步动作,哪怕是一秒钟,就有机会制胜对方。所以相对于海量刷题,学会拆解题目就显得更重要了。
相信你通过今天的学习对于A/B测试相关面试的形式和考点有了初步的了解你一定还意犹未尽没关系我们下节课接着来剖析典型面试题及考点。
## 思考题
你有遇到过什么有意思的A/B测试的面试题吗或者是有什么好的面试经验吗欢迎分享出来我们一起探讨。
欢迎分享出来,我们一起交流、探讨。也欢迎你把本节课推荐给你的朋友,一起进步、成长。

View File

@@ -0,0 +1,127 @@
<audio id="audio" title="14举一反三A/B测试面试必知必会" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/ac/73/acff622b8181e64e1275357a9a72ca73.mp3"></audio>
你好,我是博伟。
今天这节面试课,在学习的过程中你会发现考察的知识点都已经掌握得差不多了。不过我想要强调的是,知识是你业务精进的基础,也是面试时考察的一个重要方面。但更为关键的,是你能够把知识举一反三,知道在不同的场景中如何应用,这也正是把知识转化为解决问题的能力,是你的面试竞争力。
好了,那我们就趁热打铁,继续来讲面试这个主题,帮你夯实基础,做到面试不慌!
## 面试应用一
假设你现在负责跑一个A/B测试根据样本量计算测试需要跑2周。但是业务上的同事会每天关注测试结果一周之后就观察到显著结果了这时候他觉得既然结果已经显著了就想让你停止测试然后实施测试中的变化。由于业务上的同事对统计不是很熟悉所以你该怎么用直白的语言来给他解释现在还不能停止实验呢
**考点:**
1. 多重检验问题
1. 统计原理的通俗解释
**解题思路:**
其实这道题我在第7节讲分析测试结果时就给出了一个类似的实践背景由于在样本量还没有达到规定前不断查看结果就会造成多重检验问题。而一旦出现多重检验我们之前花费的功夫就会功亏一篑。所以在这道题中你需要首先指出多重检验问题接着说明出现的原因以及可能造成的具体后果得到假阳性的概率增大实验结果不准确
你也能看出来,如果只是考多重检验问题,那就太简单了。斟酌一下题目中的问题,就能知道面试官想要考察的是其实是你的表达与理解能力,也就是说你该怎么用**通俗直白的语言**来给业务同事解释复杂难懂的统计概念和原理。在实际工作中很多时候需要和没有统计背景的同事去沟通交流A/B测试的相关内容所以面试官也非常喜欢考察面试者这方面的能力。
不仅如此,这其实也是在变相考察面试者是不是真正内化了相关统计知识。毕竟如果只是死记硬背概念,肯定是不能在实践中灵活运用这些原理的,更别说再把这些原理用直白的语言去讲给没有统计背景的人听。
你可能会问,通俗直白的语言到底是什么呢?其实也很简单,就是说人话。我的经验就是“一个避免,两个多用”。
**一个避免,指的是尽量<strong><strong>避免使用统计术语P值**</strong>、**<strong>第一类错误**</strong>、**<strong>假设检验等)**</strong></strong>
一方面,专业统计术语会加大你们沟通的时间成本和沟通障碍。业务同事是不懂这些术语的,当你用专业术语去向他说明时,你就需要花更多的时间来解释术语,不仅对方难以理解,而且你们的沟通目的也没有达到。
另一方面,仔细想想,你为什么要去给业务同事解释呢?主要就是为了告诉对方,现在还不能停止实验。所以啊,说清楚为什么不能在此时停止实验就可以了,术语能少则少。
**两个多用指的是多打比方、多举例子。**尤其是通过日常生活中的事物来打比方、举例子,这会是非常好的一种方式。
比如A/B测试其实是比较两组的表现既然有比较那就有好坏输赢的概念。那**你就可以选择生活中任何有好坏输赢结果,但是每次发生结果都有可能不同的事件来<strong><strong>打比方**</strong></strong>
我比较喜欢拿体育比赛来打比方比如篮球就和A/B测试非常类似。每场NBA篮球比赛都会有事先规定的时间48分钟。而且篮球比赛的结果是以比赛结束后的最终结果为准。如果在比赛结束前的任何时间查看比分任何一方都有可能领先但是我们并不会以比赛中间的结果作为最终结果。
同理回到A/B测试当中来如果我们还没有到达规定的时间看到显著的结果就宣布实验已经完成从而停止实验这就和在比赛中看到一方领先就宣布领先的一方获胜、比赛结束是一样的道理。
再回到我们的面试场景中多重检验问题在工作中其实是很常见的。尤其是在业务上的同事没有很强的统计背景的情况下可能只是依靠P值来做决定不会考虑样本量是否充足这个前提所以用通俗的语言来解释这些统计原理尤为重要。
## 面试应用二
某产品现在想改变商标,所以想衡量新商标对业务的影响,该如何做?
**考点:**<br>
A/B测试的适用范围及替代方法
**解题思路:**
如果你对第12节课讲“什么情况下不适合用A/B测试”的知识足够熟悉就知道这里并不能用A/B测试来衡量商标改变的影响性。我讲过“当有重大事件发布时”是不适合去做A/B测试的商标即是其中之一。毕竟商标代表了产品和公司的形象如果一个产品有多个商标同时在市场流通就会给用户带来困扰从而会对产品形象有不利的影响。
还记得A/B测试的两种替代方法吗分别是非实验的因果推断方法和用户研究。不过啊在这个情境下非实验的因果推断方法也行不通因为这个商标是全新的并没有历史的相关数据。所以用户研究就是我们最终选定的方法。
在这个案例中,我们只需要收集用户对新商标的看法如何,所以就需要的样本尽可能大一些,这样意见才有代表性,但是并不会涉及到用户体验等很有深度的问题。那么我们就可以选用调查问卷的方式来收集用户反馈,从而给我们一些方向性的指导。让我们知道相较于现有的商标,用户对新商标偏正面反馈,还是更偏负面反馈。
如果从调查问卷中得到总体正面的反馈后,团队决定在市场中废除现有商标,推出新商标。这时候就可以来衡量更换商标后的影响,相对于比较推出新商标前后产品的北极星指标的变化来计算出差值去推断出新商标影响,一个更加准确的方法是建立模型。
我们可以用历史数据建立起对北极星指标的时间序列模型,用推出新商标前的数据去训练这个模型,它也可以预测出没有新商标的北极星指标的走势,然后我们可以把模型的预测数据和推出新商标后的实际数据进行比较,从两者的差值来推断出新商标的影响。
总结一下这道题的答题思路即说明题中场景下A/B测试不适用及其原因然后再给出用户研究和模型的办法来作为替代解决方法。
## 面试应用三
某社交网站准备给用户推荐好友在首页的右上角推出“你可能认识的人”这个新功能怎么设计A/B测试才能真正衡量这个功能底层的推荐算法的效果呢假设这里没有网络效应。
**考点:**<br>
A/B测试分组设计
**解题思路:**
当拿到题目一看到社交网站,你会立马想到网络效应,但是读完题发现这里假设没有网络效应。
你可能会想想要推出一个新功能而且还不考虑网络效应那肯定就是常规的A/B测试设计了呗。所以就把用户随机均分成两组对照组的用户没有“你可能认识的人”这个新功能实验组的用户有这个新功能。最后比较两组的指标来确定推荐新功能的推荐算法的效果如何。
你看,这没有什么难的!如果真的这么想,那你就在不知不觉中掉进面试官给你设的坑了。
我们再仔细读题中的场景描述,就会发现这个新功能是在页面的右上角,这意味着增加这个新功能还涉及到用户交互界面的改变。
如果按照我们刚才所说的实验分组进行设计,把实验组和对照组相比,其实是既增加了推荐算法,又改变了交互界面,是同时改变了两个因素。以此来看,即使实验组的指标相对于对照组有所提升,我们也无法确定究竟是哪个因素在起作用。
所以这道题的关键点就是如何分离这两个潜在的影响因素。在实践中,解决的方法一般是设计多个实验组,每个实验组只改变一个因素,同时共用一个对照组,也就是改变前的状态。
是不是觉得这个方法有点熟悉呢没错儿这就是我在第9节课中提到的A/B/n测试。不过这个案例的情况比较特殊因为要增加推荐算法的话肯定会改变交互界面也就是说其中一个因素必须依赖另一个因素不能单独存在。
但是如果反过来想,其实改变交互界面并不一定要增加推荐算法,所以我们可以把各个分组设计成递进关系:
- 对照组:改变前的原始版本。
- 实验组A: 增加“你可能认识的人”这个新功能, 其中推荐的内容随机产生。
- 实验组B: 增加“你可能认识的人”这个新功能, 其中推荐的内容由推荐算法产生。
我们可以发现实验组A相对于对照组只是改变了交互界面因为它的推荐内容是随机产生的。而实验组B相对于实验组A则是只增加了推荐算法而二者的交互界面是相同的。这样我们就可以通过比较对照组和实验组A来衡量改变交互界面是否有影响比较实验组A和实验组B来判断新功能的底层推荐算法是否有效果。
## 面试应用四
某社交平台开发出了一个新的交互界面希望能增加用户的点赞次数。团队通过把一部分用户随机分组进行A/B测试发现用了新界面的实验组的用户平均点赞次数比对照组高出了5%结果也是显著的。那么如果把新界面推广给所有用户你认为用户的平均点赞次数会提升多少呢是大于5%还是小于5%?为什么呢?在这个案例中,我们假设没有学习效应的影响。
**考点:**<br>
网络效应
**解题思路:**
看到“社交平台”就要想到“网络效应”,经过前面的学习,你应该对这一点形成肌肉记忆。
这道题其实难度不大,考察的是网络效应及其形成原因。不过我想通过这道题,一方面让你清楚网络效应的具体场景,另一方面,也想让你知道在有网络效应的影响下,社交平台开发新交互界面后的真实提升效果和实验结果之间的关系。
在没有学习效应的情况下,因为是社交平台,存在网络效应,所以随机分组并不能保证实验组和对照组的独立性,意味着两组的独立性被破坏了。
具体而言如果实验组的用户A因为用了的新界面点赞了一个内容那么这个被点赞的内容也会被A的好友在对照组的B看到B也有可能点赞这个内容。所以这个新界面改动既影响了实验组还会通过网络效应影响对照组即实验组的用户平均点赞次数提升对照组的也会提升。
以此来看这里的5%的提升其实是受到网络效应影响后的结果真实的提升效果应该会更大即只有实验组的指标提升而对照组的指标不变即大于5%。
所以当我们把这个新的交互界面推广到所有用户也就是在没有对照组的情况下那么和旧版本相比真实的提升效果应该是大于5%的。
## 小结
我们两节课的A/B测试的面试之旅到这里也就告一段落了。你应该也能发现这些常见的考点我们在前面的课程中都有讲解过只要你认真学习了专栏的内容是不会有太大的问题的。
在最后呢我还想强调一点。我们在这两节课讲的面试题大都是题目中直接提到A/B测试的在面试中A/B测试的考查形式是多种多样的。有时题目中并没有明确提到A/B测试但是A/B测试是这些题目中答案的有机组成部分比如让你衡量产品新功能的好坏是不是应该推进这个产品变化这种问题你的答案中肯定会有要如何定义目标和指标去表征新功能的影响如何设计A/B测试去验证新功能是否有效。总之只要让你进行因果推断需要量化改变带来的影响时A/B测试都是你的好帮手
## 思考题
这里呢我们开动脑筋如果让你用直白通俗的语言不用统计上的定义不引用其他术语解释A/B测试的相关术语的话你会怎么解释呢选取一两个尝试着解释下。
欢迎把你的解释分享在评论区,我们一起交流、讨论。同时如果你有所收获,也欢迎你把这节面试课分享给你有需要的朋友。

View File

@@ -0,0 +1,267 @@
<audio id="audio" title="15用R/Shiny教你制作一个样本量计算器" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/6c/8a/6c80a3a96474c6c400307184aa50f68a.mp3"></audio>
你好,我是博伟。
A/B测试前的样本量计算是设计实验时不可或缺的一步。在第6节讲样本量计算时我提到了现在网上的样本量计算器参差不齐的问题并且网上大部分的计算器都是只能计算概率类指标不能计算均值类指标在实际业务应用时十分局限。
鉴于这些问题加上我在实践中也想要更加快速且正确地计算样本量提高工作效率于是就从统计理论出发去钻研A/B测试样本量计算的原理让自己能够识别和掌握正确的计算方法。
后来渐渐发现身边的同事和朋友在做A/B测试时也有这方面的需求于是我就把样本量的计算方法工具化做成App放在了网上。
所以我今天教你的,就是**把样本量计算工具化的详细过程——我会带你制作一个可以发布在网上的实时计算的A/B测试样本量计算器。**
## 实战指南
既然是制作App我们还是需要进行一些简单的编程包括前端和后端使用R语言及其前端库Shiny。不过你也不用担心制作这款App不需要你掌握前端的JavaScript、HTML、CSS也不需要你会在后端如何搭建数据库。你只需要掌握以下3点就足够了。
<li>
**A/B测试样本量计算的原理**。关于原理,重点学习咱们这门课"统计篇"的两节课和基础篇的第6节课即可。
</li>
<li>
**最基本的编程知识**。我指的是通用的编程,不细指特定的语言。包括变量赋值、基本的数据类型(字符串,数字等),这些最基础的编程知识,即使不是专业的编程人员,也是大部分互联网从业者都会知道和掌握的,难度不大。
</li>
<li>
**R和Shiny的基本语法**。如果你对R和Shiny很熟悉的话那就可以直接跳过这一点。如果你之前没有接触过R和Shiny也没关系这些语法也是可以快速学习和掌握的。我在这里给你一些拓展资料供你参考学习。
</li>
- [如何安装R和Rstudio](https://ourcodingclub.github.io/tutorials/intro-to-r/#download)
- [R的基本语法](https://www.tutorialspoint.com/r/index.htm)只需看R Tutorial这部分即可
- [Shiny教程](https://deanattali.com/blog/building-shiny-apps-tutorial/)
如果你没有时间和精力学习R和Shiny的知识也别担心我会把我的代码开源贴出来你可以结合代码和本节课的内容学习理解。
相信如果你是跟我从头开始认真学习这门课的话现在你肯定已经掌握了第一点A/B测试样本量计算的原理。至于第二点最基本的编程知识相信作为互联网人的你已经掌握或者有概念性的认知了。那么我们今天就重点讲解下如何把这两点结合起来制作一个简单方便的样本量计算器在教你制作的同时呢我也会穿插讲解R和Shiny的相关知识还有一些实战案例。
在讲解前呢,我先把我的代码库和样本量计算器贴出来,供作参考:
- [代码库](https://github.com/pieces201020/AB-Test-Sample-Size-Calculator)
- [样本量计算器App](https://bowei-zhang.shinyapps.io/Sample_Size_Calculator/)
首先如果你点开GitHub上的代码库就会发现主要的文件有两个server.R和ui.R。这是Shiny App的标准文件结构其实从文件名就能看出它们大概的功能
- server.R负责后端逻辑的文件比如我们这次的样本量计算的逻辑都在server.R当中。
- ui.R负责前端用户交互界面的你的App做得好不好看全靠它了。
接着,你点开我贴出来的样本量计算器链接就会发现,它已经按照指标类型分成了概率类和均值类:
<img src="https://static001.geekbang.org/resource/image/13/2a/1329cc84db8fa9519e254cd22984fc2a.png" alt="">
那么我今天就按照这两类指标来分别进行讲解。
## 制作过程
### 概率类指标
从概率类指标的样本量计算的逻辑参看第6节课上来看我们需要函数[power.prop.test](https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/power.prop.test)。下面这段代码L31-35是在server.R文件中的具体实施
```
number_prop_test &lt;-reactive({ceiling(power.prop.test(
p1=input$avgRR_prop_test/100,
p2=input$avgRR_prop_test/100*(1+input$lift_prop_test/100),
sig.level=1-numsif_prop_test(),
power=0.8)[[1]])
})
```
函数的输入参数这里,我们需要输入以下四项信息:
- 两组的指标p1和p2。
- 显著水平sig.level。
- Power。
- 单双尾检验。
我们来对照实际的前端交互界面来看下应该怎么输入:<br>
<img src="https://static001.geekbang.org/resource/image/81/bf/81f7e0ec90dc4ce5c4314d4353011ebf.png" alt="">
**两组的指标p1和p2**
在这里我会让用户输入原始指标也就是p1和最小可检测提升。注意这里的“提升”是相对提升=p2-p1/p1而不是绝对提升=p2-p1注意和均值类指标的绝对提升进行区别。通过这两个参数就可以算出p2了。
这是根据我平时实践中的实际使用情况来设置的因为一般是有原始指标和想要获得的提升当然你也可以根据自己的需求直接让用户输入p1和p2。
**显著水平sig.level**
在这里我会让用户输入置信水平1-α),而不是显著水平α,这也是根据实践中的习惯调整的。
**Power**和**单双尾检验**
我把Power和单双尾检验都设定成了默认值是不需要用户改变的。因为很多用我制作的计算器的用户他们的统计背景并不强所以我就把Power隐藏了起来并且设定为默认的80%,这样就可以减少他们的困惑。
至于单双尾检验我在第2节课中也讲了A/B测试中更推荐使用双尾检验所以我也把它设定为默认的双尾检验从代码可以看到并没有涉及这个参数那是因为函数本身对这个参数的默认值就为“two.sided”即“双尾”
如果你还记得第6节讲的样本量计算公式的话就会知道影响样本量的因素有显著水平α、Power、两组间的差值δ和两组的综合方差$\sigma_{\text {pooled}}^{2}$。
你可能会有疑问为什么不让用户直接输入以上4个影响因素呢而是让用户输入现在交互界面上的参数呢
这其实是在帮用户省事,通过在实践中最常出现的参数,来帮助用户计算综合方差。
通过把函数的输入参数和这些影响因素对比之后你就会发现其实通过函数的输入参数完全可以确定这4个影响因素从而求得样本量。
输入完这四项信息之后,就可以开始运行了。
如果你仔细比较server.R和ui.R这两个文件就会发现整个App中两个文件通过以下方式运行的
- 整个App是通过ui.R这个文件接收到用户的输入值然后把这些输入值存到input函数中。
- 接着呢server.R再读取input进行计算再把结果存储到output函数中返回给ui.R。
- 最后ui.R再把这些结果显示在用户的交互界面上。
这里再来举个例子说明下我刚才讲的整个过程。
首先在ui.R中我们需要用户输入**原始指标**avgRR_prop_testL11-12
```
numericInput(&quot;avgRR_prop_test&quot;, label = &quot;原始指标&quot;, value = 5, min = 0, step=1)
```
**最小可检测相对提升**lift_prop_testL18-19
```
numericInput(&quot;lift_prop_test&quot;, label = &quot;最小可检测相对提升&quot;, value = 5,min = 0, step=1)
```
**置信水平**sif_prop_testL42-44:
```
radioButtons(&quot;sif_prop_test&quot;, label = &quot;置信水平&quot;,
choices = list(&quot;80%&quot;,&quot;85%&quot;,&quot;90%&quot;,&quot;95%&quot;),
selected = &quot;95%&quot;,inline=T)
```
那么这些用户输入的参数呢最后都通过input这个函数传递到server.R文件当中去进行样本量计算L31-35
```
number_prop_test &lt;-reactive({ceiling(power.prop.test(p1=input$avgRR_prop_test/100,
p2=input$avgRR_prop_test/100*(1+input$lift_prop_test/100),
sig.level=1-numsif_prop_test(),
power=0.8)[[1]])
})
```
当计算完成后再把结果存在output函数中L44-51
```
output$resulttext1_prop_test &lt;- renderText({
&quot;每组的样本量为 &quot;
})
output$resultvalue1_prop_test&lt;-renderText({
tryIE(number_prop_test())
})
```
最后output函数再把结果传递给ui.R供前端显示L57-63
```
tabPanel(&quot;结果&quot;,
br(),
textOutput(&quot;resulttext1_prop_test&quot;),
verbatimTextOutput(&quot;resultvalue1_prop_test&quot;),
textOutput(&quot;resulttext2_prop_test&quot;),
verbatimTextOutput(&quot;resultvalue2_prop_test&quot;)
)
```
这里要注意的一点是,因为通过[power.prop.test](https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/power.prop.test)函数计算出来的样本量是单组的,如果需要求总样本量时,就要用单组样本量乘上分组数量。这里的分组数量也是需要用户手动输入的。
同时你可能也注意到了我在这款App中加入了大量的解释性语言对于每个需要用户输入的参数都进行了解释说明这样做其实也是吸取了实践中的用户反馈。就像我刚才说的很多用户的统计背景并不强对于这些统计量并不熟悉所以我们要尽可能地将这些输入参数解释清楚减少用户使用时的困惑。
### 均值类指标
从均值类指标的样本量计算的逻辑上参看第6节课来看我们需要函数[power.t.test](https://www.rdocumentation.org/packages/stats/versions/3.6.2/topics/power.t.test)。下面这段代码L105-109是在server.R文件中的具体实施
```
number_t_test &lt;-
reactive({ceiling(power.t.test(delta=input$lift_t_test,
sd=input$sd_t_test,
sig.level=1-numsif_t_test(),
power=0.8)[[1]])
})
```
从这段代码我们会发现,和概率类指标相比,函数要求的输入参数有所变化,变成了:
- 标准差sd。
- 最小可检测差值delta这里是两组指标的绝对差值
- 显著水平sig.level。
- Power。
- 还有单双尾检验。
这是因为均值类指标的标准差(方差)并不能仅仅通过两组指标的值来计算,而是需要知道每个数据点来计算。
我们先看标准差的计算公式:<br>
<img src="https://static001.geekbang.org/resource/image/b5/17/b549a8a6fe9689bb364683b13408f817.png" alt=""><br>
所以标准差需要用户根据以上公式在数据中计算得出。
最小可检测差值delta是用户根据实际业务情况自定的显著水平一般为95%。
**Power**和**单双尾检验**这两项我们还沿用概率类指标的设定去设置默认值Power为80%的双尾检测。
均值类指标代码的其他部分和概率类指标均类似,这里就不再展开举例了,具体的内容,代码里也写得十分清楚了。
## 应用场景和使用案例
实践中使用样本量计算的应用场景主要分两类:
- 已知单位时间的流量,求测试时间。
- 已知测试时间,求单位时间的流量。
所以你会发现在App交互界面右下角区域的结果板块就有关于测试时间和测试流量的选项。
下面我来举一个例子来分别说明这两种情况。
假设我们现在做A/B测试的指标为下载率原始指标为5%最小可检测的相对提升为10%置信水平为95%一共有一个实验组和一个对照组通过咱们的样本量计算器求得的每组样本量为31234总样本量为62468。
###
**在单位时间测试可用流量固定的情况下,求测试时间**
这种场景是比较常见的。我们假设以周为单位每周可用的测试流量约为10000。输入参数后计算得出一共需要6到7周的时间才能达到充足的样本量
<img src="https://static001.geekbang.org/resource/image/20/e9/205d6a9b6e43cf3e90f44c22c03430e9.png" alt="">
### **在测试时间固定的情况下,求单位时间内的流量**
这种场景适用于时间紧急的情况比如一周之内要出结果一周有7天那么输入参数后计算得出我们每天的测试流量至少要有8924。
知道每天需要的流量后,我们就可以根据这个数字去调整我们的测试流量占总流量的比例了。
<img src="https://static001.geekbang.org/resource/image/27/0b/27327b6e389cfc2029ea13635d7ee20b.png" alt="">
最后我要说明一点,虽然我举的是一个概率类指标的例子,但这两个使用场景对于均值类指标是同样适用的。
### 使用案例
在使用案例这个版块,我会针对概率类指标和均值类指标各举一个例子,来说明具体情况下应该如何输入不同的参数。
先看概率类指标的案例。
<img src="https://static001.geekbang.org/resource/image/02/36/02544d86608ecf014bba6f89d0979d36.png" alt="">
再看均值类指标的案例。<br>
<img src="https://static001.geekbang.org/resource/image/fe/d7/fed41dc163edb25c95ebb996e4bfyyd7.png" alt="">
## 如何把Shiny App发布在网上
现在我们完成了server.R和ui.R在下图中点击右上角的“Run App”即可在本地打开我们的App。<br>
<img src="https://static001.geekbang.org/resource/image/c1/bf/c15db4c1cc380b153f5e14e7baa5b9bf.png" alt=""><br>
但是如果你想把App发布在网上还是得借助ShinyApps.io它是专门发布 Shiny App的平台你需要在上面注册一个免费账户具体过程呢也不难你可以查看这里的[教程](https://shiny.rstudio.com/articles/shinyapps.html)。
## 小结
那么到这里呢关于制作A/B测试样本量计算器的讲解就结束了相信你通过本节课的学习结合着我提供的代码和App已经能成功制作出自己的样本量计算器啦。
不过有一点也需要再说明一下。虽然样本量计算的逻辑是固定的但是对于用户交互前端的话在保证基本功能的前提下你可以根据自己的喜好来设计的这里我贴出来Shiny前端的[案例集](https://shiny.rstudio.com/gallery/)和[常用语句](https://shiny.rstudio.com/images/shiny-cheatsheet.pdf)供你参考。
## **思考题**
其实样本量计算可以在各种编程语言中实施这里我选用R和Shiny的原因是它们使用起来相对简单些。那如果让你用Python来实施的话对于概率类和均值类指标样本量的计算你会选择哪些函数呢
如果你在制作样本量计算器的过程中有遇到什么问题,或者有什么经验,欢迎在留言区和我分享,也欢迎你把课程分享给你的朋友、同事。