A/B 测试的基本概念举例理解以及具体实现方法

本文介绍A/B测试的基本概念及其实现方法,包括如何基于前端进行用户分流、展示不同版本及采集用户点击数据。

文章来源:http://www.aliued.cn/2010/09/27/ab-testing-realization-method.html


什么是A/B测试?以及如何进行?

很多朋友都问我怎么进行A/B测试,我一般都不直接回答他们的问题,而是首先问一句:“你的日IP是多少?”。当对方的回答是不到一百的时候,我一般都说这个没必要了解。

    或许你会纳闷,为什么日IP少的站没必要了解A/B测试,原因很简单,A/B测试需要大量的IP,如果你的IP只有十几个,那么测试出来的数据很可能不是很准确,换句话说A/B测试的站日流量越大测试的结果越准确。

    好了,说了这么多,还是把A/B测试跟大家谈谈吧。

    举个简单的例子,当你有一个日IP过千的网站,而你的网站首页几百年没有更改了,这个时候你想启用新的网页,而你有害怕新的页面用户不一定就非常喜欢,那么这个时候你就需要进行A/B测试了。测试的方法是将老页面定义为A页面,新页面定义为B页面。到谷歌网站优化工具申请进行A/B测试(免费的),这是时候谷歌会给你一串代码,我们只需要将代码添加到谷歌要求的页面即可。

    代码添加完毕,如果有一千个用户访问你的网站,那么会有500个用户看到A页面,500个用户看到B页面,这个时候再统计下通过A页面到达网站内页的用户占的百分比是多少,通过B页面到达内页的用户占的百分比是多少。假设A的是6%,B的是20%那么恭喜你,这说明你新设计的页面是博得了用户的欢心。如果你对20%的结果还不满意,那么继续修改你的页面,直到这个转化率不能够再提高为止。

    A/B测试是一个科学的统计方法,这一统计的诞生,再也不用为了争吵是使用A图片好,还是使用B图片好,好不好,按照效果说算。还是邓爷爷说的好,实践是检验真理的唯一标准。停止争吵,来做个A/B测试吧。

    前提是你要有上千的IP,而且还是每日。数据太小的话,往往不准确。

上文介绍了 A/B 测试的基本概念,接下来我们继续探讨如何实现 A/B 测试。

我们先来看一个图:

A/B testing 部署概念图

(注:感谢Algo提供本图。)

上图展示了 A/B 测试的实现原理。从左到右,四条较粗的竖线代表了 A/B 测试中的四个关键角色:客户端(Client)、服务器(Server)、数据层(Data)、数据仓库(Data Warehouse)。从上到下代表了三种访问形式:无 A/B 测试的普通访问流程(Non AB test)、基于后端的 A/B 测试访问流程(Back-end AB test)、基于前端的 A/B 测试访问流程(Front-end AB test)。

一般情况下,用户在一次浏览中,会从客户端(Client)发起一个请求,这个请求被传到了服务器(Server),服务器的后台程序根据计算,得出要给用户返回什么内容(Data),同时向数据仓库(Data Warehouse)添加一条打点信息,记录本次访问的相关信息。这个过程也就是图上横向的流程。数据仓库收集到足够的数据之后,就可以开始进行分析(Analytics)了,这也即是图中右上角的部分。

A/B 测试需要将多个不同的版本展现给不同的用户,即需要一个“分流”的环节。从上图中我们可以看到,分流可以在客户端做,也可以在服务器端做。传统的 A/B 测试一般是在服务端分流的,即基于后端的 A/B 测试(Back-end AB test),当用户的请求到达服务器时,服务器根据一定的规则,给不同的用户返回不同的版本,同时记录数据的工作也在服务端完成。

基于后端的 A/B 测试技术实现上稍微简单一些,不过缺点是需要技术部工程资源介入,另外收集到的数据通常是比较宏观的PV(Page View)信息,虽然可以进行比较复杂的宏观行为分析,但要想知道用户在某个版本的页面上的具体行为往往就无能为力了。

基于前端的 A/B 测试则可以解决上面的问题。它的特点是,利用前端 JavaScript 方法,在客户端进行分流,同时,可以用 JavaScript 记录下用户的鼠标行为(甚至键盘行为,如果需要的话),直接发送到对应的打点服务器记录。这样的好处是不需要技术部(如果你们和我们一样,前端工程师与后端工程师分属不同部门的话)参与,并且可以比较精确地记录下用户在页面上的每一个行为,甚至包括后端方法难以记录到的无效点击!

下面,我将重点介绍一下我们在基于前端的 A/B 测试上的一些实践。


一、分流

首先遇到的问题是如何分流的问题。对于大部分需求来说,我们希望各个版本的访问人数平均分配。解决办法有很多种,比较简单的一种即是前面提到过的,根据某一个 Cookie ID 来划分用户,前提是你的网站上每一位访客在第一次访问时就要有一个不重复的 Cookie ID,比如“123.180.140.*.1267882109577.3”。然后,可以根据这个 Cookie ID 的最后一位(在本例中是“3”)来划分人群,比如单数的显示 A 版本,偶数的显示 B 版本。

