调整用词

This commit is contained in:
Jerry Lee
2017-04-25 18:07:12 +08:00
parent eb2dc1f7e8
commit 27f15263ef

View File

@@ -52,7 +52,7 @@
本文提出的解决方案是将参数分成子集,每个参数子集包含相互不能独立修改的参数。一个参数子集会与一个包含实验的层相关联,不同层的实验的流量是正交的。每个`query`可以在 <img src="http://chart.googleapis.com/chart?cht=tx&chl=N" style="border:none;" alt="N" /> 个实验中,其中 <img src="http://chart.googleapis.com/chart?cht=tx&chl=N" style="border:none;" alt="N" /> 是层的数量。
# 2. 相关工作【略】
# 2. 相关工作成果【略】
# 3. 背景
@@ -67,13 +67,13 @@
一个`Web`搜索中的**实验**是指将一部分请求流量转向一个特定的处理路径,这个处理路径会改变向用户展示的内容。一个**对照实验**将一部分请求流量转向一个处理路径,但它并不改变向用户展示的内容。我们用数据推送来决定实验的配置。在数据推送中,有一个文件决定程序的默认参数配置。另一个文件决定实验所需要改变的参数的值,实验只用指定实验所要改变的参数,对于其它参数,都采用默认值。比如,在一个简单实验中,它只改变顶部广告的背景色这一个参数,它可以改变黄色(默认值)到粉色(实验值)。
实验还需要决定实验所用的流量如何**分配**。最简单的分配方式是用_随机流量_即对每个请求都进行随机分配。但这样做的问题是如果实验是用户可见的改变比如改变背景色那么一个用户可能就得到不同的用户体验背景色不断地在黄色和粉色间转换这会造成用户体验不一致。在`Web`实验中常用的方法是用 **`Cookie`** 作为流量分配的依据,`Cookie`被网站用来定位唯一用户。实践中,Cookie是机器/浏览器相关的,并可能被清除。然而,虽然一个`Cookie`不能唯一定位一个用户,但对于连续的查询,它可以提供给用户一致性的用户体验。对于实验流量分配,我们并不直接对每单个`Cookie`进行分配,而是用 **`Cookie`取模** 进行分配:用一个`ID`表示一个`Cookie`,对这个`ID`模1000将模相等的流量聚合为实验流量比如模等于42的流量。假设`Cookie`的分配是随机的,那么随意`Cookie`的模数的请求数据也应该是大致相等的。在实验配置中使用`Cookie`的模也可以很容易地检查流量之间是否有冲突实验1可能会用`Cookie`模1和模2实验2可能使用`Cookie`模3和模4这两个实验就会有相近的大小理论上是可以进行比较的流量。
实验还需要决定实验所用的流量如何**分配**。最简单的分配方式是用_随机流量_即对每个请求都进行随机分配。但这样做的问题是如果实验是用户可见的改变比如改变背景色那么一个用户可能就得到不同的用户体验背景色不断地在黄色和粉色间转换这会造成用户体验不一致。在`Web`实验中常用的方法是用 **`cookie`** 作为流量分配的依据,`cookie`被网站用来定位唯一用户。实践中,`cookie`是机器/浏览器相关的,并可能被清除。然而,虽然一个`cookie`不能唯一定位一个用户,但对于连续的查询,它可以提供给用户一致性的用户体验。对于实验流量分配,我们并不直接对每单个`cookie`进行分配,而是用 **`cookie`取模** 进行分配:用一个`ID`表示一个`cookie`,对这个`ID`模1000将模相等的流量聚合为实验流量比如模等于42的流量。假设`cookie`的分配是随机的,那么随意`cookie`的模数的请求数据也应该是大致相等的。在实验配置中使用`cookie`的模也可以很容易地检查流量之间是否有冲突实验1可能会用`cookie`模1和模2实验2可能使用`cookie`模3和模4这两个实验就会有相近的大小理论上是可以进行比较的流量。
> 【译注】上面例子中用的示例数值42是`Hacker`必读的《银河系漫游指南》中的梗42是万事万物的答案。
在数据文件中配置实验,可以让实验更快更方便地创建:数据文件是可读的,并容易手工编辑,不需要进行代码变更,并可以由非工程师进行创建,而且配置数据的推动会比二进制程序的发布更加频繁,它使创建仅包含已有参数的实验更加方便快捷。
在开发我们的实验设施之前,我们使用一个简单的单层实验设施,在这个设施中,每个请求最多进行一种实验。先分配`Cookie`取模的流量的实验,再分配随机流量的实验。上游服务会优先分配流量,所以如果上游(即`Cookie`取模的实验)进行了很多实验,那么下游可能会得不到足够的流量,即流量饥饿问题。除了这些问题之外(包括前面提到的流量饥饿和偏置问题),单层实验可以满足我们设计目标中的易用和相对的灵活性。但是在`Google`数据驱动的文件中,单层的方法没有足够的可扩展性:我们无法快速地进行足够多的实验。
在开发我们的实验设施之前,我们使用一个简单的单层实验设施,在这个设施中,每个请求最多进行一种实验。先分配`cookie`取模的流量的实验,再分配随机流量的实验。上游服务会优先分配流量,所以如果上游(即`cookie`取模的实验)进行了很多实验,那么下游可能会得不到足够的流量,即流量饥饿问题。除了这些问题之外(包括前面提到的流量饥饿和偏置问题),单层实验可以满足我们设计目标中的易用和相对的灵活性。但是在`Google`数据驱动的文件中,单层的方法没有足够的可扩展性:我们无法快速地进行足够多的实验。
# 4. 重叠实验基础设施
@@ -102,7 +102,7 @@
1. 使用非重叠域可以让我们同时进行改变大量参数值的组合实验,这些实验参数也许并不常一起使用。
2. 它允许我们进行不同参数划分方式。比如你可以划分出三个域,一个是非重叠的,一个是有两个层的域(即对参数集合进行一次划分),第三个域进行其它的划分方式(即有不同数量的层)。
3. 嵌套可以更有效地利用空间,可以根据常用的参数划分方式,和哪些跨层的实验经常进行,注意将一个层的参数从一个层移到另一个层是很容易的,只要确认参数可以安全地与原有层的参数值重叠,并注意保证不同层的实验会被独立地进行,对于基于`Cookie`取模的实验,我们用`mod = f(cookie, layer) % 1000`,而不是`f(cookie) % 1000`的方式虽然这种方式增加了复杂性但它也增加了灵活性。对配置的修改是需要付出代价的特别是对域的修改修改域的流量即是修改实验的流量比如如果我们将非重叠流量大小从10%修改到15%这多出来的5%流量来自重叠域,以前经过重叠域的请求现在会经过非重叠域。
3. 嵌套可以更有效地利用空间,可以根据常用的参数划分方式,和哪些跨层的实验经常进行,注意将一个层的参数从一个层移到另一个层是很容易的,只要确认参数可以安全地与原有层的参数值重叠,并注意保证不同层的实验会被独立地进行,对于基于`cookie`取模的实验,我们用`mod = f(cookie, layer) % 1000`,而不是`f(cookie) % 1000`的方式虽然这种方式增加了复杂性但它也增加了灵活性。对配置的修改是需要付出代价的特别是对域的修改修改域的流量即是修改实验的流量比如如果我们将非重叠流量大小从10%修改到15%这多出来的5%流量来自重叠域,以前经过重叠域的请求现在会经过非重叠域。
另一个概念是**发布层**`Launch layers`),发布层与前面介绍的实验层有下面区别:
@@ -114,7 +114,7 @@
从前面我们已经了解到实验和域都是在操作一份流量,(我们称这种流量为『分配』的流量),为了更有效的进行实验流量分配,我们提出了两个不同的概念:分配类型和分配条件。
我们在第三节讨论了两种**流量分配类型**,即`Cookie`取模方式和随机方式,还讨论了为了让层与层之间实现流量之间相互独立,在`Cookie`取模时加入了层`id`的信息(`mod = f(cookie, layer) % 1000`)。我们还支持另两种流量分配类型,用户`id`取模和`cookie`日期取模,用户`id`取模类似于`cookie`取模,区别仅是对用户`id`取模而不是`cookie`,对于`cookie`日期取模,综合`cookie`和日期的信息后再取模,采用这种方式的话,一个实验一天内圈定的`cookie`是固定的,但随着日期的变更会圈定不同的`cookie`。在所有的场景中,是没有办法配置一个实验能使特定的`cookie`或是用户必通过这个实验。同样,在分析实验结果的时候也要考虑不同抽样方式的差别。同样注意,我们当前只支持的四种分类型,但我们也可以支持其它的流量分配类型,比如通过`Hash`查询串分流。
我们在第三节讨论了两种**流量分配类型**,即`cookie`取模方式和随机方式,还讨论了为了让层与层之间实现流量之间相互独立,在`cookie`取模时加入了层`id`的信息(`mod = f(cookie, layer) % 1000`)。我们还支持另两种流量分配类型,用户`id`取模和`cookie`日期取模,用户`id`取模类似于`cookie`取模,区别仅是对用户`id`取模而不是`cookie`,对于`cookie`日期取模,综合`cookie`和日期的信息后再取模,采用这种方式的话,一个实验一天内圈定的`cookie`是固定的,但随着日期的变更会圈定不同的`cookie`。在所有的场景中,是没有办法配置一个实验能使特定的`cookie`或是用户必通过这个实验。同样,在分析实验结果的时候也要考虑不同抽样方式的差别。同样注意,我们当前只支持的四种分类型,但我们也可以支持其它的流量分配类型,比如通过`Hash`查询串分流。
支持多种流量分配类型的主要目的一方面是为了保持处理的一致性,另外也希望可以覆盖到所有可能的情况,比如因时间变化而表征出来的不同特征。基于这些原因,我们以特定的顺序对不同的流量分配类型进行分流:用户`id``cookie``cookie`日期随机。一旦这个请求被某高优先级分配方式抽中后其它低优先级的分配方式将忽略这个请求图3虽然这个顺序最大化地了一致性但它也有一个缺点比如在同一层中1%的`cookie`取模流量会比1%的随机流量大在极端情况下我们会遇到流量饥饿问题。在实践中一层之中一般只应有一种分流类型实验和对比实验必须使用相同的分流类型最主要的影响是不同的分流类型实验需要不同的样本量见5.2.1节)。
@@ -197,7 +197,7 @@ _Kohavi_ 假设实验与对照实验有相同的大小,比如 <img src="http:/
* 正确地计算和显示置信区间:实验者需要知道是否他的实验仅是没有得到足够的流量(置信区间太宽),或是是否观察到的变化是统计显著的。我们研究了很多种计算准确置信区间的方法,虽然无法完整地讨论已经超出了本文范围,仅说明一下我们考虑了`delta`方法和其它的经验方法来计算置信区间:将实验分成几个子集,从这些子集上统计方差,并注意,一定要观察多个实验指标和实验,因为一些指标值会随机显示为显著,所以一定要多检查。
* 一个好的`UI``UI`必须是易用的,并是易于理解的。图形化是会有所帮助的,如果要聚合的效果在一定时期内是致的,即使是简单的走势图也能对可视化有所帮助。`UI`也应提示不合理的比较(比如,比较两个不同层的实验),并且`UI`应该方便地更改对比的实验,或对比的时期等等。
* 支持划分,聚合后的数值常会有误导性,比如导致指标改变的原因也许并不是实验(比如,`CTR`改变而是因为一个混合的变化比如更多的商业搜索词。正如Kohavi所言[4],辛普森悖论的观察与理解是很重要的。
* 支持划分,聚合后的数值常会有误导性,比如导致指标改变的原因也许并不是实验(比如,`CTR`改变),而是因为一个混合的变化(比如,更多的商业搜索词)。正如 _Kohavi_ 所言[4],辛普森悖论的观察与理解是很重要的。
* 扩展性,它必须能方便地添加用户自定义的指标和划分,特别是对新特性,已经存在的指标集合和划分可能是不够的。
只有一个工具提供实验准确的指标意味着我们有唯一的一致性实现,它使用相同的过滤器(比如,移除潜在的爬虫流量和垃圾流量),这样,不同的团队之间就可的`CTR`值就具有了可比较性。一个唯一的工具也更高效,因为计算会一次完成后,并呈现给实验者们,而不是每个实验者进行他们自己的计算。
@@ -237,7 +237,7 @@ _Kohavi_ 假设实验与对照实验有相同的大小,比如 <img src="http:/
我们可以用几个标准来判断我们是否成功地运行更多的实验在一个时期上一共运行了多少实验这些实验中有多少发布了有多少不同的实验在运行实验见图5。要说明的是实验的数目包含了对照实验的数目。对于运行实验人数一些实验是有多个拥有者的比如如果某人离开城市或发生了事或是将团队邮件列表中的成员也认为拥有者。不幸的是我们无法轻松地知道有多少拥有者是非工程师但有意思的是非工程师的数据是在增加的对分布层的数量我们只计算了使用重叠实验的发布层的数量。在重叠实验之前我们用其他的一些机制发布实验但它们的频率在下降。在所有的图中y轴上的数据出于保密的原因隐去了它们是线性比例但从趋势上可以明显地看出我们系统支持了指数级增加的实验发布实验者。
<img src="figure-05-1.jpg" width="290"><img src="figure-05-2.jpg" width="290"><img src="figure-05-3.jpg" width="290">
<img src="figure-05-1.jpg" width="30%"><img src="figure-05-2.jpg" width="30%"><img src="figure-05-3.jpg" width="30%">
**图5**:实验,拥有者,发布数量在时间上的趋势图
## 6.2 更好