Np-Urのデータ分析教室

オーブンソースデータなどWeb上から入手できるデータを用いて、RとPython両方使って分析した結果を書いていきます

【傾向スコア-後編】犠牲バントの「本当の効果」を分析するための傾向スコア使い方

本記事は下の記事の続きとなります。まだご覧になっていない方は、是非お読みください!
www.randpy.tokyo

前編では、現実世界のデータから施策の評価をしたいときに、よく起こる問題点について述べました。
そしてその問題点を解決する手法の一つが傾向スコアです。

傾向スコアの理論的に詳しいところは、こちらの論文を読んでもらうのが良いかと思います。
https://www.niph.go.jp/journal/data/55-3/200655030007.pdf

かなり詳しく書いてありますので、ちゃんと知りたい方はこちらの論文と論文内で紹介されている各論文を読んでもらうのがベストです。
ただやっぱり読むのに時間はかかりますし、ちょい難しいところも含んでいるので前提知識が足りないと厳しい箇所も含んでいます。

そこで本記事では、なるべーーく直観的に理解ができるように説明していきたいと思います。

単純比較の問題点と傾向スコア

前編と一緒で犠牲バントの例をもとに話を進めていきます。

犠牲バントが起こったときのデータと、起きていないときのデータを比べてもあまり意味がないのは、ものすごい端的に言うと、「条件が異なるから」です。
もう少し説明すると、犠牲バントが起こるような場面というのは、

  • 塁に選手がいる
  • 次のバッターが強打者
  • 何が何でも点を入れたい場面

だったりして(他にも様々あると思います)、要するにかなり点が入りやすい状況がすでに整っていることが多くないですか?

その2群の情報(例えばその後に入った得点かどうかなど)を単純に比較しても、良い結果は得られないでしょう。

犠牲バントが発生する確率?

「2群の前提条件が異なって困っているのだったら、同じような条件に揃えてあげればいいじゃない?」
マリーアントワネット様なら言いそうな言葉ですが、このムチャぶりに答えてみましょう。

先ほど犠牲バントが発生するときというのは、そもそも犠牲バントが発生しやすいような前提条件が整っている可能性が高いと書きました。
では犠牲バントが発生する or しないというのは、何によって影響を受けているのか推定できそうですよね?

この「する or しない」、つまり「1 or 0」のデータが何によって影響を受けているのかという推定、これどっかで見たことありませんか?

そうです!ロジスティック回帰です!以前にRとPythonで実践記事を書きました。
www.randpy.tokyo
www.randpy.tokyo

このロジスティック回帰を使えば、犠牲バントが起こったかどうか(1 or 0)を目的変数、状況(塁に人はいるか、何回何アウトか、次のバッターの打率、などなど)を説明変数にして、どんな状況であればどのくらいの確率で犠牲バントが起こるか推定することができますね。

この「そもそも施策が行われるかどうか」を表す確率を傾向スコアと呼びます。施策が行われそうかの傾向を表す指標なので、傾向スコアというわけです。ちなみに英語では、Propensity Scoreと呼びます。

推定が行われると、例えば

  • 傾向スコア(犠牲バントが発生する確率)が30%の場面で、犠牲バントが行われた
  • 傾向スコア(犠牲バントが発生する確率)が30%の場面で、犠牲バントが行われなかった

のようなデータを得ることができます。

すると、「傾向スコアが同程度」 = 「施策が行われるような前提条件が同程度」
→ 「同程度の傾向スコアを持つ2群のデータ(得点が入ったかどうかなど)は、値を比較することができる」

と考えられます。これが傾向スコアの基本的な考え方となります。
もう一度まとめると、

  1. 傾向スコア(施策が行われる確率)を求める
  2. 傾向スコアで条件づけてあげて、そのうえで値を比較する

ということになります。

傾向スコアで条件付け → 比較することができる

このあたりは前述した論文中の【Strongly Ignorable Treatment Assignmen】あたりで詳しく書いてありますので、時間がある方はご覧ください。

傾向スコアによる調整法

先程は2群(犠牲バントが発生したときと、しなかったとき)から、同程度の傾向スコアを持つデータを持ってきて比較する、と書きました。
実はこれは傾向スコアを使ったデータの調整方法の中の、「傾向スコアマッチング」という手法で、他にも傾向スコアによる調整方法は提案されています。

