Re:ゼロから始めるML生活

どちらかといえばエミリア派です

「オンラインテスト後の長期的な介入効果」について考える

A/Bテストなどのオンラインテストを行っている事例はネットで探せば沢山見つかります。 ただ、そのオンラインテスト後の介入効果の長期影響について分析については、あまり見かけない気がします。

いざ実務でオンラインテストを行うと、「A/Bテストが良かったのはわかったから、その後継続的に成果出てるの?」と聞かれるとチョット困ってしまいます。 そんなオンラインテスト後の「A/Bテストの介入効果の長期影響」について考えてみたので、メモです。

あくまで「自分がやるならどうすっかな?」というノリで考えてみた、というレベルの話なので、「普通こうするやろwww」みたいなのがもしあったらこっそり教えていただけると嬉しいかもです。

前提

前後比較は基本的に避けるべき

何らかの施策の介入効果を測定しようとするとき、基本的には前後比較は避けるべきです。

理由は、季節性や外部要因によっても評価指標が変動する場合、仮に前後比較によって指標が上昇していたとしても、それが施策の介入効果によるものなのか、季節性や外部要因によるものなのかを見極めることができないからです。 (わかってる人にとっては「何を当たり前のこと言ってんだ」となりそうですが)

そのため、外部要因等の条件をすべて同じにして介入の有無の差分だけがある状態で評価指標にどれだけ影響があるかを測定するために、A/Bテストが行われます。 A/Bテストでは、同一期間に介入群/対照群と2つのグループに分けて介入群にだけ変更を加えるということを行うため、

  • 介入群: 介入を行ったときのテスト期間での評価指標
  • 対照群: 何もしなかったときのテスト期間での評価指標

のそれぞれを確認することで、介入群/対照群の両方に季節性・外部影響が働くため、「介入に効果があったか」だけにフォーカスして確認することができます。

A/Bテストだけでもある程度介入効果を予測することはできる

前提として、A/Bテストで介入効果をある程度予測することはできます。(身もふたもありませんが)

そのときの介入効果を雑に見積もるとするならば、下記のような式のようなのが考えられるかもしれません。

\displaystyle{
metrics_{expect} = metrics_{before} \cdot  (\frac{treatment}{control} )
}

  •  metrics_{expect}: 見積もりの期待値
    • 計算したい期待値(eg. 月間のクリック数、日次の売上、年間の契約金額など)
  •  metrics_{before}: 介入を行う前での指標
  •  treatment: オンラインテスト時の介入群の指標の結果
  •  control: オンラインテスト時の対照群の指標の結果

非常に単純で良いと思う一方、いくつか問題があると思っています。 パッと思いつくのは、

  1. ノベルティ効果が入り込んでいる恐れがある
    • treatment群には少なからずユーザー体験が変化することによって介入効果がポジティブ/ネガティブに関わらず、ユーザーの行動が活性化されているので、そもそもオンラインテストで勝ちやすくなったりします
  2. 他の機能と相乗効果で指標が変化する恐れがある
    • Aという機能に関して介入したとき、ユーザーの行動が機能Bに対して影響を及ぼす恐れがあります。何らかのフィードバックループが発生する場合には、別の機能からの影響が指標に影響を与えるまでにタイムラグが発生したりします
    • 例1:商品購入のためのブックマーク機能を改善
      • 売上はブックマークに対して遅行系列である事が多く、時間をかけて商品購入が増加するかもしれません
    • 例2:SNSでのフォロー機能に介入
      • フォロー・フォロワーの関係が増加してよりCTRの高い広告を推薦できるようになれば広告収益が増加するかもしれません

と考えています。 簡単に見積もりを計算するにはこれくらいで十分だとは思いつつ、可能ならどうにかしたいと考えています。

とはいえ、オンラインテストの結果を過信するのは不安

下みたいな状況、意外とあるんじゃないでしょうか?

オンラインテストでtreatmentの結果良かったんでしょ?じゃあ、テスト期間以外でもよくなってるはずだよね?今後の施策での介入効果の参考値に経営会議で使いたいからその後どれくらい上がったか教えてよ。よろしく!

経営会議とか重要そうなワードが飛び出ると、ちゃんと値計算できてるか不安になったりしませんか? そうじゃなくても、オンラインテストの結果だけを使用して、その後の施策を考えるなどの意思決定をするのはちょっと不安になりそうです。

上のような問題が頭にちらつくと、オンラインテスト時の結果ではなく、オンラインテスト後の結果から再度介入効果を確認したくなりませんか? (え、ならない?そこは無理やり思っていただいて…)

ってことで、「基本的には」前後比較は避けるべきですが、今回はオンラインテスト前後の値を使って、介入効果がどれくらい出たのかを確認できるか考えてみたいと思います。

オンラインテスト後の長期的な介入効果

さて、なぜ「オンラインテスト後の長期的な介入効果」を見たいかわかったところで、実際にどうやるかを考えてみたいと思います。

考え方

