參考:
從假設(shè)檢驗(yàn)到AB實(shí)驗(yàn)——面試前你要準(zhǔn)備什么?
一文入門A/B測試(含流程、原理及示例)
A/B testing(一):隨機(jī)分配(Random Assignment)里的Why and How
AB測試的簡介
我們都或多或少聽說過A/B測試,即便沒有聽過其實(shí)也被動的參與過——作為受試者。AB實(shí)驗(yàn)是數(shù)據(jù)分析、產(chǎn)品運(yùn)營、算法開發(fā)在工作中都時常接觸到的工作。在網(wǎng)站和APP的設(shè)計(jì)、產(chǎn)品的運(yùn)營中,經(jīng)常會面臨多個設(shè)計(jì)/運(yùn)營方案的選擇。小到按鈕的位置、文案的內(nèi)容、主題的顏色,再到注冊表單的設(shè)計(jì)、不同的運(yùn)營方案,都有不同的選擇。A/B test可以幫助我們做出選擇,消除客戶體驗(yàn)(UX)設(shè)計(jì)中不同意見的爭執(zhí)。按鈕顏色、廣告算法、標(biāo)簽排序,這些互聯(lián)網(wǎng)產(chǎn)品里常見的功能與展示都是在一次次AB實(shí)驗(yàn)中得到優(yōu)化。
所謂A/B test,其實(shí)類似于初中生物說的對照試驗(yàn)。對用戶分組,每個組使用一個方案(方案應(yīng)遵從單變量前提),在相同的時間維度上去觀察用戶的反應(yīng)(體現(xiàn)在業(yè)務(wù)數(shù)據(jù)和用戶體驗(yàn)數(shù)據(jù)上)。需要注意的是各個用戶群組的組成成分應(yīng)當(dāng)盡量相似,譬如新老用戶很有可能表現(xiàn)出較大的偏好差異。最后根據(jù)假設(shè)檢驗(yàn)的結(jié)果,判斷哪些版本較之原版有統(tǒng)計(jì)意義上的差異,并根據(jù)效應(yīng)量選出其中表現(xiàn)最好的版本。
一個完整的AB測試流程
- 分析現(xiàn)狀,建立假設(shè):分析業(yè)務(wù),確定最高優(yōu)先級的改進(jìn)點(diǎn),作出假設(shè),提出優(yōu)化建議。
- 設(shè)定指標(biāo):設(shè)置主要指標(biāo)來衡量版本的優(yōu)劣;設(shè)置輔助指標(biāo)來評估其他影響。
- 設(shè)計(jì)與開發(fā):設(shè)計(jì)優(yōu)化版本的原型并完成開發(fā)。
- 確定測試時長:確定測試進(jìn)行的時長。
- 確定分流方案:確定每個測試版本的分流比例及其他分流細(xì)節(jié)。
- 采集并分析數(shù)據(jù):收集實(shí)驗(yàn)數(shù)據(jù),進(jìn)行有效性和效果判斷。
- 給出結(jié)論:①確定發(fā)布新版本;②調(diào)整分流比例繼續(xù)測試;③優(yōu)化迭代方案重新開發(fā),回到步驟1。
注意點(diǎn)
測試時長 : 測試時長不宜過短,否則參與實(shí)驗(yàn)的幾乎都是該產(chǎn)品的高級用戶(短時間新用戶流入較少)。
分流(抽樣):應(yīng)該保持同時性、同質(zhì)性、唯一性、均勻性。
同時性:分流應(yīng)該是同時的,測試的進(jìn)行也應(yīng)該是同時的。
同質(zhì)性:也可以說是相似性,是要求分出的用戶群,在各維度的特征都相似??梢曰谟脩舻脑O(shè)備特征(例如手機(jī)機(jī)型、操作系統(tǒng)版本號、手機(jī)語言等)和用戶的其他標(biāo)簽(例如性別、年齡、新老用戶、會員等級等)進(jìn)行分群,每一個A/B測試試驗(yàn)都可以選定特定的用戶群進(jìn)行試驗(yàn)。 控制變量
思考:如何判斷是不是真的同質(zhì)? 可以采用AAB測試。抽出兩份流量進(jìn)行A版本的測試,進(jìn)行AA測試,并分別與B版本進(jìn)行AB測試。通過考察A1和A2組是否存在顯著性差異,就可以確定試驗(yàn)的分流是否同質(zhì)了。唯一性: 即要求用戶不被重復(fù)計(jì)入測試。
-
均勻性: 要求各組流量是均勻的。希望把每一個用戶隨機(jī)分配到試驗(yàn)組(treatment group)和控制組(control group),但為什么我們要做隨機(jī)分配(why we need to do random assignment),和應(yīng)該怎么做隨機(jī)分配(how to do random assignment)可以參考:隨機(jī)分配里的Why and How。(統(tǒng)計(jì)學(xué)原理上,我沒有找到均勻性這一要求的依據(jù),其實(shí)雙樣本的假設(shè)檢驗(yàn)并不要求兩個樣本的數(shù)量相等或相近。當(dāng)然從直觀上是可以理解,希望分出的用戶組越相近越好,包括人數(shù)的相近。)
- 1 現(xiàn)在有一個user,他有一個user_id
- 2 每run一個實(shí)驗(yàn),我們都有一個特定的salt,把這個user_id和這個salt拼接起來成一個長字符串;
- 3 把2中得到的長字符串扔進(jìn)一個哈希函數(shù)(可以是MD5或者SHA1),這里用MD5,然后生成一條哈希數(shù)據(jù)(Hashed data);
- 4 取3中得到的哈希數(shù)據(jù)的頭六位字符,轉(zhuǎn)換成一個十六進(jìn)制整數(shù);
- 5 拿4中得到的整數(shù)去除以最大的六位十六進(jìn)制數(shù)字(0xffffff),注意用浮點(diǎn)數(shù)相除,會得到一個介于0和1之間的浮點(diǎn)數(shù)。
- 6 根據(jù)第5步得到的浮點(diǎn)數(shù)是否大于預(yù)設(shè)閾值,決定這個用戶的分組。舉個例子,如果我們想得到50-50的平均分配,那么我們會預(yù)先設(shè)定一個閾值0.5,如果第5步得到的是0.4,那么這個用戶被分到控制組,因?yàn)樗∮?.5,如果第5步得到的是0.6,這個用戶被分配到試驗(yàn)組。
理由:
- 我之前做隨機(jī)的時候都是取隨機(jī)數(shù)和閾值進(jìn)行比較,超過閾值一組,低于閾值的是另一組。 但是如果發(fā)生了錯誤,對用戶精準(zhǔn)定位就會比較麻煩(隨機(jī)數(shù)是隨機(jī)的,需要靠隨機(jī)數(shù)種子控制,而且每次試驗(yàn)取不同的隨機(jī)數(shù)種子)。這種方法是可以對每次試驗(yàn)的用戶的分組進(jìn)行實(shí)現(xiàn)的(每個用戶的id是確定的,每個試驗(yàn)的salt也是確定的),不僅方便精確定位用戶,而且實(shí)驗(yàn)出問題了也方便debugging。
- 一個實(shí)驗(yàn)對應(yīng)一個salt,每個實(shí)驗(yàn)不一樣,這樣保證不同實(shí)驗(yàn)有完全不一樣的隨機(jī)分配。因?yàn)橐患夜疽惶炜赡茏龊芏鄬?shí)驗(yàn),如果一個用戶老是被分到試驗(yàn)組,他用戶體驗(yàn)會比較差
- 最后得到的隨機(jī)分配結(jié)果還是比較'Random'的,雖然本質(zhì)上都是假Random。
A/B測試只能有兩個版本么?
A/B test不是只能A方案和B方案,實(shí)際上一個測試可以包含A/B/C/D/E/……多個版本,但是要保證單變量,比如按鈕的顏色赤/橙/黃/綠/青/藍(lán)/紫,那么這七個方案是可以做A/B測試的;但如果某方案在旁邊新增了另一個按鈕,即便實(shí)驗(yàn)結(jié)果產(chǎn)生了顯著差異,我們也無法判斷這種差異的成因究竟是誰。
同一段時間內(nèi)可以做不同的A/B測試么?
比如一個test抽取總體20%的流量做按鈕顏色的實(shí)驗(yàn),另一個test也抽取總體20%的流量做布局樣式的實(shí)驗(yàn)。是否可行?
我認(rèn)為是可行的。但要求多個方案并行測試,同層互斥。如果從總體里,先后兩次隨機(jī)抽取20%流量,則很有可能會有重疊的用戶,既無法滿足控制單變量,又影響了用戶的使用體驗(yàn)。
- 同層指的是在同一流量層中創(chuàng)建實(shí)驗(yàn),在此層中創(chuàng)建的實(shí)驗(yàn)共享此層中的100%流量。
- 互斥指的是在此層中,一個設(shè)備有且只能分配到此層多個實(shí)驗(yàn)中的某一個實(shí)驗(yàn)。
假設(shè)檢驗(yàn)的示例
數(shù)據(jù):對web新舊頁面的A/B測試結(jié)果,來自Udacity的示例案例
- 用戶id
- 時間戳
- 分組(實(shí)驗(yàn)組還是對照組)
- 展示頁面的新舊版本(新版本還是舊版本)
- 該用戶是否發(fā)生了轉(zhuǎn)化(0-未轉(zhuǎn)化、1-轉(zhuǎn)化)
ab測試目的:判斷新舊兩版頁面在用戶的轉(zhuǎn)化情況上是否有顯著區(qū)別
數(shù)據(jù)清洗
- 查看總的數(shù)據(jù)行數(shù) 和 (去重后)的獨(dú)立用戶進(jìn)行比較
- 發(fā)現(xiàn)上述不一致(出現(xiàn)了重復(fù)統(tǒng)計(jì)的用戶)
- 利用duplicated考察重復(fù)數(shù)據(jù)
- 分組group和展示頁面的新舊版本landing_page應(yīng)當(dāng)是匹配的(treatment-new_page、control-old_page),但是發(fā)現(xiàn)存在不匹配的情況。 去掉不匹配的記錄。
- 去掉不匹配的記錄之后利用drop_duplicates去掉重復(fù)值(發(fā)現(xiàn)此時只有一條重復(fù)值)。
6.檢查缺失值,若存在缺失值可以進(jìn)行直接刪除、填充等處理。 - 比較收到新頁面的用戶占比和老頁面的用戶占比。
假設(shè)檢驗(yàn)
1.給出零假設(shè)和備擇假設(shè):
記舊頁面的轉(zhuǎn)化率為,新頁面的轉(zhuǎn)化率為
我們的目標(biāo)是為了說明, 因此作出如下假設(shè):
即
即
這個業(yè)務(wù)可以抽象為:X是否被轉(zhuǎn)化,也就是兩點(diǎn)分布
。對于n個個體則為二項(xiàng)分布
。
因此有:
和
由于滿足兩點(diǎn)分布
有以上的鋪墊下面求
此刻和
都是未知的,所以要通過樣本成數(shù)進(jìn)行估計(jì),即設(shè)
,其中
因此:-
確定檢驗(yàn)類型和檢驗(yàn)統(tǒng)計(jì)量
獨(dú)立雙樣本。樣本大小n>30,總體的均值和標(biāo)準(zhǔn)差未知,用Z檢驗(yàn)。檢驗(yàn)統(tǒng)計(jì)量為:
為轉(zhuǎn)化率的聯(lián)合估計(jì),
,其中
。
給定顯著性水平
方法一、直接根據(jù)公式計(jì)算檢驗(yàn)統(tǒng)計(jì)量Z
舊版總受試用戶數(shù): 145274 舊版轉(zhuǎn)化用戶數(shù): 17489 舊版轉(zhuǎn)化率: 0.1204
新版總受試用戶數(shù): 145310 新版轉(zhuǎn)化用戶數(shù): 17872 新版轉(zhuǎn)化率: 0.1230
轉(zhuǎn)化率的聯(lián)合估計(jì): 0.12169
檢驗(yàn)統(tǒng)計(jì)量z: -2.1484
, 拒絕域?yàn)?img class="math-inline" src="https://math.jianshu.com/math?formula=%7BZ%20%3C%20-1.6449%7D" alt="{Z < -1.6449}" mathimg="1">。
z=-2.15落入拒絕域。在顯著性水平時,拒絕零假設(shè)。
假設(shè)檢驗(yàn)并不能真正的衡量差異的大小,它只能判斷差異是否比隨機(jī)造成的更大。cohen-s-d,因此,我們在報(bào)告假設(shè)檢驗(yàn)結(jié)果的同時,給出效應(yīng)的大小。對比平均值時,衡量效應(yīng)大小的常見標(biāo)準(zhǔn)之一是Cohen's d,中文一般譯作科恩d值:

