ronghuaiyang · 2020年06月01日

A/B测试的一些工程问题

作者:Dario Gieselaar

编译:ronghuaiyang

首发:AI公园公众号

导读

文章给出了A/B测试中的一些理念上和工程上的思考和经验的总结,有些内容翻译起来有些拗口,见谅。

在过去的两年里,在我工作的环境中,A/B测试一直是一个主要的rollout 机制 —— 这对我来说是一种全新的体验。最近,Nicolas Gallagher发了37个单词,相当准确地总结了我至少一半的A/B测试经验,并促使我写了一篇关于它的文章。

image.png

A/B测试的前景

===========

A/B测试,或多变量测试,是一种机制,用来比较相同特性或页面的两个(或多个)版本,并比较这些版本的统计数据,以查看哪个版本执行得更好。理想情况下,这将导致更多基于(数据)的决策的制定,并实现快速反馈循环和持续改进。经典的例子(也是我第一次听说A/B测试):[谷歌曾经测试过40种深浅不同的蓝色,以了解哪种颜色的用户换的最多](https://iterativepath.wordpre... of-blue-ab-testing/)。

在高层次上,它是这样工作的(或者,它“应该”这样工作):

  • 有一个关于用户行为的假设(通常基于心理学理论,如害怕错过)。为了测试这个假设,我们创建了一个“实验”,其中我们测试了当前的实现(通常称为“控制”),以及新实现的一个或多个变体。在测试开始之前,要决定将对实验的哪些指标进行评估。
  • 用户访问网站或应用程序,特别是你正在测试的功能。
  • 然后,它们被分配到“桶”中,这意味着它们被分配到你正在测试的实验的一个变体中。用户落在哪个桶中,决定他们可以看到和使用哪个版本的实验。在实验过程中,用户一直留在这个桶里。
  • 记录用户行为事件,并存储以进行统计分析。通常情况下,实验至少持续一周或更长时间。一旦完成,就会对结果进行分析,并且在大多数情况下,会向所有用户推出性能最佳的实验变体。

设置一个实验

现在,假设你想要实现一个A/B测试。你需要什么?以下是一些你可以在任何解决方案中寻找的关键点:

  • 分桶:用户需要分桶。本质上,这是一个Math.random() > 0.5 ,通常情况下,进行50/50的分割(或者在不同的变量中平分),但是如果你在运行一个风险更大的实验,你可能会做类似于80/10/10的分割。你还可以使用目标受众或环境来确定用户是否有资格参加实验。
  • 远程配置:使用一个与代码分开的配置来闭和打开实验。在大多数情况下,部署应用程序的新版本是一个繁琐的过程,并且管理实验的人通常不是工程师自己。理想情况下,产品经理/市场营销人员可以通过一个单独的过程来管理配置,这个过程比发布新版本对他们来说更友好。至少,你希望去管理启用了哪些实验(因为,你知道,代码会出问题),以及开始和结束日期或目标等内容。
  • 跟踪:你还需要在我们的实验中获得有关用户行为的数据,以便评估哪种变体执行得更好。我们的用户在页面上花费了多少时间?他们会转换到漏斗的下一个步骤吗?他们在购物车里放了多少东西?你需要记录这些事件,并将它保存下来…
  • 分析:一旦你有了这些数据,当实验结束了,你需要分析结果。有一些基本的数字:有多少用户来自变式B或变式C?他们在你选择的度量标准上表现如何?检验的统计意义是什么?也许你想细分设备类型,或受众的数据。你可以从数据库导入统计数据并使用基本的excel进行分析,或者还可以使用诸如谷歌Analytics之类的工具,该工具允许你进行序列的查询,这在分析用户行为时非常有用。
  • 可视化编辑器:像Optimizely这样的工具提供了一个可视化编辑器,允许你通过点击的方式来设计一个新的实验。如果你没有与工程团队直接接触的机会,这是非常有用的(如果你_有_这样的机会,可能会有更好的选择)。

根据我有限的知识,至少有五种方法可以实现A/B测试:

  • Canary发布:如果你想测试你网站的一个新版本,你可以为你想测试的每个版本部署一个新版本(可能是一个功能分支),然后将你的一部分用户路由到那个新的部署上。为了能够使用它,你必须有一个可以进行管理的,良好的基础设施和发布管道,特别是当你希望并行运行多个测试,并且需要许多不同的部署和随之而来的路由复杂性时。你可能也需要相当大的流量。不过,好处很明显。例如,任何失败的实验都不会引入技术债务(代码永远不会落到主服务器上,部署之后就被删除)。另一个好处是,强制用户一次只能在一个实验中,但是多重实验既带来了技术挑战,也带来了实验之间相互影响的不确定性。
  • 分割URLs:历史上谷歌有个建议来防止SEO问题,你可以使用url将用户路由到不同的实验上。例如:/amazing-feature/test-123/b。这种方法的好处是,当你尝试不同的设计时,你不会对域上给定URL的任何SEO值产生负面影响。
  • 服务侧:当请求页面时,用户在服务器上被分到一个桶里。然后设置一个cookie以确保用户被“粘”在这个桶中,并使用它来呈现用户正在进行的任何实验的界面。你几乎可以做任何你想做的事情:A/B测试、多元测试、特性切换、并行实验,这些都取决于你。对于用户来说,这是最好的选择之一,因为性能影响可以忽略不计。然而,由于你使用cookie, CDN的好处是有限的。cookie会在请求中引入变化(特别是当用户可以输入多个实验时),这会导致缓存遗漏,使你无法获得CDN的保护。
  • 客户侧:如果你没有访问服务器的权限,或者你希望获得最大的灵活性,那么客户端A/B测试也是一个选择。当你没有开发人员,并且使用外部工具运行实验时,这种选择通常是有意义的。然而,就性能而言,这通常是最糟糕的选择。
  • On the edge:如果你的网站前面有一个CDN,你可以使用edge workers来运行实验。它的要点是你的服务器显示所有界面的变化,你的CDN缓存此响应,然后当用户加载你的网站时,在edge workers删除不适用的HTML的用户请求之后,缓存的响应来提供服务。如果你关心性能,这是一个非常有前途的方法,因为你可以在不影响浏览器性能的情况下获得CDN的好处。

A/B测试的现实状况

事实证明,A/B测试是困难的。它可能是非常有价值的,我认为你应该把它作为你的底线来衡量。然而,这并不是什么灵丹妙药,你必须根据你的公司类型(或你想成为什么样的公司)来调整你的方法。以下是我在一家每天有大约5万到10万用户的中等规模公司学到的东西:

尽可能的做孤立实验

在我现在的公司,我们正在并行地实现实验,并且实现总是在它被验证之后立即投入生产,不管它是否会被使用(基本上是一个特性切换)。这主要是由于我们的技术选择:我们有一个服务器端呈现的单页应用程序,这使得canary策略难以使用(因为你永远不会回到路由器或负载平衡器)。除此之外,由于缺乏流量,我们无法负担每个用户在平台上进行一次实验的奢侈费用。实际上,这意味着实验有副作用。这里有两个问题在起作用。

首先,同时执行的实验使得任何端到端测试覆盖的合理预期都成为不可能:即使像10个A/B测试这样的少量测试也会创建100个应用程序变体。为了测试所有这些不同的变化,我们的测试将花费250小时而不是15分钟。因此,我们在测试期间禁用所有实验。这意味着任何实验都可能 —— 并最终会 —— 破坏关键(和非关键)用户功能。此外,除了我前面提到的缓存问题之外,它还使从错误报告系统可靠地重现bug变得更加困难。

其次,在用户的旅程中运行多个实验将导致测试结果的不确定性。假设你在产品页面上有一个实验,在搜索页面上有一个实验。如果搜索实验对发送到产品页面的流量类型有很大的影响,那么产品实验的结果就会有偏差。

我能想到的最好的隔离策略是canary发布和特性分支。它是这样工作的:当你开始一个实验时,你创建一个分支,它将包含一个变体的变化。你打开一个pull请求,然后部署一个带有该更改的测试环境。一旦检查通过,就将其部署到生产环境中,并更新路由器配置,将一定数量的流量发送到你想要测试的变体上。你必须查看预期的使用情况、通常的流量和测试所需的持续时间,以确定什么流量划分是有意义的。假设你估计20%的流量一个星期就足够了,它将共同排除80%的流量测试,并把剩下的20%平均分配在运行当前版本的网站实例上和运行实验版本的实例上。

image.png

A/B测试的结构图

我可以想象,安排这样的实验需要大量的工程工作,尤其是当你想要自动启动实验,或者当你想要使用更高级的目标时。你必须有足够的流量,在这一点上,你会看到把你的网站分成更小的可部署单元的好处。

如果你不能正确地分离实验,你可以试着接受并不是生活中的所有问题都是或应该是可以解决的。如果你是一个控制狂(像我一样),你可能会考虑互斥实验 —— 这意味着实验X中的用户不能同时出现在实验Y中。这将有助于消除行为的副作用。如果你需要更多的测试信心,你可以选择进行更低级别的测试,比如单元测试或组件测试。或者,你可以处理250个小时以上的pipelines,只要你愿意。

坚持高标准

围绕A/B测试的一个经常重复的口头禅是“这只是一个测试,我们稍后会修正它”。这里的想法是你建立一个MVP并衡量这个投入,如果有的话,你建立一个更好的设计,最终得到一个更好的最终版本。在实践中,我没有看到这方面的工作,大概有两个原因:第一个原因是,最初的处理问题的动机在开发完成后就没了。这适用于所有方面:工程、设计和产品。它已经被证明是一种提升,花时间重新设计或重构会感觉没有必要。而那些“感觉”不需要的东西 —— 即使它们是需要的 —— 也不会发生,尤其是在产品工程上。第二个原因是,重新实施一项实验,甚至重新设计它,都可能对之前假定的提升产生影响。要绝对确定,你必须运行另一个实验,现在已经有了可用于生产的实现,没人有时间这么做。问题是:需要为实验的实现走捷径的环境类型也不太可能分配时间来重构或重新运行一个成功的实验。

这样会发生什么呢?你会积累技术债。通常没有明确的范围,也没有定量的描述。债务很难用数字来描述,也很难有理由去解决。这些债务会慢慢爬向你,直到最后,每个人都放弃了,然后重头开始做。

不一样的标准不仅是不明智的,而且令人困惑。让工程师们在一个标准上保持一致已经够难了,但是两个标准呢?这是不可能的。做好准备,在代码评审中进行无休止的反复。

目标的影响

一个平台,估计大约有1 / 7的实验是失败的,在CRO的世界里,最常见的说法就是失败没什么大不了的,只要你能从中吸取教训。这里的假设是,知道什么没用,和知道什么有用一样有价值。

然而,这并不意味着你应该开始尝试一些仅仅是猜测的事情,或者可以通过常识、经验或定性研究得出的事情。每一个都比浪费掉一个一年10万设计师或85%的开发生产力要便宜 —— 尤其是如果你考虑到员工的流失率,如果你的员工觉得他们的工作毫无意义,这将不可避免地发生。

你如何保持高昂的士气,让员工觉得他们是有价值的?当然,相信并强调学习是有帮助的。但对我来说,做一次大的尝试是很刺激的。他们允许我充分利用我的经验和技能来做出改变。现在,什么是大的尝试取决于你是哪种类型的公司,但我不认为重定位或重复实验属于这一类。将标准定得太低的一个很好的迹象是会出现许多非结论性的实验(或需要长时间运行才能有意义的实验)。如果是这种情况,你就做了太多的小尝试。

现在,回到这个推特中...

老实说,我使用Nicolas的推特主要是为了对一个相当无聊的话题进行一个漂亮的介绍,但它包含了一个强有力的事实:数据,或数据的需求,往往会导致惰性。数据并不是所有的答案。它不会取代愿景,也不是战略。

定义一个大方向,然后使用A/B测试来验证你在实现该方向上的进展。而不是反过来。

—END—

英文原文:https://levelup.gitconnected....

推荐阅读


关注图像处理,自然语言处理,机器学习等人工智能领域,请点击关注AI公园专栏
欢迎关注微信公众号
AI公园 公众号二维码.jfif
推荐阅读
关注数
8257
内容数
210
关注图像处理,NLP,机器学习等人工智能领域
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息