Np-Urのデータ分析教室

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

【傾向スコア-前編】現実のデータを扱う上での問題点とその対策について

突然ですが、施策の効果をきちんと測定することは、実はとても難しいのです。

ここでいう施策の効果とは、例えばあるクラスの生徒への特別な教育の効果であったり、ある病気にかかった人々への薬の処方の効果であったり、プロ野球のある場面で犠牲バントを行う効果だったり...のことを指しています。

どうして難しいのか?そしてその困難をどのようにして回避するのか?
次の章から説明していきます。

RCTと傾向スコア

どうしてこれらの効果を測定することが難しいのか、犠牲バントの例をもう少し掘り下げてながら考えてみましょう。
プロ野球の試合のデータから、得られるものは

  • 犠牲バントが発生した時のデータ(その後実際に得点が入ったかなど)
  • 犠牲バントが発生していない時のデータ(その後実際に得点が入ったかなど)

しかありません。
この2つのデータを比較して、「犠牲バントをしたときの方が得点が入ることが分かった!」→ 「じゃあ犠牲バントをする方がいい!」と考えるのは早計です。

なぜなら、犠牲バントが行われる場面というのは、すでに得点が入りやすいチャンスな状況であるかもしれないからです。犠牲バントが発生するときと発生しないときでは、試合状況に大きく差があります。そんな状態を比べても、良い推論ができるとは思えないですよね。

よって本当の犠牲バントの効果を確認したかったら、犠牲バントが発生した場面で実際に犠牲バントが行われたデータと、犠牲バントが発生した場面で犠牲バントを行わなかったデータを比較する必要があります。
(ちょっと不思議なことを言っていますが、ついてきてください笑)

犠牲バントが発生した場面 犠牲バントが発生していない場面
犠牲バントを行う
犠牲バントを行わない

表を書いてみると、取得可能なデータは①と④のみですが、犠牲バントの真の効果を確認するには、①と③、もしくは②と④を比較する必要があります。

しかし、これって不可能ですよね?

犠牲バントが発生した場面で犠牲バントを行わないデータ(③)というのは取得できませんし、同様に犠牲バントが発生していない場面で犠牲バントを行ったデータ(②)を取得することはできません。

「うーん困ったなー…」
という時に活躍するのが「傾向スコア」という手法です。

この傾向スコアを用いることで、現実には取得できなかった、②や③のデータを仮想的に手にすることができるようになります!

RCT(Randomized controlled trials)

なお、このような施策の効果を見るのに最も有効なとされているのが、RCT(Randomized controlled trials)という手法です。十分に大きなサンプルサイズでランダムに対象者を複数のグループに振り分けることで、グループ間の差(処置の効果)を比較するというものです。

例えばWeb業界でよく使われるA/Bテストなどは、ランダムにユーザーを振り分けることで、効果を測定することができます。

RCTでは、例えば犠牲バントが発生しそうな状況などの不公平性をフラットにすることができるため、単純に2群を比較してあげることで施策の効果を見ることができます。
f:id:Np-Ur:20170721192839p:plain
しかし、RCTをプロ野球における犠牲バントの有効性に関して当てはめようとするならば、ランダムにバッターに対して犠牲バントをするかどうかを割り当て、データを集める必要があります。急に「君は犠牲バントだ!次の君は打て!」と指示するなんてことはプロ野球ではできませんよね…。

同じく教育の効果について考えるときに「こっちの生徒は教育する!そっちの生徒は教育しない!」と振り分けることや、薬の効果について考えたいときに「こっちの患者には薬を与える!そっちの患者には薬は与えない!」と振り分けることは「倫理的に」難しいです。こういった難しさが現実世界ではよく起こります。

そんなときの救世主の1つが傾向スコアというわけです。

現実のデータの問題点について数式を使って表現

先ほど言葉で説明した内容を数式を使って説明してみます(ここら辺から少しずつ難しくなります……)。

犠牲バントが発生した場面 犠牲バントが発生していない場面
犠牲バントを行う
犠牲バントを行わない

犠牲バントが発生した状態を\(z=1\)、犠牲バントが発生しなかった状態を\(z=0\)、また犠牲バントによって得られる成果(例えば得点)を\(y_1\)、犠牲バントしなかったことで得られる成果(同様に例えば得点)を\(y_0\)とします。このとき、本当に欲しい情報は以下のように表されます。

\begin{eqnarray*}
ATE &=& E(y_1) - E(y_0)\\
&=& E(y_1 - y_0)
\end{eqnarray*}

なおATEとは、Average Treatment Effect(平均処置効果)を意味しています。
RCTであれば、取得できた2群の値は\(E(y_1)\)と\(E(y_0)\)となるので、差をとってあげればそれが施策の効果となります。

もしくは、施策が行われた方のグループでの効果のみ見たい場合は、以下のような式で求めることができます。

\begin{eqnarray*}
ATT &=& E(y_1 \mid z=1) - E(y_0 \mid z=1)\\
&=& E(y_1 - y_0)
\end{eqnarray*}
ATTとは、Average Treatment Effect on the treated(処理群の平均処理効果)を意味しています。

しかし、これらに対して前述した①と④の差を比べるのは、
\begin{eqnarray*}
E(y_1 \mid z=1) - E(y_0 \mid z=0)
\end{eqnarray*}
を計算していることに過ぎません。「犠牲バントが発生した時のデータ」と「犠牲バントが発生していない時のデータ」を単純比較して判断することに意味があまり無いことがお分かりいただけたかと思います。

傾向スコアの求め方と使い方

では、これらの問題の救世主となる傾向スコアとは何なのか…を説明しようと思ったのですが、ちょっと現実のデータの問題点について語っていたら、かなり長くなってしまったので、
続きは【後編】記事にて、とさせていただきます。

www.randpy.tokyo

追記

傾向スコアの実践編を公開しました。

www.randpy.tokyo
www.randpy.tokyo