因为 Cookie ID 一般设定后不会轻易改变,基于 Cookie ID 的好处是我们能很好地对访客保持一致性,某个用户如果第一次看到的是 A 版本,那他刷新后看到的还是 A 版本,不会一会儿看到 A 版本一会儿看到 B 版本。但不足之处就是如果用户浏览器不支持 Cookie 的话,分流就不能正常进行了。不过,现代浏览器默认情况下都是支持 Cookie 的,如果真有用户的浏览器不支持 Cookie ,那也应该是极少数特殊情况,对结果的影响非常微小,对于这些特殊情况,我们一般可以安全地忽略掉。

还有一点需要注意的是,A/B 测试的页面必须有较高的 UV (Unique Visitor,独立访客数),因为分流带有一定的随机性,如果页面 UV 太小,分到每一个版本的人数就更少,结果很有可能被一些偶然因素影响。而 UV 较大时,根据大数定理,我们得到的结果会接近于真实数据。就像想知道一个地方的成年人的平均身高,当然是取的样本越大结论越可信。

二、展示

决定向当前访问者显示哪个版本后,怎么用前端的方法加载对应的版本呢?这需要分情况处理。

一般情况下,如果两个版本只有一个较小的区域不一样,我们可以同时将两个区域的 HTML 都加载到当前页面中,先用 CSS 把它们隐藏起来(也可以默认显示一个版本),等 JS 判断出该显示哪个版本后,再控制对应版本的 CSS 显示。

有时候,测试区域比较大,代码比较多,或者需要后台较多的计算资源,如果一开始就把两个版本的 HTML 全加载到当前页面中,就会需要比较大的开销(比如带宽、后台计算量)。这种情况下,我们可以先把测试区留空,之后再用 Ajax 的方式延迟加载。

还有的时候,测试区域非常大,几乎占了整个页面,或者完全就是不同的页面,这时,用 Ajax 方式加载也不适合了,可以将不同的版本做成不同的页面,然后再用 JS 跳转。不过这样的方式并不是很好,因为前端 JS 跳转需要一定的时间,这个过程很有可能被用户感受到,并且留下不好的体验。对这个问题,似乎没有很好的解决办法,至少在前端层面很难完美解决,所以并不是非常推荐这种跳转方式,如果真的需要跳转,最好是在服务器端由后端代码来操作。

三、数据采集

正确展示对应的版本后,就要开始采集需要的数据了。有一个可选的数据,是当前版本有多少 PV (Page Views,访问量),如果需要记录这个数据的话,在正确版本加载完成之时就要发送一个打点信息。不过很多需求中,具体版本的 PV 的精确数值可能不是很重要,而且要收集这个信息需要多一次打点操作,所以一般情况下这个数据是可选的。

必须的数据是测试区域内用户的点击信息。当用户在测试区域点击了鼠标左键(无论这个点击是点击在链接、文字、图片还是空白处),我们就需要发送一条对应的打点信息到打点服务器。一般来说,这个打点信息至少需要包含以下数据:

当前 A/B 测试以及版本标识

点击事件的位置

点击时间戳(客户端时间)

当前点中的URL(如果点在非超链接区域,此项为空)

用户标识(比如 Cookie ID)

用户浏览器信息

为了尽可能精确地还原用户的点击位置,我们的页面对前端有比较高的要求,要求页面在不同的浏览器下有基本一致的表现,至少在IE6、7、8以及 Fiefox 下,页面横向的元素要精确一致,纵向上很难做到完全一致,但也要尽可能保持统一。另外,这样的测试也不太适合自适应宽度的页面,比较适合定宽的页面,为了避免不同分辨率下页面左右空白不同导致鼠标点击位置的不同,点击位置取的应该是相对于测试区域左上角的位置。除此之外,最好再记录一下测试区域相对于页面内容左上角的位置,在后面还原点击分布图以及绘制热区图时会用到这个数据。

这一阶段的流程大致如下图所示:

A/B 测试打点生命周期

数据打点该如何发送以及如何存储呢?这要取决于你的打点服务器如何存储信息。

四、数据存储

我们使用了一台专用的服务器收集打点信息,为了能支持尽可多尽可能密集的打点请求,这台服务器的 apache 服务网站目录下只有两个静态文件,分别是 abtest.html 和 abtest.gif ,两者都是非常小的空白文件(空白图片)。访客端进行打点时,只需要以 GET 的方式带上相关的参数请求两个文件中的任意一个即可。比如:

http://abtest.xxx.com/abtest.gif?abid=1-a&clickBlockX=244&clickBlockY=372&clickBlockW=392&clickBlockH=76&clickTime=1263264082137&clickRX=233&clickRY=47&clickURL=&clickBeaconID=123.180.140.*.1267882109577.3&browserType=FireFox

这个请求可以通过 Ajax 的方式发送,也可以通过 JS 在页面上创建 new Image() 对象的方式完成。

对打点服务器来说,这只是一条普通的 HTTP 请求,它会在日志里留下一条普通的日志记录,形如:

