# Controlled Experiments on the Web: Survey and Practical Guide ## 1 Introduction ABテストのはじまり 18世紀にイギリスの海軍で壊血病を防ぐための実験 ライムありの食事となしの食事→なしのほうが罹患率低い 知識がなくても観察からできた実験 OCEはROIに直結する Webサービスはアイデアを手早く試すのに最適 Control:施策なし、現状 Treatment:施策あり、改善後 OLAPなどのマニュアル/機械学習/データマイニングを使ったユーザのセグメント分析によってどの層に効いているかわかる OCEは因果関係をテストするので信頼度高い(←→事後解析、中断時系列分析) ## 2 Motivating Examples ### 2.1 Checkout page at Doctor FootCare クーポンコード入力欄を設けることで損をしているのではないかとユーザが不安になり、収入が90%減った ### 2.2 Ratings of MS Office help articles 星5つの1段階の評価よりも2段階の評価(2択+理由)のほうがレスポンス率が上がった 説明付き星5つ+2段階評価のほうが星5つ+2段階より良い 説明付きのシンプルな評価(これは国民性にもよる気がするけど)+理由がいい →結局説明付き3択+理由に落ち着いた ### 2.3 MDN home page ads 広告は基本的にUX下げるけど、収入は増やす この、収入とUXをどう比較するか PVとクリック数をKPIにした この例よくわからなかった、広告についての知識が不足しているからか? 検索エンジンに課金して外部からユーザを誘引する(?)あとで調べよ ### 2.4 Behavior-Based Search at Amazon BBS:アイテムXを買った・見た人はアイテムYを買う・見る BBSはクエリを全く考慮しないことが特徴 BBSというかCFのことだな 「24」というクエリを投げると別に昭和の名曲24選24インチの何かとかを探しているわけじゃなくてテレビのタイトルらしい セブンとかだな でもこのCFにも弱点があって、ユーザのクエリの意図を読み取れない 例えば「ソニー DVDプレーヤー」を検索したのに東芝出てきたら怒るでしょ 固有名詞入ってるならその固有名詞しか出して欲しくないはず →OCEした 結局BBSがよかったんかな?収益3%のびた ## 3 Controlled experiments 無作為抽出がポイント データを集めたあと、OECを求める 対象実験ならOECの違いはABテストからのみ得られるものだと言える ### 3.1 Terminology 頻出用語 OEC Over Evaluation Criterion: 実験の目的を測る定量評価 統計学でいうResponse of Dependent Variable いわゆる結果? クリック数のような短期的な指標でなくリピーター数のような長期的な指標が良い Factor, Variables 変数、要因、ABテストならAとB Variant 変数部分に与えられるUXのこと(ここでは) Variant. A user experience being tested by assigning levels to the factors; it is either the Control or one of the Treatments. Sometimes referred to as Treatment, although we prefer to specifically differentiate between the Control, which is a special variant that designates the existing version being compared against and the new Treatments being tried. In case of a bug, for example, the experiment is aborted and all users should see the Control variant. え、variantてなんだ、変数とは違うの Experimental Unit 実験の対象、Webサービスなら普通はユーザ(同じユーザでも1日ごと、セッションごとに分けられることもある) Unit同士は独立に動く→だから無作為に抽出するのかな Webサービスの場合はクッキーに保存されたIDから無作為抽出 無作為抽出が不適切な場合もある(付録参照) Null Hypothesis 帰無仮説 Confidence level 信頼度 帰無仮説が否定される境界になる確率 Power 帰無仮説が偽であるときに否定することができる確率 有意な差があるときにそれを検知できる能力を測る A/A Test, Null Test AB テストした後に良かった方同士で同じ結果が出ることを(他の要因で結果が出ていないことを)検証する 1. データを集めてpowerを計算したときのばらつきを検定する 2. 実験システムの正しさ(?)を調べる ### 3.2 Hypothesis testing and sample size factorsの検定において重要な項目 1. Confidence level 信頼度を95%に設定するということは、**5%の確率で、有意差がないのにあると結論づけてしまうということ。** Confidence levelをあげるとPowerが下がる。 2. Power 別に設定できるわけではないけど、80-95%が望ましい。Powerが80%であるということは、**OECに差が見られて帰無仮説が偽のとき、80%の確率でその差が有意であると決めるということ。** 3. Standard Error 標準誤差が小さいほどその検定が有効である。標準誤差を減らす方法↓ - OECはサンプルの平均から求める。母集団から抽出されたサンプルから平均を求める場合、平均の値が母平均に対してどの程度ばらついているかを表す。なので、実験を長くやるとサンプルを多く得られるのでSEを減らせる。 - 実験の対象になっている変更部分に触らなかったユーザを除外することでOECのばらつきを減らす。 4. Effect AとBのOECにおける違い Factorが1つの場合→t検定 中心極限定理 平均\mu、分散\sigma^2に従う母集団からサンプルサイズnの標本を抽出するとき、平均の分布はnが大きくなるにつれて正規分布に近づく Confidence level 95%/Power 80%を満たす最小限のサンプル数は n=\frac{16\sigma^2}{\delta^2} nはABそれぞれのサンプル数、\sigma^2はOECの分散、\deltaはsensitivity(感度、真陽性率:例えば検査の有効性を調べるなら、実際にその病気に罹患している人のなかで検査で陽性になった人の割合のことだけどWebだと何にあたるんだ) **Treatmentのサンプル数を不当に増やすと検査の話なら実際に病気だった人が1増えるだけで感度の上がり幅が大きくなって帰無仮説否定しやすくなるので同じサンプル数にすること!** 80%なら16、90%なら21に係数変えるらしい。 1つのFactorにvariantが3以上?複数になった場合に使えるもう一つの公式(これ何検定?) A-1A-2Bテストみたいになったときってことか??? n=(\frac{4r\sigma}{\delta})^2 rはvariantの数 #### 3.2.1 サンプルサイズがOECのばらつきに与える影響 CVR5%、購入者の購入額平均$75、全体平均$3.75→標準偏差$30 AB tesutoして収益を5%変化させようと思うと 16 * (0.05 * (1 − 0.05))/(0.05 * 0.05)^2より409000人のサンプルが必要(Power80%の場合) 今度はCVRを5%変化させようとすると、 - 実験の対象になっている変更部分に触らなかったユーザを除外することでOECのばらつきを減らす。 よりOECのばらつきは小さくなる。購入というCVイベントはベルヌーイ試行(CVする・しない)なので標準偏差は\sqrt{p(1-p)} 16 * (0.05 * (1 − 0.05))/(0.05 * 0.05)^2 より122000人のサンプルが必要。 収益ではなくてCVRにした方がサンプル数は少なくて済む。ユーザ数は線形に増えるものなのでそうなるとより実験期間も短縮できる。 #### 3.2.2 感度の低下がサンプルサイズに与える影響 感度はサンプルサイズの平方根なので CVを20%変化させようとすると5%の変化のときに比べて必要なユーザ数が16から7600になる。 →実験中にバグを検知するときに役立つ。 OECを1%変化させる実験をしていたとして、バグのせいでOECが20%悪化したとする。そういうバグは実験期間の1/400が経過したところで検知することができる。2週間なら最初の1時間で気づけることができる。 #### 3.2.3 ABテストの影響を受けないユーザを除外する 購入プロセスにおけるAB テストをするなら、購入画面に至ったユーザだけを分析すべきである。CVRが0.5で標準偏差が0.5なら 16 * (0.5* (1 − 0.5))/(0.5 * 0.05)^2 より必要なユーザ数は購入画面に至った6400人だけ。 #### 3.2.4 OECは実験まえに決める ### 3.3 信頼区間 #### 3.3.1 absolute effect を測るための信頼区間 t検定でよく見るやつ ### 3.3.2 percent effect を測るための信頼区間 AB間の違いが小さいときに、何パーセント変化したかのほうがabsolute differenceよりも直感的に理解できることがある。 例えば、CTRが0.00014しか違わないということは、12.85%の変化と言い換えることができる。でもこれだとランダム変数(O_Aのこと?)で割ることになるので信頼区間を直接求めることはできない。 分母が漸近的に0に近い場合信頼区間の両端は存在しない。 変動係数を、標準偏差を平均値で割って求めて、 ![](https://i.imgur.com/wGKDCXJ.png) から求める。無作為抽出ならAB間の共分散は0になるはず。 **ここ要復習** ### 3.4 botの影響 AAテストで差異が出るのでわかるらしい。 外れ値的な動きをするとPowerが下がるので悪質。 対策法↓ - Factor部分?Treatment部分?をJSで呼び出す - Cookieを拒否するリクエストを除く。CookieからユーザIDを取る。 ### 3.5 その他のTips - 最初Control/Treatmentの比を99.9:0.1くらいにして、バグがないか確認しながら増やしていく - 収益の最大化が目的なら、一定のOECを超えたところでTreatmentを増やしていくバンディットアルゴリズムとかHoeffding Racesのようなアプローチをとるのも良い - 逆にDBマイグレーションするときにもAB テストが使える。UXが何も変わらないことを旧バージョンと新バージョンで比較する ### Limitations - 説明的ではない。ABどっちがどのくらいいいかはわかるけれどなぜかまではわからない。仮説検証として使うなら良さそう。 - 長期的な目標を包含できていないかも。例えば、広告を増やす実験をするとして、UXを下げる代わりにクリックされない広告にはペナルティを課すとか、リピート率をOECにするとか。Latent CVを意識しよう。これが理由でABテストやらない理由にはならない。 - ご祝儀効果←→使い慣れたユーザにとってはなんでも最初は使いにくいと不評。Hawthorne effect。新規のユーザのみを実験対象にするのもいいかも。 - ちゃんと実装してから実験しよう。簡単なプロトタイプが有効なのは定性評価においてであって定量評価ではx。 - Launch Events and Media Announcements.ユーザが知ってたらABテストの意味ない。 ## 4 Multivariable Testing 1カ所以上の変更点(Factor)がある実験をMTV Multi Variable Testingといいます。 Factorそれぞれの影響だけでなく相互作用も見る。 MVT vs. 連続ABテスト pros 1. MTVのほうがたくさんのfactorを短期間で検証するkと尾ができる。 2. 相互作用を検証することができる(大杉さんのスライド) 。 cons 1. 組み合わせによってはUXが下がる。オフライン検証の時点でUXが下がるようなパターンは排除すべき。 2. 分析と結果の解釈が難しい。 3. 同時に試したいならどれか1つの準備に支障が出たとき時間がかかる。 ### 4.1 Traditional MVT fractional factorial design:一部要因実施計画、全通りはできないから直交表に則って同じ回数だけ実験できるようにする。 Plackett-Burman計画法ではAとBを比較するのでユーザグループの数は4の倍数になる。 FFDだと5つの主要な(主要なとは?単体の作用ということか?)作用を見られるけど交互作用は見られない。交互作用は主要な作用や他の交互作用と交絡してしまう。 結論FFDはオフラインテストに留めて4.2と4.3のいずれかを使うのがおすすめ↓ ### 4.2 Concurrent MVT factorごとに単体のABテストを同時に(同じ期間で)走らせれば簡単に全通りの結果を得られる。 1つのfactorが2以上になるとサンプル数が減るので実験のPowerが低くなる。 Controlと同数のサンプルサイズを確保することが重要。 ### 4.3 ABテストを単体で行う。他のfactorが実装終わるのをを待たない。 大きな交互作用は実はあまりない。2つのfactorに関する検証でオーバーラップする部分(部分というのはOECのばらつきのことかな?)があれば交互作用を見てみるという感じ。 結論、手早く検証を終わらせたい&交互作用がないと考えるなら4.3、交互作用をしっかりみるなら、ユーザを独立に無作為に抽出してテストを同時に走らせて全ての組み合わせについて検証を行う。 ## 5 Inplementation Architecture ### 5.1 Randomizeaation Algorith ランダムアルゴリズムが満たすべき性質5つ 1. 50ー50になること 2. 実験期間を通して同一ユーザは一貫したvariantを割り振られること 3. 実験同士が相関しない あと2つはオプション 4. ramp-upは単調に、少しずつ増やす 5. ユーザに割り当てられたvariantを実験者が変えられるようにする 以後手法の紹介 #### 5.1.1 キャッシュを用いた擬似乱数 1と3を満たすサーバーサイドを1度だけ参照しているならOK、リクエストごとだと前後で同じシードを使う可能性がある。例えば、Visual Basicで実験間で相関が生まれる2元交互作用(?英語わからん)(Eric Peterson, 05) 2を満たすためにはDBに割り当てを登録する方法(リソースに限りがあるので非現実的しかし5も同時に満たせる)とCookieで保持する方法とある。 #### 5.1.2 Hash and partition 擬似乱数生成の代わりにハッシュ関数を使う。 ユーザIDと実験のIDを結合した値(例えばね)をハッシュ関数に入れて連続一様分布になる値を得る。分布のなかでvariantごとに区切ってどの variantか割り当てる。 どのハッシュ関数を選ぶかが重要。隣接したキーが同じ値を得ると連続一様分布にならない。ハッシュ値を予測できると実験間で相関が現れてしまう。 時間がかかるのが欠点。部分的にキャッシュをとるとユーザが異なる実験でも同じハッシュ→同じ割り当てを得ることがある。実験間で相関が現れるので3が満たせない。 5は満たせない。 ### 5.2 Assignment method #### 5.2.1 Traffic splitting fleetてのはサーバのことか?logical fleetとはなんぞ? ![](https://i.imgur.com/k4HHHhi.png) ロードバランサーもしくはプロキシサーバで割り振りをして、variantごとに別サーバに送る。 コードを変更しなくて良い。 欠点↓ - リクエストより細かい粒度の実験は無理 - ABで捌くリクエストの数が違う、実験が終わったらControlで100%捌くスペックが必要なのでコストかかる。 - 複数ABテスト走らせるとコストかかる。 - サーバが結果に影響を与えているかもしれないので、ハードウェアとネットワークトポロジーを一位に定めてAAテストでサーバ関連の特徴がないか検証すべき お金はかかるがエンジニアの工数が減るのが特徴。コードを大幅改修したときのAB テスト以外は使わないほうが良さそう。 #### 5.2.2 Page rewriting ![](https://i.imgur.com/FxsEGuv.png) サーバから返ってきたHTMLをユーザに渡す前にプロキシサーバで変更する。そういう特殊なプロキシサーバがあるらしい。 欠点↓ - ページをレンダリングする気パンが長くなりパフォーマンスが落ちる。 - プロキシサーバが潜在的なトラフィックを全て捌かなければならなくなるので(?)障害点になるかもしれない。リクエストもレスポンスもプロキシサーバを経由するから負荷が大きいということ? - エラーを起こしやすい。variantごとにHTMLを用意するというよりはルールの集まりを適用するという感じ?具体例がないとよくわからないな - レンダリングした後にvariantを割り振るのでバックエンドのアルゴリズムに関する実験には適さない。例えば検索アルゴリズムとか。 - 暗号化された通信には適さない。 #### 5.2.3 Client-side assignment ![](https://i.imgur.com/vIe3IdO.png) サードパーティのプラットフォームで最もよく使われる方法。 Google Website Optimizer (2008), Omniture’s Offermatica (Omniture 2008), Interwoven’s Optimost (2008), Widemile (2008), and Verster (2008)などなど挙げられているけどどれも知らない。 JSのコードを埋め込んでレンダリングするときに割り当てる。ユーザにページを表示する前に割り当てに従ってDOMを変更する。 ## 6 Lessons learned ### 6.1 Analysis #### 6.1.1 Mine the data ブラウザの種類によってはJSがバグってTreatmentが上手く発動しないことがある。 真野氏の見解↓ https://developer.mozilla.org/ja/docs/Web/API/Navigator/sendBeacon ``` リクエスト送信方法がxhrとfetchとbeaconがあって、そこらへんの対応状況とか仕様がブラウザ間で異なることから、ユーザーの使っているブラウザごとに取得できたデータが異なってきてしまったり、パフォーマンスに影響が出てしまった、みたいな話かと ``` #### 6.1.2 Speed matters レスポンスタイムがOECに含まれていないならなおさらレスポンスタイム遅くなってないか確認すること。 #### 6.1.3 Test one factor at a time 交互作用は思ったほどないから単体のABテストをたくさんするほうがいい。交互作用があるとわかったら全ての組み合わせを検証すればいい。 ### 6.2 Trust and execution #### 6.2.1 Run continuous AA test ユーザが計画通りに割り振られているか、集められたデータがシステムのレコードと合致しているか、結果に有意な差がないか、確認する。 #### 6.2.2 Automate ramp-up and abort 暫定のOECがよければ少しずつ増やして、著しく悪ければ実験を中断する。 #### 6.2.3 Determine the minimum sample size 実験前に(?)AAテストをしてみてどれくらいの変化を検知したいのか、OECのばらつきを推測する。 Powerが80%に満たない実験は失敗する(?)失敗するとはどういうことだろう Powerを高めるTipsを実践してサンプル数を決める。 #### 6.2.4 Assign 50% of usero treatment ramp-upするにしても最終的には50-50にしよう #### 6.2.5 Beware of day of week effect 基本的にどんなサービスも曜日の影響があるので1週間は実験しよう。 コロナで在宅勤務になったら人々の週間もデータレベルで変わってるのか気になるな。 ### 6.3 Culture and business #### 6.3.1 Agree on the OEC upfront 実験の前にOECの軸を決めておく。多くの場合LTVを増やす方向らしい。 Lifetime valueを完全に勘違いしていた。企業と顧客が継続的に取引をすることによって、顧客が企業にもたらす利益のことらしい。だから新しいユーザのアクションのほうが既存のユーザのアクションよりもありがたい(この表現は微妙だな) #### 6.3.2 Beware of launching features that do not hurt users 違いがなかったのは本当にABで違いがなかっただけなのか実験がPowerが不足していて差を検出できなかっただけかもしれないことに注意しよう。もしかしたら悪い結果が出ていたかもしれない。 しかしこのセクションのタイトルがなぜ”Does not hurt anything”七日はよくわからない。 #### 6.3.3 Weigh the feature maintenance costs 運用が面倒なのにOECがちょっとあがるだけならやらない。メンテナンスコストも考慮しよう。ほんまに。 #### 6.3.4 Change to a data-driven culture