专栏名称: 张铁蕾
老程序猿,全栈攻城狮,CTO,与你一起讨论技术干货和个人成长。
目录
相关文章推荐
51好读  ›  专栏  ›  张铁蕾

科学精神与互联网A/B实验

张铁蕾  · 公众号  ·  · 2019-09-20 21:29

正文

我们先讲两个历史上真实发生过的小故事。

第一个故事是关于黄热病。

黄热病是一种严重的传染病,曾在1793年袭击美国费城。当时,费城有一位著名的人物,他叫本杰明·拉什[1]。拉什曾经签署过《独立宣言》,是美国的开国元勋之一。同时,他还是著名的教育家和出色的外科医生。在费城的黄热病爆发的时候,他坚信放血疗法可以治疗这种疾病。于是,他用手术刀或水蛭吸血的办法给病人放血。当拉什自己染上这种疾病的时候,他也采用同样的方法给自己治疗。

第二个故事是关于坏血病。

坏血病在历史上曾是严重威胁人类健康的一种疾病,尤其在远洋航行的水手中尤为严重。在18世纪,一位英国船长发现,在一些地中海国家的海军舰艇上服役的船员没有坏血病。他注意到,这些船员的食物配给中含有柑橘类(citrus)水果。于是,为了弄清真正的原因,这位船长将他的船员们随机分为两组:其中一组在日常饮食中加入酸橙(limes),而另外一组维持原来的食谱不变。结果通过对比发现,定期食用酸橙的一组船员,真的防止了坏血病的发生。后来,定期食用柑橘类水果就变成了英国水手必须遵循的一种规定。这种做法越来越普遍,以至于在后来的美国英语中产生了一个新的词汇——limeys[2],用来代指任何一个英国人。这个词翻译成中文称为「英国佬」。

现在让我们来比较一下这两个故事有什么不同。

在第一个故事中,本杰明·拉什坚信他的放血疗法可以治疗黄热病。实际上,他确实「治」好了一些病人。当然,也有一些病人死掉了。事情的解释就演变成这样:如果病人情况好转,那么就被作为放血疗法有效的证据;反之,如果病人死掉了,拉什就解释说是病情太严重,已经无药可救了。后来,有评论家指出,他的疗法甚至比疾病本身更加危险。

而在第二个故事中,船长将船员分成了两组,进行了 对照实验 (controlled experiment)。现代医学已经证实,这位船长通过对照实验得到的结论确实是有效的。坏血病的致病原因是由于缺乏维生素C,而柑橘类水果中含有大量的维生素C。

在这两个故事中,当事人都试图在寻找事物之间的一种 因果关系 (causal relationship)。本杰明·拉什相信放血疗法和治愈黄热病之间存在因果关系;而第二个故事中的船长则发现了食用酸橙和防止坏血病之间的因果关系。那为什么拉什没有找到真正的因果关系,而那位英国船长找到了?关键就在于对照实验。

进一步追问,为什么使用对照实验就能得到真正的因果关系?这本质上是一个哲学问题,涉及到「科学」之所以成为科学的本质原因。接下来,我们就先展开来聊一聊,什么是真正的因果关系以及这个问题所涉及到的科学本质;然后再回到现实,跟大家讨论一下在互联网的业务中关于如何进行对照实验的各种技术。

因果律的陷阱

每当我们得出一个因果性结论的时候,都应该倍加小心。比如,看到苹果落地,怎么就能得出万有引力是导致苹果落地的原因的?为什么不是其它原因导致的?想一想我们可以考虑的别的因素还有很多啊,比如天气啊,地理位置啊,苹果的品种啊,等等,它们为什么就不能是苹果落地的「原因」呢?为什么我们不能得出结论说:因为今天天气晴朗,所以苹果就落到地上了,而明天可能一下雨,苹果就自己飞到天上去了?为什么我们不能得出结论说:我们看到的这个苹果因为它生长在河北省,所以就落到地上了,而对于生长在湖南省的苹果,也许就未必了?

你肯定会说,这样想问题太荒谬了。没错,是很荒谬。但那是因为现在我们已经很清楚苹果落地的原因了,我们对科学给出的「万有引力」这个解释已经深信不疑了,所以才会认为这些想法很荒谬。试想一下,在人们发现「万有引力」之前,是不是考虑「天气」、「地理位置」这些现有的因素也许是更自然的想法呢?

