A/A Test:商業實驗不能忘的前置動作

by 好豪
Published: Updated:

A/A Test 是 A/B Test 上線執行以前的重要前置準備,它幫助我們確認實驗流程本身是否有問題,畢竟,如果實驗方法有錯,那 A/B Test 呈現的任何結果當然也都是錯!

這篇筆記將與你分享 A/A Test 檢測的兩個重要項目:流量隨機分配檢驗(Sample Ratio Mismatch)、以及偽陽性錯誤檢驗,並且附上 Python 程式碼 讓讀者能一起學習實作。

此外,學會 A/A Test 除了幫助我們建立更可信的實驗系統,筆者好豪認為,A/A Test 也是個用不同角度理解 P-Value 的好方法。

什麼是 A/A Test

A/A Test 其實就是 A/B Test 的一種,A/A Test 特點是要比較兩組產品版本一模一樣、但是不同使用者的樣本。

A/A Test 的實驗流程也與典型的 A/B 測試相同:

  1. 決定好要觀測的指標、建立假設
  2. 設定參數:顯著水準與檢定力、最小期望指標差異、指標變異數
  3. 依照參數 計算所需樣本數
  4. 啟動實驗,隨機分配流量
  5. 分析結果

A/A Test 比較的是兩個一模一樣的產品版本,那這個流程結果理所當然是要不顯著、沒有差異,對吧?不見得!

如果 A/A Test 不符合「一模一樣」的預期,最常見會有兩項問題:

  1. 實驗系統的流量分配邏輯有 Bug,不是真的隨機分配
  2. 統計方法或假設有問題,偽陽性錯誤率會高於我們控制的顯著水準

接下來的篇幅,我將介紹 A/A Test 如何檢驗出上述兩樣問題。


A/A Test 必備檢驗項目

1. 流量隨機分配檢驗

你的 A/A Test 要確認控制組與實驗組分配的流量,是否和預先設定的一樣。

假設你在 A/A Test 中,決定讓你的流量以 50%:50% 隨機分配成大小相同的兩組,你就需要檢驗系統分配流量的結果是否確實是預期比例的 50%:50%。

再進一步假設情境:一星期後,你搜集了總共 100 萬個使用者流量。通常,控制組跟實驗組各自的樣本大小,都不會完全剛好是 50 萬,對吧?

我們可以直覺地想像:

  • 如果控制組有 500,012 人、實驗組有 499,988 人,這個流量分配看起來是合理的、距離完美的 50 萬只有一點點自然誤差
  • 如果控制組有 502,000 人、實驗組有 498,000 人,兩組樣本相差 4,000 人,是不是感覺就差很多、不像是「自然」誤差呢?

問題在於:當我們預期系統是隨機的流量按比例分配時,究竟多少誤差是合理的呢?我們可以使用 One Sample Proportion 的假設檢定來觀察:


$$H_0: p=p_0$$
(在此是 \(H_0: p=0.5\))
$$z^{*}=\frac{\hat{p}-p_{0}}{\sqrt{\frac{p_{0}\left(1-p_{0}\right)}{n}}}$$