這里的標(biāo)準(zhǔn)差,由于是雙獨(dú)立樣本的,需要用合并標(biāo)準(zhǔn)差(pooled standard deviations)代替。也就是以合并標(biāo)準(zhǔn)差為單位,計(jì)算兩個樣本平均值之間相差多少。雙獨(dú)立樣本的并合標(biāo)準(zhǔn)差可以如下計(jì)算:

Cohen's d的值約為-0.00797,絕對值很小。兩者雖有顯著性水平5%時統(tǒng)計(jì)意義上的顯著差異,但差異的效應(yīng)量很小??梢院唵蔚乩斫鉃?strong>顯著有差異,但差異的大小不顯著。

利用python進(jìn)行計(jì)算:
statsmodels.stats.proportion.proportions_ztest
第一個參數(shù)為兩個概率的分子
第二個參數(shù)為兩個概率的分母
第三個參數(shù)alternative[‘two-sided’, ‘smaller’, ‘larger’]分別代表[雙側(cè),左尾,右尾]
import statsmodels.stats.proportion as sp
# alternative='smaller'代表左尾
z_score, p_value = sp.proportions_ztest([convert_old, convert_new], [n_old, n_new], alternative='smaller')
可以同時得到檢驗(yàn)統(tǒng)計(jì)量和P值,得到的z值和前面計(jì)算的完全相同,落在拒絕域,故拒絕零假設(shè)。同時我們也得到了p值,用p值判斷與用檢驗(yàn)統(tǒng)計(jì)量z判斷是等效的,這里p值約等于0.016, ,同樣也拒絕零假設(shè)。
在python中一般的z檢驗(yàn)是這樣做的statsmodels.stats.weightstats.ztest
直接輸入兩組的具體數(shù)值即可,同樣有alternative參數(shù)控制檢驗(yàn)方向。
蒙特卡洛模擬
蒙特卡羅法其實(shí)就是計(jì)算機(jī)模擬多次抽樣,不過感覺好強(qiáng)啊,結(jié)果直觀又容易理解,能夠很好的幫助初學(xué)者理解分布、p值、顯著性、分位數(shù)等概念。
在零假設(shè)成立的前提下( 即
),
為臨界情況(零假設(shè)中最接近備擇假設(shè)的情況)。如果連臨界的情況都可以拒絕,那么剩下的部分更可以拒絕(
)。
可以利用樣本數(shù)據(jù)求得整體的總轉(zhuǎn)化率,下面考察臨界情況,以
為新舊版共同的轉(zhuǎn)化率,即取
,分別進(jìn)行n_old次和n_new次二項(xiàng)分布的抽樣。
重復(fù)抽樣多次,每次抽樣之后,都可以得到:舊版本與新版本之間的轉(zhuǎn)化率差值。而此數(shù)據(jù)的轉(zhuǎn)化率差值為:-0.0026。
可以觀測模擬得到轉(zhuǎn)化率差值的分布(由于概率相等,應(yīng)該接近于正態(tài)分布)和此數(shù)據(jù)的轉(zhuǎn)化率差值的位置關(guān)系。