上面苹果落地的例子表明,找到真正的因果关系,并不容易。在牛顿时代之前,人们对于苹果落地这一司空见惯的现象已经观察了成百上千年,也没能得出现象背后的真正原因到底是什么。而弄错了因果关系,就会得到很荒谬的结论。

实际上,这还不是最糟的。当我们在讨论苹果落地的「原因是什么」的时候,已经首先假定了苹果落地是「存在一个因」的。而在科学和哲学的发展史上,因果关系本身存在的合理性甚至都被怀疑过。苏格兰历史上有一位怀疑一切的哲学家,名叫休谟。他比较极端,认为世界上根本不存在因果律这种东西。还是以苹果落地为例,按照休谟的观点,就算你观察到苹果离开树枝后落到地上的这一事实发生了一万次,也不能说明第一万零一次苹果离开树枝就一定会落到地上。换句话说,他根本不相信苹果落到地上是存在某种「必然」的原因的,而只能看成是偶然事件,哪怕它发生了再多次也是一样。结论听起来仍然很荒谬。但哲学家都是聪明人,绝不是头脑混乱才胡言乱语(实际上休谟是个天才,人家12岁就上大学了)。休谟是沿着怀疑主义前后一贯的逻辑进行推论的。罗素就曾经评论说:“他把洛克和贝克莱的经验主义哲学发展到了它的逻辑终局,由于把这种哲学作得自相一致,使它成了难以相信的东西。”

《三体》小说中提到过一个「农场主假说」,跟休谟的这种观点类似。这个假说是这样描述的:

一个农场里有一群火鸡,农场主每天中午十一点来给它们喂食。火鸡中的一名科学家观察这个现象,一直观察了近一年都没有例外,于是它发现了自己宇宙中的伟大定律:“每天上午十一点,就有食物降临。”它在感恩节早晨向火鸡们公布了这个定律,但这天上午十一点食物没有降临,农场主进来把它们都捉去杀了。

这只可怜的火鸡认为自己发现了一个「因果律」:每天上午十一点(这是因),就有食物降临(这是果)。但最后事实证明,「上午十一点」和「食物降临」这两个事件之间并没有必然的因果关系,它们只是在过去一年内恰好同时发生(最后在感恩节这天发生了变化)。这个故事含有一丝神秘的意味,它暗示了,我们人类发现的一些「因果规律」,也许是某个更高等级的文明或者某个神秘力量随意设置的。

我们很快就发现了,按照这样的方式思考问题,完全不承认这个世界上有因果律存在,那么科学就没法玩了。科学研究要进行下去,就必须承认因果律是普遍存在的,因为科学定律基本都是对因果规律的总结。我们之所以应该承认和尊重科学,是因为科学「有用」,它在过去几个世纪内深入地影响了人类的生活。我们必须转向实用主义的观点,否则就会陷入虚无的诡辩。总而言之,我们应当及时放弃休谟的极端观点,回过头来相信因果规律的存在。

关键的一点是,科学必须有一套行之有效的方法和标准,来验证科学定律的正确性,来检验它是否真正反映了事物的因果关系。实际上,科学定律都不是「空中楼阁」,都是被实践验证过的理论。牛顿的三大定律,被无数的实验和观察验证过;爱因斯坦的相对论,也被很多天文观测所验证。这种「科学的」验证方法就是前面提过的「对照实验」。

什么是对照实验呢?通俗来说,对照实验就是将实验的物体或人群随机分成两个组,一个实验组 (treatment group),一个对照组 (control group)。对实验组人为地修改某个控制变量(也就是实施实验),而对照组只是用来做对比(维持它原来的状态)。以文章开头提到的坏血病故事为例,英国船长就是实施了一组对照实验。他将船员们随机分为两组:在日常饮食中加入酸橙的一组是实验组,食谱维持不变的一组是对照组。最终实验结果是:实验组的船员发生坏血病的比率减少了。这个结果的「因」,也就是在实验组和对照组之间有差异的那个因素——酸橙。至此,船长得到了结论:酸橙可防止坏血病。

