こんにちは。LINEヤフー株式会社の牧山です。
私は現在データ分析の部署で働いており、自社サービスのデータ分析をしたり、自分の体重データを眺めては「減らないな……」と思ったりしています。
このような本来の業務とは別に、当社の分析部門には、好きなテーマで自由研究に取り組める時間があります。Google の「20%ルール」に近い制度ですが、特徴は自由研究をサポートする専門のチームが存在することです。
このチームは、「新しい論文の手法を試してみたい」というような自由研究のテーマを思いついたときに、手法を適用できそうな社内データを探してくれたり、データを持っていそうな関係部署を紹介してくれたり、論文を一緒に読んで理解を深めてくれたりと、非常に頼れる人たちです。
このチームに関しては別記事をご覧ください: "成長を自己責任にしない"分析組織の実現に向けた取り組み
この記事では、そんなサポートを受けて自由研究として開発した R パッケージ deltatest を紹介します。
WebサービスのA/Bテストにおける統計的仮説検定の落とし穴
LINEヤフーではサービス改善のために、日常的に A/B テストを実施しています。
UI のボタン配置のちょっとした変更から、レコメンドアルゴリズムの刷新にいたるまで、様々な変更に対して、ユーザーを2つのグループ(従来版を提示する A グループと変更版を提示する B グループ)に振り分けて比較します。AグループとBグループは変更点以外の違いがないため、その変更による純粋な効果を計測することができます。これがA/Bテストです。
A/Bテストにおいて、評価指標(たとえば商品の購入率)に差があるかどうかの判断に使うのが統計的仮説検定です。統計的仮説検定を使うと、本当は差がないのに誤って差があると判断してしまうリスクを制御できます。統計的仮説検定の手法にはいろいろあるのですが、Webサービスのサンプルサイズは十分大きいので、ほとんどの場合に Z検定を使うことができます。
ただし、WebサービスのA/B テストでは、一般にユーザーごとにグループの振り分けを行うのに対し、検定したい評価指標はページビューあたりのクリック率やセッションあたりの購入率などです。この場合、1 人のユーザーが複数のページビューやセッションを生成できるため、データに偏りが生じやすくなります。
例えば、石油王がネットショッピングする時、石油王は大金持ちなので、気に入った商品を見つけたら間違いなく購入するでしょう。購入率100%です。一方、私は片足で乗ると体重が半分になる体重計を探しているが見つけられず、世の中に絶望しています。購入率0%です。
私がAグループに振り分けられ、石油王がBグループに振り分けられると、Bグループが有利になるのは明らかです。しかも、私は暇人なので1時間に100回くらいアクセスします。私がアクセスするたびにAグループの評価が落ちるわけです。迷惑すぎる。
このようなデータに通常の Z検定を適用すると、検定結果が信頼できなくなります。
デルタ法を使った分散推定
Z検定は平均の差に対して分散を計算して標準誤差を求めるというシンプルな手法です。問題は、ユーザーごとに購入率が異なるため、同一ユーザーのデータに相関が生じることです。
通常の分散の計算式はデータが独立であるという前提があるため、この相関を無視すると分散が実際より小さく算出されます。これを「分散の過小推定」と呼びます。私の体重計も過小推定してくれたらいいのですが。
分散が過小推定されると、本当は差がないのに誤って差があると判断してしまうリスクが高くなってしまいます。この分散の過小推定問題に対して、古くから使われている手法がデルタ法です。
A/Bテストの文脈でデルタ 法を統計的仮説検定に使うという記述は、Tang et al. (2010) にすでに見られます。しかし、詳しい説明はされておらず、正式に論文化したのは Deng et al. (2018) のようです。この論文をきっかけに社内でもデルタ法ブームが起こり、A/B テストの標準手法として定着しました。
ところが、この手法は実装が容易なぶん、各部署が毎回「車輪の再発明」をしているのが現状でした。専用パッケージが存在しなかったため、誰かのスクリプトをコピペしたり、独自に書き起こしたりしている状況です。どうせなら、みんなが共通で使えるパッケージを作ろう! ついでに夜中にカップラーメンを食べるのをやめよう!そんな思いから、自由研究の時間を活用して deltatest を開発しました。
deltatest パッケージ
こうしてできたものが、デルタ法を使った統計的仮説検定を行うRパッケージ deltatest です。インストールするには、Rのコンソール上で次を実行します。
install.packages("deltatest")
必要なデータは、各ユーザーについて、
- AとBのどちらのグループに振り分けられたか
- 購入回数
- セッション数
を集計したデータです。
deltatest には、サンプルデータを生成する関数があるので、これを使ってデモデータを生成します。
library(dplyr)
n_user <- 2000L # ユーザ数
set.seed(314)
data <- deltatest::generate_dummy_data(n_user) |>
mutate(group = if_else(group == 0, "A", "B")) |>
group_by(user_id, group) |>
summarise(buy_count = sum(metric), session = n(), .groups = "drop")
head(data)
user_id group buy_count session
1 1 B 1 6
2 2 B 2 11
3 3 A 0 17
4 4 A 4 12
5 5 A 5 10
6 6 A 1 15
このデータに対して、デルタ法を使った統計的仮設検定は次のように実行します。
- 第一引数にデータを指定
- セッションごとの購入率(=購入回数/セッション数)を検定したいので、第二引数に buy_count / session を指定
- by 引数に、ユーザがAとBのどちらのグループに属するかを示すカラム group を指定
library(deltatest)
deltatest(data, buy_count / session, by = group)
Two Sample Z-test Using the Delta Method
data: buy_count/session by group
Z = 0.31437, p-value = 0.7532
alternative hypothesis: true difference in means between control and treatment is not equal to 0
95 percent confidence interval:
-0.01410593 0.01949536
sample estimates:
mean in control mean in treatment difference
0.245959325 0.248654038 0.002694713
このように、たった一行でデルタ法を使った統計的仮設検定が実行できるようになりました。今まで自分で書いていたコードがなくなり、コードがスリム化しますね(私の腹まわりもスリム化したい)。
まとめ
本記事では、LINEヤフーの自由研究制度を活用して開発された R パッケージ deltatest を紹介しました。LINEヤフーでは 、豊富でバラエティ豊かな自社データを分析したいという人を募集しています。
参考リンク
- "成長を自己責任にしない"分析組織の実現に向けた取り組み|LINEヤフー データストーリー 公式note
- Work @ Google 20%
- Overlapping Experiment Infrastructure: More, Better, Faster Experimentation
- Applying the Delta Method in Metric Analytics | Proceedings of the 24th ACM SIGKDD International Conference on Knowledge Discovery & Data Mining
- 統計指標の信頼区間を評価する Delta method とその応用(論文紹介)
- CRAN: Package deltatest