いま、なんらかの新しい機能開発や改善を行い、そのオンラインテストを実施したとします。 そのとき、オンラインテストの評価指標が下記のように推移したとします。

さて、今知りたいことは「オンラインテスト後の施策の長期的な介入効果」でした。 (ある施策を行ったことで、オンラインテスト後にどれだけ効果が出たかが知りたい)

ぱっと思いつくやり方としては、

  • オンラインテスト前後での単純比較
  • 時系列モデリングによるシミュレーション

らへんでしょうか。それぞれやってみたいと思います。

単純な前後比較

雑にやるなら前後比較で良さそうです。

ただこのやり方は、評価指標に季節性がある場合その影響を考慮できません。 なので、雑にやるならこれでいいとは思いつつ、あまり信用ができない感じがしてきます。

時系列予測との比較

「オンラインテスト後の施策の長期的な介入効果」を知るために、もしも施策を行っていなかったときの予測値がわかれば、その値と実際の値の差分を見れば、それは施策の介入効果と考えられそうです。

時系列データについては、時系列モデリングによって、

  • trend
  • seasonality

の影響を考慮して未来の値をある程度推定することができます。

もちろん、外部要因や別の施策によって指標の値はぶれます。 ただ、何もしないよりは幾分マシになりそうなのは想像に難く無いと思いますし、季節性やトレンドの影響がある程度大きいことがわかっている場合には時系列モデリングによって予測することはそれほど筋が悪いことではないように思います。

また、時系列モデリングにある程度・労力を払って、指標の推移を正確に予測できるモデルを作れば、それだけ効果の見積もりを正確に測定ができるとも考えられます。 そのため、このへんは頑張り次第でどうにかなる余地もありそうです。

疑似データを作ってやってみる

データセット作り

まずは前回やった疑似データ作りを参考に、今回用のデータセットを作ってみたいと思います。

データを作成するに当たって、状況を考えたいと思います。

  • もともとの指標にはトレンドと季節性がある
  • その指標に対して効果のあるオンラインテストを実施した
    • 今回は、2019年6月にA/Bテストを実施したものとする
    • オンラインテストはA/Bテストとし、分割はアクティブなユーザーのちょうど半分にした
  • その後、その変更を全体に対してリリースした
    • オンラインテスト時にcontrol群だったユーザーが全体リリースのタイミングで介入されるようになった
    • 今回は、2019年7月にA/Bテストを終了し、全体リリースしたものとする

上のような状況をイメージして疑似データを作成します。 使用したコードはこの記事の最後に貼り付けるとして、データを確認してみます。

こんな感じの時系列データを想定します。

trend, seasonalityに分解するとこんな感じ。

これを使って前後比較がどれだけ難しいか見てみます。

前後比較

まず単純にオンラインテストの前後の値だけで比較するとどうなるか確認します。

年月 指標
2020年5月 2.49388865390346
2020年7月 9.95690365243194

なので、

介入効果(= 実測値 - 予測値) = 7.46301499852848

と算出されており、実際の介入効果(=2)と離れてしまいました。

時系列予測との比較

今度はオンラインテストを行う直前までのデータを使用して、状態空間モデルを使って介入を行わなかった場合の指標をモデリングし、その未来予測値と介入した後の実測値を比較します。 状態空間モデルの使用にはこちらの記事を参考に記述しました。

結果は下記のようになりました。

赤線が予測値、青線が実測値を表しています。 なんとなく介入効果がなかった場合をちゃんと予測できてそうに見えます。

実際の値も確認してみます。

年月 指標
2020年7月(実測値) 9.95690365243194
2020年7月(予測値) 8.25274713813861

ここから、

介入効果(= 実測値 - 予測値) = 1.70415651429333

と算出されており、前後比較よりはまともな介入効果を推定することができました。 また、このデータにはノイズとして標準偏差0.2のノイズを乗せているので、なんとなくですが、それっぽい推定になってそうです。

使用したコード

使用したコードはこちらになります。(データ生成にランダム要素が多分に入っているので、やるたびに結果が変わるとは思いますが)

参考文献

この記事を書くに当たって下記の文献を参考にさせていただきました。

感想

ということで、もしも「オンラインテスト後の長期的な介入効果」を推定することになったらどうするか、ということをかんがえてみました。 最終的にはそれっぽい値が出たんですが、他にいいやり方があったら教えてほしいなーって気持ちです。

また、今回はモデルの当てはまりとかは特に考えず、適当にモデルの式に当てはめてしまいましたが、実際にはちゃんとモデリングの当てはまりの良さも評価しなきゃなーとか思いました。 実際には、こんなにきれいな波形をしていない(その他いろいろな影響が合算して指標に現れる)ので、ちゃんと当てはまりを見ないとこれまた変な値を見積もってしまいそうです。

こういうの考え始めると、何らかの指標をそこそこ正確に見積もれる時系列モデルって大事ですね。 時系列モデリング自体1年ぶりくらい、R書いたのが2〜3年ぶりくらいで色々久しぶりでした。 思い出すのが辛かったです。 面白かったので良しとします。