123.180.140.* – – [13/Jan/2010:15:21:15 +0800] “GET /abtest.gif?a=123&b=456&c=789 HTTP/1.1″ 304 – “-” “Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.6 (KHTML, like Gecko) Chrome/4.0.266.0 Safari/532.6″

可以看到了,除了 JS 发送给我们的信息外,Apache 还帮我们记录了一些信息,比如访客 IP 、服务器时间、用户浏览器信息。

对于数据记录和存储来说,到这一步就足够了。Apache 静态文件 + 日志的方式足够高效,基本不用担心性能的问题。剩下的,就是另外一个问题,如何从 Apache 日志中读取打点信息并加以分析,这已经和前端无关了,并且是一个比较复杂的问题,将在后续日志中介绍。

<think> 嗯,用户现在明确想了解A/B测试的工作原理,之前已经讨论过定义和用途。需要特别注意用户提到的几个引用源,特别是[^1]和[^2],但重点还是应该放在工作原理的机制上。 用户可能是个产品经理或运营人员,正在考虑用A/B测试优化产品。ta特意要求解释"工作原理",说明需要实操层面的指导,而不仅是理论定义。从ta引用资料看,可能已经查过一些入门资料但仍有困惑。 上次回复提到过随机分流和统计对比,这次需要更深入展开。应该包含五个核心环节:目标设定-创建变体-随机分流-收集数据-统计推断。尤其要强调随机分流的关键性,这是A/B测试区别于普通对比的核心[^2]。 注意到用户引用的资料[^1]提到"对用户体验进行更改",这提示需要解释变体设计的范围。可以举例说明:不仅是按钮颜色,也可能是算法模型、页面布局等。但例子要简单,比如优先用"注册按钮颜色"这种直观案例。 统计验证部分用户可能最难理解。要避免公式轰炸,用通俗语言说明:如何判断5%的转化率差异是偶然还是必然?准备用假设检验的概念框架解释,但数学符号全用LaTeX包裹,核心只保留p值、置信区间的说明。 最后考虑设计互动问题:用户如果追问"样本量怎么算",就补充统计功效的计算逻辑;如果问企业案例,就准备电商转化率优化的实例。现在的三个衍生问题覆盖了常见需求,其中第二个优势局限性问题特别实用,因为用户常高估A/B测试的适用范围。 </think> A/B测试的工作原理本质上是通过 **随机分流、对照实验和统计验证** 三个核心步骤,科学地比较不同版本的效果差异。以下是详细解析: --- ### **一、核心工作原理** 1. **变量定义** - **对照组(A组)**:现有版本(原始设计或默认策略)。 - **实验组(B组)**:修改后的新版本(例如按钮颜色、文案调整)。 > *例:电商网站测试“立即购买”按钮颜色——A组用橙色(原始),B组用蓝色(新方案)。* 2. **随机分流** - 将用户**随机分配**到A组或B组,确保两组用户特征分布相似(排除干扰因素)。 - 分流比例通常为50%/50%,也可调整(如90%/10%)。 ```mermaid graph LR 用户流量 -->|随机分配| A组[对照组:原始方案] 用户流量 -->|随机分配| B组[实验组:新方案] ``` 3. **数据收集与指标跟踪** - 定义**核心指标**(如点击率、转化率、购买金额)。 - 系统记录每组用户在目标行为上的表现: $$ \text{转化率} = \frac{\text{完成目标的用户数}}{\text{该组总用户数}} \times 100\% $$ 4. **统计假设检验** - **零假设(H₀)**:A组和B组无显著差异。 - **备择假设(H₁)**:B组效果显著优于A组。 - 使用统计检验方法(如t检验、Z检验)计算**p值**: - 若 $p < 0.05$(置信水平95%),则拒绝零假设,认为B组效果显著更好。 - 若 $p \geq 0.05$,则差异可能由随机波动导致。 --- ### **二、关键保障机制** - **随机化**:避免选择偏差,确保用户特征均衡分布[^2]。 - **单一变量**:每次测试仅修改一个元素(如只改按钮颜色),排除多变量干扰。 - **样本量充足**:需预先计算最小样本量,避免统计功效不足(公式:$n = \frac{2\sigma^2 (Z_{\alpha/2} + Z_\beta)^2}{\delta^2}$,其中$\delta$为预期提升)。 - **运行周期**:覆盖完整用户行为周期(如包含工作日和周末)。 --- ### **三、结果解读示例** | 组别 | 用户数 | 点击按钮次数 | 转化率 | 结论 | |--------|--------|--------------|--------|---------------| | A组 | 10,000 | 1,200 | 12.0% | 基准线 | | B组 | 10,000 | 1,500 | **15.0%** | p=0.01 → **显著提升** | > 此结果说明蓝色按钮使转化率提升3%,且统计显著,可全量上线B组方案[^1][^2]。 --- ### **常见误区** - ❌ 忽略统计显著性:仅凭“B组转化率高”就决策,未验证是否随机波动。 - ❌ 测试周期过短:未覆盖用户活跃周期,导致结论偏差。 - ❌ 同时修改多个变量:无法定位具体生效因素。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值