【共変量の調整】傾向スコア・マッチングによる因果推論 | python

今回は傾向スコアをご紹介します。

実際の数式に入る前に、しっかり「傾向スコアが必要な理由」を知ることが大事だと思います。

因果推論に必要な考え方ですので、しっかり習得しましょう。

傾向スコア propensity score

傾向スコアとは、「処置とコントロール群以外の条件を同じにしたい」というモチベーションから考えられます。

以下の例を考えてみましょう。

新薬には血圧を下げる効果があるのかどうかを調べたいです。


健康状態や年齢がバラバラの被験者50人連れてきて、新薬を飲むか飲まないかを自分で決めてもらいます。


(こちらが、新薬を投与するかしないかを指定する(ランダム)と倫理的に問題があるからです。)


処置群の血圧の変化から、コントロール群の血圧の変化を除いた時に、新薬の効果はわかるでしょうか?

答えとしては、微妙です。

微妙な理由としては、血圧に影響を与える影響のある、「年齢」や「健康状態」がバラバラだからです。

この属性の違いにより、本人が新薬を使うかどうかを選択する可能性が変わります。

若くて健康状態の良い人がコントロール群に選び、比較的年をとっていて健康状態が良くない人が処置群に選ばれる傾向がありそうです。

杜撰な例

差の差分析によって得られる、新薬の介入効果が全くの出鱈目であるということはわかると思います。

この時に傾向スコアを使います。

当然処置群とコントロール群では、属性が似通っている方が因果効果を正確に測れますよね。

この属性(交絡因子)の「似通い度」を傾向スコアと呼んでいるわけです。

もう少し正確に言えば、傾向スコアとは「各サンプルが介入を受ける確率」のことです。

求め方としては、ロジスティック回帰や決定木、深層学習などで各サンプルのもつ観測された共変量を説明変数、介入の有無を目的変数に置くことで求められます。

利点の一つとして、目的変数の確率分布を考えなくて良い、ノンパラメトリックな手法であることです(後で詳しく解説いたします)

*健康状態や年齢は事前にある程度揃えて実験しろというのが真っ当な意見です。

今回は、「処置の有無以外の条件を被験者で一緒にしたいよね」というのが傾向スコアのモチベーションであると理解してもらえると嬉しいです。

定理

ここでは、傾向スコアの定理を紹介します。

傾向スコアとは共変量Xが与えられた時の処置に割り付けられる確率を意味します。

定理1:バランシング

処置の割り付けTと観測された共変量Xは、傾向スコアe(X)が与えられた時の条件付き独立です。

定理2:条件付き独立性

傾向スコアe(X)が与えられると、潜在的結果変数{γ(1),γ(0)}と処置の割り付けTは条件付き独立です。

これは、つまり処置と結果変数が関連していないということです、

注意点として、傾向スコアによるモデリングでは処置の割り付けに影響を与えるものは観測された共変量Xのみであり、未観測の共変量によるバランシングまでは補償していません。

バランシング


共変量Xの関数b(X)が与えられた時のXの条件づき分布が、処置群とコントロール群で同じになること。

つまり、傾向スコアとは「傾向スコアが同じだと、期待される目的変数は同じであるという便利な統計量」ということがわかりました。

CODE

先ほどの例を使います。

全て架空のデータになっております。現実には全く即していないのでご了承ください。

healthblood pressureageintervention
0102.31250
161.44301
265.50291
372.07300
464.00281
一部データを抜粋する
health:健康指標。10に近づくほど健康。

blood pressure:介入(コントロールでも可)前後の血圧の変化量(負の数)。

age:年齢

intervention:被験者が介入を受けたかどうかのダミー変数。0なら介入がなく、1なら介入がある。
import numpy as np
import pandas as pd
import statsmodels.api as sm

ライブラリのインポートを行います。

先ほど表に書いたデータを読み込んでデータフレームにしてみましょう。

df = pd.read_csv("health.csv")
# 傾向スコアを算出するために使用する説明変数
X = df[["health","age"]]
X = sm.add_constant(X)



# 介入変数
D = df["intervention"]

Xを傾向スコアを算出するために使用する説明変数とします。

今回交絡因子となりそうなのは、「健康状態」と「年齢」が挙げられます。

また、介入変数として、「新薬の投与有無」のinterventionを与えます。

つまり、介入が行われるかどうかは、健康状態や年齢の影響を受けるということです。

# 傾向スコアを算出
model = sm.Logit(D, X)
result = model.fit()
result.predict(X)

先ほども説明いたしましたが、傾向スコアとは「介入を受ける確率」です。

傾向スコアをロジスティック回帰を使って推定します。

df["傾向スコア"] = result.predict(X)
df.head()

50人の被験者に対し、以下のような傾向スコアが与えられました。

傾向スコアが近いほど、介入を受ける確率(今回で言うと、新薬を自分で試す確率)が近くなります。

healthblood pressureageintervention傾向スコア
0102.312500.078998
161.443010.512202
265.502910.497296
372.073000.376869
464.002810.482395
一部抜粋

平均処置効果(Average Treatment Effect)