よく聞くところでは、

  • 傾向スコアマッチング
  • 共分散分析へ応用
  • 層別解析
  • 傾向スコアによる重み付け推定法

などがあります。

傾向スコアマッチングは、2群からなるべく同じ傾向スコアを持つデータを持ってきますが、2群のデータのサイズに偏りがある場合に少ないほうに引っ張られるという欠点があります。
犠牲バントの例がそうです。プロ野球の全打席からしたら、犠牲バントが発生するのは1割ぐらいでしょうか?

例えば1万打席のデータがあったとすると、

  • 1000件の犠牲バントが発生したデータ
  • 9000件の犠牲バントが発生しなかったデータ

を比べることになります。

このとき、それぞれから同程度の傾向スコアを持つデータ同士を持ってきて比較をしていくので、犠牲バントが発生しなかった方のデータのうち、9000 - 1000 = 8000 件は使われません。

そんなときは上記のうち他の手法を試してみる、という必要があるかもしれません。

傾向スコアマッチング以外の調整法

層別解析

層別解析とは、各群で傾向スコアが近い被験者でいくつかのグループを作り、それぞれのグループで値を比較(\(E(y_1) - E(y_0)\)を計算)する方法です。

ただし、何グループに分けるのが適切なのかという問いに対する良い答えは無く、実験者が恣意的に決定することにることになります。一応5グループに分けると良い推定になりやすいという情報を見たことがありますが、ちょっと理論的な説明は難しいようです。

共分散分析

これはそのままですが、得られた傾向スコアを共変量として、共分散分析にかける方法です*1

ただし、共分散分析では説明変数と被説明変数に線形を仮定しているのですが、傾向スコアは必ず\(0\)から\(1\)の範囲に含まれるため、適さないと指摘されています。

傾向スコアによる重み付け推定法

これはちょっと複雑なのですが、アイデアとしては傾向スコアの逆数で、比較したい値(犠牲バントの例では得点など)を重み付けして各群の期待値として加算していく手法です。

一応式を書くと以下のようになります。
\begin{eqnarray*}
E(y_1) &=& \frac{1}{N}\sum_{i=1}^N \frac{z_iy_i}{e_i} \\
E(y_0) &=& \frac{1}{N}\sum_{i=1}^N \frac{(1-z_i)y_i}{(1-e_i)} \\
\end{eqnarray*}

このような重みづけをしてあげることで、施策の行われやすさというバイアスを取り除くことができます。各群から取り出してマッチングするのではなく、\(E(y_1)\)や\(E(y_0)\)を直接計算したうえで、2群間の差の評価をするという意味で、わかり易さがあります。

まとめ

前編後編にわたって、得られたデータの偏りを補正するための傾向スコアという手法について書いてきました。

傾向スコアの適用範囲は幅広く、

  • 犠牲バントの効果の推定
  • 学校選択制の導入が不動産価格へ与える影響の推定
  • 妊婦の冷え性と早産の関係性
  • 冠動脈疾患患者へのアスピリンの有用性

などなど応用例があります。

また今回2群への利用方法として紹介しましたが、実際に多群への研究も進んでいて、2群でなくても傾向スコアを用いることができることが証明されています。

なお、傾向スコアを求める手法としては、ロジスティックス回帰が一般的ですが、ニューラルネットワークやノンパラメトリック推定を用いることもあるようです(調べたらちょくちょくありました)。

他にもこのようなデータのバイアスを取り除く手法はありますが、傾向スコアは個人的にとても面白い手法だと思っています。
是非参考にして実践してみてください!そして深掘りしたくなったら、最初にあげた論文や以下の書籍を読んでみてください!

調査観察データの統計科学―因果推論・選択バイアス・データ融合 (シリーズ確率と情報の科学)

調査観察データの統計科学―因果推論・選択バイアス・データ融合 (シリーズ確率と情報の科学)

統計的因果推論―回帰分析の新しい枠組み (シリーズ・予測と発見の科学)

統計的因果推論―回帰分析の新しい枠組み (シリーズ・予測と発見の科学)

追記

傾向スコアをRとPythonから実践してみましたので、そちらも是非ご覧ください。
www.randpy.tokyo
www.randpy.tokyo

*1:共変量や共分散分析については、こちらをご覧ください。いずれ本ブログでも解説してみます