在diffs列表的數(shù)值中,有多大比例小于ab_data.csv中觀察到的轉(zhuǎn)化率差值?此次模擬的結(jié)果為0.0155,每次模擬的結(jié)果都不太相同,但都在p值(0.016)上下浮動,且隨著樣本量的增大,更加接近p值。
上圖的含義是,在時進(jìn)行的10000次隨機(jī)模擬得到的差值中,只有1.55%比數(shù)據(jù)集中的差值更極端,說明我們這個數(shù)據(jù)集在
的前提下是小概率事件。如果
則得到的差值的分布仍然近似于正態(tài)分布但是其均值會右移,此時數(shù)據(jù)中的差值會更加極端。因此,此數(shù)據(jù)的結(jié)果是零假設(shè)中的極端情況,零假設(shè)很有可能是不成立的。
若diffs的分布就是標(biāo)準(zhǔn)正態(tài)(這里只是近似),則豎線左側(cè)的面積占比其實(shí)就是p值(左側(cè)or右側(cè)or雙側(cè)要根據(jù)備擇假設(shè)給定的方向
p值到底要多小才算真的小?
這需要我們自己給定一個標(biāo)準(zhǔn),這個標(biāo)準(zhǔn)其實(shí)就是,是犯第一類錯誤的上界,常見的取值有0.1、0.05、0.01。
所謂第一類錯誤,即拒真錯誤,也就是零假設(shè)為真,我們卻拒絕了。在這個例子里就是——新舊版轉(zhuǎn)化率明明相等,只不過我們很非酋,得到的樣本正好比較極端,以至于我們錯誤地認(rèn)為新舊版轉(zhuǎn)化率不等。所以要取定一個時,認(rèn)為原假設(shè)在該顯著性水平下被拒絕。(如果我們?nèi)〉氖?.01而不是0.05,則這個例子里就拒絕不了零假設(shè)了。)
并不是越小越好,這與第二類錯誤的概率有關(guān),
越小,則
就越大,而第二類錯誤的概率也需要控制在一定的范圍,因此不能一味地取極小的
。