我们再来看一个对照实验的例子。

《哲学家们都干了些什么》这本书中描写了一个案例。有人调查了大学生的体重和交友数据之后发现,越是胖的人,身边的朋友就越多。然后就得出了一个结论:身体胖是朋友多的原因,也就是说,身体越胖,越有魅力。这个调查其实也可以设想成一组对照实验:我们找两组大学生,一组体重超标(实验组),一组体重正常(对照组)。然后我们对比两个组的交友数据,发现实验组的学生朋友比较多。于是,我们这样分析,「朋友多」是一个结果,它的「因」就是在实验组和对照组之间有差异的那个因素——身体胖。

仔细的读者一定已经发现了这里的一个陷阱。在做对照实验的时候,一定要保证实验组和对照组除了实施实验所必需的那个控制变量之外,其它所有特征均相同。刚才这个案例的陷阱就在于,实验组和对照组的选择是有问题的,两个组除了体重不同之外,还可能有很多其它不同的特征。这些其它的不同特征,也都有可能是造成两组朋友多寡的原因。这个案例的真正答案可能是这样的,身体胖的人喜欢参加饭局,而喜欢参加饭局是因为他们社交范围比较广,社交范围比较广的表现就是朋友比较多。这是一个典型的「第三变量」问题。「身体胖」和「朋友多」都和第三变量「喜欢参加饭局」有关,所以「身体胖」和「朋友多」之间并不存在直接的因果关系,它们之间只是具有「相关性」。

统计学上有一个经典的结论:相关性不代表因果性。我们在做数据分析时,很容易发现两个变量之间的相关性,比如一个变量随着另一个变量的增大而增大,或者一个变量随着另一个变量的增大而减小,但具有相关性的两个变量之间是否具有因果关系,决不能草率地下结论。

我们再分析一下为什么会陷入把相关性当成因果性的陷阱。刚才提到,在分析大学生体重和交友数据的例子中,实验组和对照组的选择是有问题的,我们把这个问题称为「选择性偏差」。我们对于实验组(也就是胖子组)的选择,掺杂了太多人为的因素,导致实验组和对照组之间差异巨大,根本不存在可比性。也许,胖子组里面有钱的学生更多,或者胖子组里面女生比男生更多(或者反过来),照这样分析,我们也许会认为「有钱金多」或「性别」都是「朋友多」的原因呢。那为什么文章开头坏血病的对照实验是成功的呢?那是因为船长对于船员进行分组时有一个很关键的细节:是「随机」分组的。首先,两个组的船员都来自同一艘船,他们平常的生活条件大体相同。如果不是来自同一艘船,就会引入额外的干扰因素,比如船员的航线不同,出身不同,整体健康状况可能也不同,最终导致实验失败。其次,两个组是随机分派的,这样就避免了「选择性偏差」。

说了这么多,无非就是为了告诫我们自己,当我们设计实验来探索或验证因果律的时候,需要加倍小心。不管是科学实验本身就经常遭遇的相关性陷阱和选择性偏差,还是来自哲学意义上的对于因果律根本性的挑战,都说明对于事物之间因果关系的分析是一个非常棘手的课题。而科学正是由于它的这种「谨慎」,才让它在近现代历史的发展中大放异彩。

互联网业务中的A/B实验

互联网产品通常是逐渐迭代、慢慢进化的,而通常情况下选择都是比较多的。那么自然就产生了一个问题,产品在每一步到底应该选择向着什么方向迭代,才是最有利于业务发展的?在互联网业务的开发和运营当中,我们经常需要面对这样的问题进行决策。比如,对产品首页进行改版,可能有不同的方案,那么到底应该选择哪个方案?再比如,对推荐算法进行新版本升级,能不能保证提高数据指标?又比如,在商业化的过程中,想在产品中投放广告,怎样做能够收益最大而对用户体验的影响最小?