応用として、傾向スコアを用いたマッチングまで行おうと思います。

傾向スコアを算出するだけではなく、マッチングまで行わなければ意味はありません。

ここで求める値は、平均処置効果(ATE)と呼ばれるものです。

【ゼロから始める】統計的因果推論とは。で個別個体効果を説明しましたが、個別個体効果は直接求めることはできません。

注目されるのは、平均処置効果の方です。

介入群における平均処置効果
コントロール群における平均処置効果

介入前後による血圧の変化の期待値が、介入群における平均処置効果です。

一方、コントロール前後(要は何もしない)の変化の期待値が、コントロール群における平均処置効果です。

そして、実験の目的である「新薬の効果」とはATTからATUを除いた平均処置効果です。

これを関数を作って求めてみます。

差の差分析と同じ考え方ですね。

# 平均処置効果を求める
def calc_match_ate(df, step=0.1):

    scores = np.arange(0, 1, step)

    match_arr = np.array([])
    for score in scores:
        _df = df[(df["傾向スコア"]>=score) & (df["傾向スコア"]<score+step)]
        tmp0 = np.array(_df[_df["intervention"]==0]["blood pressure"])
        tmp1 = np.array(_df[_df["intervention"]==1]["blood pressure"])
        if (tmp0.size!=0) and (tmp1.size!=0):
            match_arr = np.append(match_arr, tmp1.mean() - tmp0.mean())

    return match_arr.mean()
calc_match_ate(df, step=0.1)

>0.6199404761904762

0.619940476‥くらい純粋な効果が見込める。と言うことがわかりました。

ノンパラメトリック手法

傾向スコアは、ノンパラメトリック手法と言われます。

ノンパラメトリック手法は、パラメトリック手法と違い、目的変数の確率分布が分からなくても良いです。

正しいモデルをわかっていれば、共分散分析は有効です。

しかし、「モデルがわからない」かつ「共変量を置いて、線形関係を仮定したときに明らかに望ましくない」場合にノンパラメトリック手法を使います。 

線形性の過程が必要な共分散分析について知りたい方は、【交絡を解決!?】共分散分析(ANCOVA)とは一体何なのか。をご覧ください。

ランダムな割り付け(ランダム比較化実験など)ができればいいのですが、例えばマーケティングのABテスト(新しいモーダルを見せるor見せない)だと、半数には見せないので毀損が生じる可能性があります。また、今回の例で取り上げた新薬の例では、「半数には血圧を下げる効果があると思われる薬を投与しないのか」という倫理的な問題が生じます。

こうしたABテストなどを実施できない時には、介入以外による影響のバイアスを否定できず、介入効果を過大もしくは過小に評価してしまう恐れがあります。

こんな時に傾向スコアを使うと便利です。

傾向スコアによる解析は準実験と呼ばれます。準実験とは、処置の無作為な割り付けがない観察研修でも割り付けや比較対象の集団についてなんらかの統制を行うことで無作為化実験を真似するデザインであり、社会科学系でよく使われることが多いです。

青の統計学では、社会科学のうち計量経済学を取り扱っています。

詳しくは、計量経済学をご覧くださいませ。

-Udemy-のご紹介

データサイエンスやプログラミングに興味がある方におすすめなのが、Udemyと呼ばれる世界最大級のオンライン学習プラットフォームです。

Udemyは、世界中の学びたい人と教えたい人をオンラインでつなぐサービスです。

つまり、講師は企業ではなく、一般のエンジニアやデータサイエンティスト、デザイナーです。

講座カテゴリー

  • Pythonなど、機械学習プログラミング言語
  • Javaなど、Webアプリケーション言語
  • Webデザイン(HTML&CSS/JavaScript)
  • Excel
  • マーケティング

特に最近ではAI・データサイエンスなど先端ITの講座が人気を博しております。気になる方は以下のボタンからご覧ください。

ジャンルが豊富で学びたい講座がきっとみつかる

受講者数講師数講座数
4,000万人70,000人約18.5万
2021年3月時点(Udemy)

世界中にサービスを展開しているため、サービスの規模は非常に大きいです。

AI・データサイエンスなど最先端のIT技術からプレゼンなどビジネススキルに関する講座まで 18.5万以上(※海外講座含む)あるため、自分が学びたい講座をみつけることができます。

きっとピッタリな講座が見つかるでしょう!

講座は、PC一台があればカフェでも学校でも職場でも受講することができます。

また倍速対応ができ、0.5〜2倍の変速機能で自分のペースで受講が可能です。

お手頃な価格帯

講座により、価格は大きく変わりますが、数千円台のものも多く、手を出しやすいです。

講座は一度購入すれば視聴期限なく受講でき、30日返金保証もついているので安心して始めることができます

こんな方におすすめ!

  • Webデザイナーになって、自由な生活を手に入れたい方。
  • プログラマーになって、本業以外の副収入を得たい方。
  • 自学自習じゃなかなか続かない方。
  • 資格習得や、スキルの向上により、今の年収をupさせたい方。

具体的には、以下のようなコースがあります。きっと良い講師に出会えるはずです。

FOLLOW ME !

PAGE TOP