總樣本數控制組樣本數實驗組樣本數P-Value檢驗結果
1,000,000500,012499,9880.9809正常
1,000,000500,763499,2370.1270正常
1,000,000501,189498,8110.0174*有問題!
1,000,000502,000498,0000.0001**有問題!
Sample Ratio Mismatch,One Sample Proportion 假設檢定範例(Source: 好豪的 GitHub – Python3 實作程式碼

經過 One Sample Proportion 的假設檢定,如果 P-Value 很小、例如小於 0.05,我們就可以知道流量比例分配的結果不符合預期。在上方的表格範例中,如果 100 萬的總樣本數中,實驗組樣本數是 502,000 人的話,檢定告訴我們這個分配顯然不是 50%:50%,這個問題稱為 Sample Ratio Mismatch (SRM),一旦發生,我們就需要檢查我們系統在流量分配的隨機性出了什麼問題。

Sample Ratio Mismatch 發生的原因包括實驗組不恰當的隨機分配方法、Log 埋點與回傳問題、或者系統篩選假資料的過程造成影響等等。並且,原因可能是複合的,所以多個面向都同時需要檢查,如果對於 Sample Ratio Mismatch 的原因追蹤有興趣的讀者可以進一步閱讀 Microsoft 的研究文章

2. 偽陽性錯誤檢驗

接下來,我們要確定 A/A Test 兩組的指標(Metric)是符合預期的無差異,做法是:

  1. 執行多次 A/A Test
  2. 確認:其中兩組別指標有顯著差異的頻率,不能超過 5%

在繼續解釋這個檢驗的原理前,先請讀者想想看:既然 A/A Test 是兩個一模一樣產品版本的比較,那對於我們任何有興趣的指標(例如點擊率、收入等),在做假設檢定之後,兩版本的指標差異只可能是不顯著;換言之,只要我看到 A/A Test 檢定出現顯著,一定就是系統實驗設定有問題,這樣想正確嗎?

並不是!統計檢定沒辦法做到百分百正確,但是我們可以用顯著水準控制對每次實驗發生錯誤的預期

每次做假設檢定的時候,我們都設定了顯著水準(以下都以 0.05 為例),而 顯著水準 的意義是:

假設虛無假設為真,我們的實驗結果拒絕虛無假設的機率

在 A/A Test 的實驗設計中,兩個產品版本都一樣,也就是已知「虛無假設為真」,我們仍需預期存在 5% 的 Type I Error (偽陽性錯誤)機率、會看到指標有顯著差異;也就是統計工具有 95% 的機率會告訴我們指標差異確實是不顯著。

(如果還不熟悉這個小節提到的顯著水準 5% 與 檢定力 80% 的意思,推薦你參考 這篇文章的圖示案例,快速學習!)

在 A/A Test 進行偽陽性錯誤檢驗的要點是:需要進行多次的 A/A Test!

  • 只做一次 A/A Test 並不足以判斷系統可信度,就算看到顯著差異,也只是來自於本來就有的 5% 偽陽性錯誤發生率
  • 做了多次 A/A Test 之後,如果所有實驗結果中,只有約 5% 的實驗結果 P-value < 0.05,就可以宣告實驗流程正常
  • 反之,做了多次 A/A Test 之後,如果所有實驗結果中,發生 P-value < 0.05 的次數遠超過 5%,那就代表實驗方法或系統出了問題!
比較 A/A Test 與 A/B Test 的 P-value 分佈(Source: 好豪的 GitHub – Python3 實作程式碼

由上圖的實驗,好豪也希望分享給讀者用 A/A Test 來理解 P-value 的另一種觀點:在假設檢定的實驗框架下,如果造成指標差異的效果事實上並不存在,P-value 將會是均勻分佈

  • P-value 為 0.00 ~ 0.05 的機率是 5%
  • P-value 為 0.05 ~ 0.10 的機率也是 5%
  • P-value 為 0.10 ~ 0.15 的機率也是 5%
  • 以此類推

反之,若指標差異確實存在,P-value < 0.05 的機率就是我們假設的檢定力(Statistical Power),這會取決於我們實驗開始前設定的樣本數、顯著水準、期望效果差異大小等等。此外,若指標差異確實存在,P-value 大多會遠小於 0.05、集中分佈在更靠近 0 的數值,為了解決 A/B Testing 多重檢定問題而設計的 Bonferroni 校正,就是運用了這項 P-Value 分佈特性,有興趣的讀者可以閱讀我的 多重檢定介紹文章

至於在 A/A Test 下,P-value < 0.05 發生頻率異常的原因,Ron Kohavi 在他的書中提出常見的幾種:樣本之間並非獨立而造成變異數低估、A/A Test 不是真的兩版本完全相同等等。


結語

沒什麼論文討論 A/A Test,因為它通常單純是個 Bug,但在實務上,這個 Bug 會是巨大的實驗偏誤來源!
因此,A/A Test 是建立可信實驗系統的必要步驟。

資料科學家 Ron Kohavi

A/A Test 檢測的內容簡單、直覺、使我們總是誤以為實驗系統理所當然沒問題,但是,只要你是經手過 A/B Test 實踐的資料科學家,會發現這些簡單的錯誤,在實務上比我們想像的更常發生。

A/A Test 當然還有其他值得檢驗的項目,這篇筆記希望讓讀者至少記得在 A/A Test 先做到這兩件事:

  1. 檢查分組的樣本數是否符合預期的比例
  2. 進行多次 A/A Test,檢查指標呈現顯著差異的頻率,是否與設定的顯著水準不同

最佳的做法,是在 A/B Test 開始前,儘早分配流量執行 A/A Test,就可以早些發現問題,處理可能的隨機流量分配 Bug、或者統計方法假設錯誤,否則,等到做完一堆 A/B Test 才發現系統問題、決策結論全都不可信,這時才後悔就來不及囉。

這篇文章相關實驗的 Python 程式碼,都放在 我的 GitHub,分享給讀者們玩玩看。


參考資料:


如果你對 A/B Testing 有興趣,相信你會喜歡我的 A/B Testing 系列文章

未來我也會持續撰寫我學習與實作 A/B Testing 的心得、也分享更多資料科學知識,有興趣的讀者歡迎追蹤 好豪的粉絲專頁

推薦閱讀