这些事情本质上也是在寻找事物之间的因果关系。我们发布了某个新的产品feature,或者对产品进行了优化,这是「因」;然后我们观察到了数据指标的变化,比如用户留存率或活跃度变高了,这是「果」。根据上一节的讨论,我们已经知道了,分析因果关系需要加倍小心,否则很容易陷入思维的陷阱。通常产品持续在迭代,当我们对产品进行某个更改之后,其它的变化也在发生(比如另一个团队也对产品进行了修改),周围的环境也在发生变化(比如节假日和社会热点事件的影响),我们就很难分析出最后数据指标变化的原因到底是来源于哪些变化因素。

在一个缺乏完善的对照实验机制的环境中,人们通常会对照不同的时间段进行数据分析。人们经常会这样宣称,你看,之前的某段时间内,用户留存率是这样的,但从某天开始,我们做了一个实验(发布了一个产品改动,或者改变了某个运营策略),结果留存率提升了1个百分点。这样的分析在很多情况下都是比较危险的。这相当于在时间维度上先后选取了「对照组」和「实验组」,它们未必就有可比性。首先,当产品每天都在迭代更新,甚至多个改动同时并存的时候,你很难将留存率的提升归因于某个具体的产品改变。其次,就算你在做实验的时候确定没有别的干扰因素了,但某些隐藏的因素的变化,你根本没办法识别出来,比如群体的统计特征也很可能在随着时间变化。这样得到的结论,未必反映了真实的因果关系,也许换一个时间、换一个环境就不适用了。这时候我们能做的,也只有对数据进行各种各样的解释,如果解释不通,就叠加更多的补充因素和假定条件来解释。

与科学实验类似,其实我们在互联网业务中也可以采取严格的对照实验。在程序开发的领域,我们一般称之为A/B实验。实际上,在不同的场合,它至少有半打以上不同的名字。下面的列表列出了这些名字:

  • Controlled experiments (对照实验)

  • Randomized experiments (随机实验)

  • A/B tests (A/B测试,A/B实验)

  • Split tests

  • Control/Treatment tests

  • MultiVariable Tests (MVT)

  • Parallel flights

关于互联网业务中的A/B实验,有两篇论文做过详尽的论述:

  • 《Overlapping Experiment Infrastructure: More, Better, Faster Experimentation》,作者是谷歌的Diane Tang, Ashish Agarwal, Deirdre O’Brien, Mike Meyer。

  • 《Controlled experiments on the web: survey and practical guide》,作者是微软的Ron Kohavi, Roger Longbotham, Dan Sommerfield, Randal M. Henne。

现在我们就逐步展开来看看这两篇论文给出的A/B实验方案是怎样的。

假设,最开始整个系统里就只有两个实验(1个实验组和1个对照组)。注意,我们统一下词汇,不管是实验组还是对照组,我们都称为1个实验。虽然对照组只是用来做对比,分配到对照组的用户看不到任何产品或运营策略改动,但我们也把它称为1个「实验」。

我们随机分出了10%的流量作为对照组,又随机分出了10%的流量作为实验组。这时剩下了80%的流量是空闲的,没有进行任何实验。从用户的角度来看,在实验组内的这10%的用户,能够看到正在进行的实验(产品或运营策略改动),而在对照组和剩下的空闲流量中的用户(总共90%),是看不到产品或运营策略改动的。如下图(点击看大图):

一般情况下,我们需要保持用户体验的前后一致。也就是说,一旦一个用户被分到了实验组,那么他发起的后续请求应该都落到实验组的流量里面。我们需要一种会话保持(session sticky)的机制,而这有很多种可能不同的方案。如果用户是有登录状态的,我们可以拿用户ID来取模,如下:

mod = 用户ID % 1000

而如果用户是没有登录态的,就像谷歌的搜索服务一样,那么可以拿cookie变换成一个数值再取模,如下:

mod = f(cookie) % 1000

当然还有很多计算 mod 的方案(关键是达到随机的效果)。但不管是上面哪一种取模的方式,我们只需要将 mod [0, 99] 之间的请求分配到实验组,将 mod [100, 199] 之间的请求分配到对照组,就分别获得了10%的随机流量。







请到「今天看啥」查看全文


推荐文章
风青杨  ·  懂得富养自己,到底有多重要?
8 年前
理想聚焦  ·  喜欢喝酒的,务必进来看看
8 年前
移动互联网资讯  ·  360董事长周鸿祎:两种人加我微信我会通过
7 年前