mirror of
https://github.com/oldratlee/translations.git
synced 2026-04-13 17:51:58 +08:00
调整标点、用词、格式
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
原文链接: [Overlapping Experiment Infrastructure: More, Better, Faster Experimentation](http://research.google.com/pubs/pub36500.html "Overlapping Experiment Infrastructure: More, Better, Faster Experimentation") - _Diane Tang, Ashish Agarwal, Deirdre O’Brien, Mike Meyer_
|
||||
基于[火光摇曳Flickering](http://www.flickering.cn/)上 _lexqu(屈伟)_ 的译文稿`v1.2.0`: [Google 重叠实验框架:更多,更好,更快地实验](http://www.flickering.cn/uncategorized/2015/01/%E9%87%8D%E5%8F%A0%E5%AE%9E%E9%AA%8C%E5%B9%B3%E5%8F%B0%EF%BC%9A%E6%9B%B4%E5%A4%9A%EF%BC%8C%E6%9B%B4%E5%A5%BD%EF%BC%8C%E6%9B%B4%E5%BF%AB%E5%9C%B0%E5%AE%9E%E9%AA%8C/)
|
||||
|
||||
# 重叠实验设施:更多,更好,更快地实验
|
||||
# 重叠实验设施:更多、更好、更快地实验
|
||||
|
||||
<img src="expt0.png" align="right" >
|
||||
|
||||
@@ -40,10 +40,10 @@
|
||||
|
||||
对`UI`的修改通常会使用实验来评价用户反应,但需要注意的是算法的修改同样也需要实验。例如:假设一些团队想测试一个新的机器学习算法来预测广告`CTR`,或是测试对现有算法的调整(比如,修改学习速度或是收敛速度)。虽然线下评估可以进行一些分析后,可以缩小参数的最佳取值区间(不是最佳取值),但最终这些参数还是需要在线上流量进行评估,分析这些参数在真实的流量上的效果(因为修改可能会影响用户的行为,并改变流量本身的模式,这是不可能在线下环境评估的)。所以,评价这些机器学习算法是需要通过线上实验的方式进行的。
|
||||
|
||||
设计我们实验设施的目标是:_更多_,_更好_,_更快_。
|
||||
设计我们实验设施的目标是:_更多_、_更好_、_更快_。
|
||||
|
||||
* **更多**:我们需要能同时进行多个实验的可扩展性。但是我们也需要灵活性:不同的实验需要不同的配置和不同的流量来衡量实验的统计意义上的效果显著性。有些实验只需要修改流量的一个子集,比如只是日语的流量,并需要取一个合理的流量规模。其它的实验有可能需要修改所有的流量,并对指标造成很大影响,这种才可以在小流量上进行测试。
|
||||
* **更好**:不合理的实验是不应该让它在线上流量进行的。合理的但是很差的实验(比如,有`bug`的实验或是无意中产生的很差的实验结果)都应该能很快的被捕获并且停止它的进行。标准化的标价指标可以让所有的实验进行公平的比较:比如在计算`CTR`指标的时间,两个实验应该用相同的过滤器去掉爬虫流量。
|
||||
* **更好**:不合理的实验是不应该让它在线上流量进行的。合理的但是很差的实验(比如,有`Bug`的实验或是无意中产生的很差的实验结果)都应该能很快的被捕获并且停止它的进行。标准化的标价指标可以让所有的实验进行公平的比较:比如在计算`CTR`指标的时间,两个实验应该用相同的过滤器去掉爬虫流量。
|
||||
* **更快**:能够很容易并且很快地建立一个实验。容易到非工程师不需要写代码就可以创建一个实验。评价指标应该很快的被统计出来,以便分析。简单的迭代可以很快速地进行。理想状态是,实验系统不仅支持实验,并且可以控制放量,比如,以一种系统的和容易理解的方式对实验进行放量。
|
||||
|
||||
为了达到这些设计的目标,我们不仅需要实验架构来进行更多的实验,并且需要一些工具和指导过程来支持更多和更快的实验。
|
||||
@@ -63,7 +63,7 @@
|
||||

|
||||
**图1**:一个请求经过多个模块的例子,信息(和时间)都是从左流向右
|
||||
|
||||
每个服务都有二进制推送和数据推送。二进制推送是指发布新的程序(`bug`修复、性能提升、新特性,等等),它一定时期进行一次(比如每周)。数据推送更频繁(比如,按需或是每几小时推送一次),并且这还涉及了推送更新的数据到相应的程序。数据推送中还包含了默认参数配置,参数是用来配置程序如何运行,比如,控制结果如何展示的服务也许有一个参数是决定顶部广告块的背景色。再比如,预测`CTR`的服务可能有参数是控制学习速度和收敛速度的。程序可能有几百个参数。新的特性可能会添加一个或多个参数:最简单的场景是,一个参数可以控制打开或关闭新特性,在更复杂的场景中,也许有多个参数决定新特性如果展示,有数值阈值决定新的特性是否被展示,等等。将程序和数据分离,意味着如果我们可以找到合适的分离方式,我们就可以同时得到快速影响线上服务的通路,和慢速影响线上服务的通路(程序是慢的通路,改变参数值是快速的通路)。
|
||||
每个服务都有二进制推送和数据推送。二进制推送是指发布新的程序(`Bug`修复、性能提升、新特性,等等),它一定时期进行一次(比如每周)。数据推送更频繁(比如,按需或是每几小时推送一次),并且这还涉及了推送更新的数据到相应的程序。数据推送中还包含了默认参数配置,参数是用来配置程序如何运行,比如,控制结果如何展示的服务也许有一个参数是决定顶部广告块的背景色。再比如,预测`CTR`的服务可能有参数是控制学习速度和收敛速度的。程序可能有几百个参数。新的特性可能会添加一个或多个参数:最简单的场景是,一个参数可以控制打开或关闭新特性,在更复杂的场景中,也许有多个参数决定新特性如果展示,有数值阈值决定新的特性是否被展示,等等。将程序和数据分离,意味着如果我们可以找到合适的分离方式,我们就可以同时得到快速影响线上服务的通路,和慢速影响线上服务的通路(程序是慢的通路,改变参数值是快速的通路)。
|
||||
|
||||
一个`Web`搜索中的**实验**是指将一部分请求流量转向一个特定的处理路径,这个处理路径会改变向用户展示的内容。一个**对照实验**将一部分请求流量转向一个处理路径,但它并不改变向用户展示的内容。我们用数据推送来决定实验的配置。在数据推送中,有一个文件决定程序的默认参数配置。另一个文件决定实验所需要改变的参数的值,实验只用指定实验所要改变的参数,对于其它参数,都采用默认值。比如,在一个简单实验中,它只改变顶部广告的背景色这一个参数,它可以改变黄色(默认值)到粉色(实验值)。
|
||||
|
||||
@@ -118,7 +118,7 @@
|
||||
|
||||
支持多种流量分配类型的主要目的一方面是为了保持处理的一致性,另外也希望可以覆盖到所有可能的情况,比如因时间变化而表征出来的不同特征。基于这些原因,我们以特定的顺序对不同的流量分配类型进行分流:用户`id`,`cookie`,`cookie`日期,随机。一旦这个请求被某高优先级分配方式抽中后,其它低优先级的分配方式将忽略这个请求(图3),虽然这个顺序最大化地了一致性,但它也有一个缺点,比如,在同一层中1%的`cookie`取模流量会比1%的随机流量大,在极端情况下,我们会遇到流量饥饿问题。在实践中,一层之中一般只应有一种分流类型,实验和对比实验必须使用相同的分流类型,最主要的影响是不同的分流类型实验需要不同的样本量(见5.2.1节)。
|
||||
|
||||
在通过流量分配类型选择一部分流量后,**分流条件**(`condition`)通过仅分配特定条件的流量给实验或域,以达到更高效利用流量的目的。比如,一个实验仅仅改变来自日语的查询,那么实验配置中只抽取日语的流量。我们可以基于地区,语言,浏览器等信息设置流量抽样条件。有了分流条件,一个只使用『日语』流量的实验,和一个只使用英语流量的实验,可以使用相同的`cookie`取模。另一个使用分流条件的场景是灰度测试新代码(代码是通过二进制推送发布的),比如,在一股小流量上测试新代码,以保证新代码没有`bug`,并与预测一致,然后才能放到大流量环境中(灰度环境中,通过错误日志和实验监控方式检查`bug`)。为了支持这种使用场景,我们提供了以机器或数据中心为分流条件的分配方式,它进一步限制了一个实验的流量。虽然灰度实验无法代替严格的测试,但它们是一个有用的补充,因为它既限制了潜在的错误,并且它让新的代码在真实环境中运行,从而可以遇到各种在测试环境中很难构造的真实请求。
|
||||
在通过流量分配类型选择一部分流量后,**分流条件**(`condition`)通过仅分配特定条件的流量给实验或域,以达到更高效利用流量的目的。比如,一个实验仅仅改变来自日语的查询,那么实验配置中只抽取日语的流量。我们可以基于地区,语言,浏览器等信息设置流量抽样条件。有了分流条件,一个只使用『日语』流量的实验,和一个只使用英语流量的实验,可以使用相同的`cookie`取模。另一个使用分流条件的场景是灰度测试新代码(代码是通过二进制推送发布的),比如,在一股小流量上测试新代码,以保证新代码没有`Bug`,并与预测一致,然后才能放到大流量环境中(灰度环境中,通过错误日志和实验监控方式检查`Bug`)。为了支持这种使用场景,我们提供了以机器或数据中心为分流条件的分配方式,它进一步限制了一个实验的流量。虽然灰度实验无法代替严格的测试,但它们是一个有用的补充,因为它既限制了潜在的错误,并且它让新的代码在真实环境中运行,从而可以遇到各种在测试环境中很难构造的真实请求。
|
||||
|
||||

|
||||
**图3**:决定请求进入域、层、实验的逻辑
|
||||
@@ -146,7 +146,7 @@
|
||||
|
||||
## 5.2 实验设计与样本量
|
||||
|
||||
相比基本的对实验配置的基本检查外(比如,每个实验都必须有一个对照实验,它与实验使用相同的分流条件),实验设计(experiment design)和样本量(`sizing`)是更高级的话题。
|
||||
相比基本的对实验配置的基本检查外(比如,每个实验都必须有一个对照实验,它与实验使用相同的分流条件),实验设计(`experiment design`)和样本量(`sizing`)是更高级的话题。
|
||||
|
||||
### 5.2.1 样本量
|
||||
|
||||
@@ -166,7 +166,7 @@ _Kohavi_ 假设实验与对照实验有相同的大小,比如 <img src="http:/
|
||||
|
||||
我们的重叠架构的其一优点是我们可以在每一层创建一个大的比照实验,这样它可以被多个实验共享,如果共享的对照实验规模比实验大的多( <img src="http://chart.googleapis.com/chart?cht=tx&chl=1%2F%5Ctext%7Bqueries%7D_%7B%5Ctext%7Bcontrol%7D%7D%2B1%2F%5Ctext%7Bqueries%7D_%7B%5Ctext%7Bexperiment%7D%7D%20%5Capprox%201%2F%5Ctext%7Bqueries%7D_%7B%5Ctext%7Bexperiment%7D%7D%0A" style="border:none;" alt="1/\text{queries}_{\text{control}}+1/\text{queries}_{\text{experiment}} \approx 1/\text{queries}_{\text{experiment}}" /> ),那么我们可以用 <img src="http://chart.googleapis.com/chart?cht=tx&chl=%5Ctext%7Bqueries%7D_%7B%5Ctext%7Bexperiment%7D%7D%3DN%0A" style="border:none;" alt="\text{queries}_{\text{experiment}}=N" /> 而不是 <img src="http://chart.googleapis.com/chart?cht=tx&chl=2N%0A" style="border:none;" alt="2N" /> ,这样虽然样本量变小为 <img src="http://chart.googleapis.com/chart?cht=tx&chl=%5Ctext%7Bqueries%7D_%7B%5Ctext%7Bexperiment%7D%7D%3DN%20%5Cge%2010.5(s%2F%5Ctheta)%5E2" style="border:none;" alt="\text{queries}_{\text{experiment}}=N \ge 10.5(s/\theta)^2" /> ,却有着90%的统计功效( <img src="http://chart.googleapis.com/chart?cht=tx&chl=1-%5Cbeta" style="border:none;" alt="1-\beta" /> )。
|
||||
|
||||
在确定实验规模的过程中,更重要的问题是如何估计标准误差 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s" style="border:none;" alt="s" /> ,特别是当我们使用很多比率指标 <img src="http://chart.googleapis.com/chart?cht=tx&chl=y%2Fz" style="border:none;" alt="y/z" /> 时(比如,覆盖率,有多少查询是返回广告的(有广告返回的查询/全部查询量))。问题产生于是实验的单元与分析的单元不一致时,比如,对于覆盖率,分析的单元是一个查询,但对于`cookie`取模的实验而言,实验的单元是一个`cookie`(一系列查询),并且我们无法假设来来自同一用户或`cookie`的请求之间是相互独立的,我们的方法是计算 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> ,即每个实验的标准误差,然后以 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> 来表示 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s" style="border:none;" alt="s" /> ,在上例中, <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> 是每个`cookie`取模的标准误差,且 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s%3Ds'%5Csqrt%7B%5Ctext%7Bavg%20queries%20per%20cookie%20mod%7D%7D" style="border:none;" alt="s=s'\sqrt{\text{avg queries per cookie mod}}" /> 。对于比率指标,我们用delta方法计算 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> [11]。
|
||||
在确定实验规模的过程中,更重要的问题是如何估计标准误差 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s" style="border:none;" alt="s" /> ,特别是当我们使用很多比率指标 <img src="http://chart.googleapis.com/chart?cht=tx&chl=y%2Fz" style="border:none;" alt="y/z" /> 时(比如,覆盖率,有多少查询是返回广告的(有广告返回的查询/全部查询量))。问题产生于是实验的单元与分析的单元不一致时,比如,对于覆盖率,分析的单元是一个查询,但对于`cookie`取模的实验而言,实验的单元是一个`cookie`(一系列查询),并且我们无法假设来来自同一用户或`cookie`的请求之间是相互独立的,我们的方法是计算 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> ,即每个实验的标准误差,然后以 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> 来表示 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s" style="border:none;" alt="s" /> ,在上例中, <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> 是每个`cookie`取模的标准误差,且 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s%3Ds'%5Csqrt%7B%5Ctext%7Bavg%20queries%20per%20cookie%20mod%7D%7D" style="border:none;" alt="s=s'\sqrt{\text{avg queries per cookie mod}}" /> 。对于比率指标,我们用`delta`方法计算 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> [11]。
|
||||
|
||||
图4是在不同实验中,包括`cookie`取模和随机流量实验,对于覆盖率指标与标准误差呈 <img src="http://chart.googleapis.com/chart?cht=tx&chl=1%2F%5Csqrt%7BN%7D" style="border:none;" alt="1/\sqrt{N}" /> 的关系,图中的斜线即是 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s" style="border:none;" alt="s" /> ,坐标轴上的值出于保密的原因隐去了,但可以看出`cookie`取模的斜线比查询的斜线陡峭,比如在相同的准确度下衡量相同的覆盖率的变化,一个`cookie`取模的实验需要比随机流量实验大的规模。
|
||||
|
||||
@@ -175,11 +175,11 @@ _Kohavi_ 假设实验与对照实验有相同的大小,比如 <img src="http:/
|
||||
|
||||
因为不同的指标和不同的分配有着不同的 <img src="http://chart.googleapis.com/chart?cht=tx&chl=s'" style="border:none;" alt="s'" /> ,那么我不应该让每个实验者自己去计算它, 我们提供了一个工具计算实验者指定的关注指标和指标敏感度,分配类型(比如`cookie`取模或是随机流量)和他们想要的某种流量(比如,分配条件,比如日语流量),工具就告诉实验者他需要多大规模流量才可以支持他的要求的实验。实验者可以轻松地在流量大小和敏感量之间权衡,有了这个工具,我们可以认为实验者在运行实验之前会设置合理的实验规模。
|
||||
|
||||
为了为我们的实验规模工具收集数据,我们一直运行一组 **同质测试**(`uniformity trial`),比如,我们运行许多对比实验或A vs. A实验。这些实验有着不同的实验规模和分配类型,我们可以用这些结果经验地衡量我们指标的自然变化(`natural variance`),并可以测试我们计算的置信区间的正确性。
|
||||
为了为我们的实验规模工具收集数据,我们一直运行一组 **同质测试**(`uniformity trial`),比如,我们运行许多 对比实验或A vs. A实验。这些实验有着不同的实验规模和分配类型,我们可以用这些结果经验地衡量我们指标的自然变化(`natural variance`),并可以测试我们计算的置信区间的正确性。
|
||||
|
||||
### 5.2.2 Trigging, Logging, & Counter-factuals
|
||||
|
||||
回顾一下,流量分配是指分配给实验的流量,但是一个实验可能不会对所有分配给它的流量进行新特性服务,相反,一些实验可能仅在某种请求时被 **触发**(`trigger`),比如一个实验是测试何时应该显示天气信息,它可能会得到全部的流量 ,但只有一部分流量的查询会触发显示天气,这一部分但触发查询就称为触发集合。
|
||||
回顾一下,流量分配是指分配给实验的流量,但是一个实验可能不会对所有分配给它的流量进行新特性服务,相反,一些实验可能仅在某种请求时被 **触发器**(`trigger`),比如一个实验是测试何时应该显示天气信息,它可能会得到全部的流量 ,但只有一部分流量的查询会触发显示天气,这一部分但触发查询就称为触发集合。
|
||||
|
||||
通常,我们无法仅将触发集合的流量给实验,因为要确定请求是否触发,是需要运行时计算的,这种运行时的计算正是触发无法实现成分配条件的原因(这个触发条件很难构造对照实验流量),所以,重要的工作是记录事实(`factual`,当实验被触发)和反事实(`counter-factual`,当实验可被触发),反事实是在对比实验中记录的,比如在前面的例子中,事实(当天气信息展示)是记录在实验中的,反事实是记录在对照实验中的。比如当这个查询是可以展示天气信息的(因为它是在对比实验中,所以实际并没展示)。这些日志对于实验样本量和分析实验都很重要,因为流量中包括了没有实验变化的请求,这些请求会稀释实验的作用,在触发集合上衡量实验结果会更准确衡量实验的影响。另外,通过关注于触发集合的显著效果,实验流量的需求可以减少,因为实验的有效规模是依赖于我们要想检测的敏感度的倒数(<img src="http://chart.googleapis.com/chart?cht=tx&chl=1%2F%5Ctheta%5E2" style="border:none;" alt="1/\theta^2" />)。
|
||||
|
||||
@@ -195,7 +195,7 @@ _Kohavi_ 假设实验与对照实验有相同的大小,比如 <img src="http:/
|
||||
|
||||
实验除了正确性和完备性,对一个实验分析工具的其它重要设计目标包括:
|
||||
|
||||
* 正确地计算和显示置信区间:实验者需要知道是否他的实验仅是没有得到足够的流量(置信区间太宽),或是是否观察到的变化是统计显著的。我们研究了很多种计算准确置信区间的方法,虽然无法完整地讨论已经超出了本文范围,仅说明一下我们考虑了delta方法和其它的经验方法来计算置信区间:将实验分成几个子集,从这些子集上统计方差,并注意,一定要观察多个实验指标和实验,因为一些指标值会随机显示为显著,所以一定要多检查。
|
||||
* 正确地计算和显示置信区间:实验者需要知道是否他的实验仅是没有得到足够的流量(置信区间太宽),或是是否观察到的变化是统计显著的。我们研究了很多种计算准确置信区间的方法,虽然无法完整地讨论已经超出了本文范围,仅说明一下我们考虑了`delta`方法和其它的经验方法来计算置信区间:将实验分成几个子集,从这些子集上统计方差,并注意,一定要观察多个实验指标和实验,因为一些指标值会随机显示为显著,所以一定要多检查。
|
||||
* 一个好的`UI`,`UI`必须是易用的,并是易于理解的。图形化是会有所帮助的,如果要聚合的效果在一定时期内是致的,即使是简单的走势图也能对可视化有所帮助。`UI`也应提示不合理的比较(比如,比较两个不同层的实验),并且`UI`应该方便地更改对比的实验,或对比的时期等等。
|
||||
* 支持划分,聚合后的数值常会有误导性,比如导致指标改变的原因也许并不是实验(比如,`CTR`改变),而是因为一个混合的变化(比如,更多的商业搜索词)。正如Kohavi所言[4],辛普森悖论的观察与理解是很重要的。
|
||||
* 扩展性,它必须能方便地添加用户自定义的指标和划分,特别是对新特性,已经存在的指标集合和划分可能是不够的。
|
||||
@@ -223,7 +223,7 @@ _Kohavi_ 假设实验与对照实验有相同的大小,比如 <img src="http:/
|
||||
|
||||
另一个过程是讨论会,实验者们带着他们的实验结果与专家进行讨论,讨论的目标是:
|
||||
|
||||
* 保证实验的结果是有效的。在有些时候,即使有实验委员会,但在实际的实验上出错了,或是有一些意外发生,在这些情况中,讨论会中的讨论就像是一个`debugging`的过程,有完整的开发,日志,实验架构,指标,分析工具的专家集合是解决问题的关键。
|
||||
* 保证实验的结果是有效的。在有些时候,即使有实验委员会,但在实际的实验上出错了,或是有一些意外发生,在这些情况中,讨论会中的讨论就像是一个调试(`debugging`)的过程,有完整的开发,日志,实验架构,指标,分析工具的专家集合是解决问题的关键。
|
||||
* 有了有效的结果后,要保证对指标集合做整体的观察,以理解实验结果到底如何,其它划分数据的方法或是改变指标也许可以更进一步理解实验的影响。一些实验很复杂,需要实验者追踪地进行几次。
|
||||
* 有了完整的结果集合,讨论并决定整个实验是一个正影响或负影响的用户体验,有了决定后,决策者可用这个数据(结合策略和战略信息)来决定是否要发布这个实验,或提出可能的改进建议,或是放弃。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user