DoWhyで因果推論(Causal Inference)

因果推論(Causal Inference)とは?

因果推論(Causal Inference)は、データを用いて変数間の因果関係を推定・検証するための統計学的手法です。因果関係とは、ある変数(原因)が他の変数(結果)にどのように影響を与えるかを示す関係です。因果推論は、単なる相関(相関関係があるが、必ずしも因果関係があるとは限らない)とは異なり、直接的な因果関係を明らかにすることを目指します

DoWhyは、この因果推論(Causal Inference)を行うためのPythonライブラリです。

この記事では、このDoWhyを利用した因果推論を行って見たいと思います。
環境はGoogle Corabです。

ライブラリのインストール

!pip install dowhy

データセットの読み込み

今回は有名なタイタニック号の沈没事故に関連するデータを含むTitanicデータセットを利用します。データセットには、乗客の個人情報や乗船情報、生存状況などが含まれています。

データセットを読み込み、データの前処理を行っておきます。

import pandas as pd
import numpy as np

url = 'https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv'
data = pd.read_csv(url)

data = data[['Sex', 'Survived', 'Pclass', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']]
data = data.dropna() 
data['Sex'] = data['Sex'].map({'male': 1, 'female': 0}) 
data['Embarked'] = data['Embarked'].map({'S': 0, 'C': 1, 'Q': 2})

因果モデル

因果モデルの定義をCausalModelで行っていきます。
この例では、性別(Sex)が生存(Survived)に与える影響を推定します。

from dowhy import CausalModel

model = CausalModel(
    data=data,
    treatment='Sex',
    outcome='Survived',
    common_causes=['Pclass', 'Age', 'SibSp', 'Parch', 'Fare', 'Embarked']
)

treatment(処置)は、因果関係を調べる際の「原因」に相当する変数を指定します。この変数がoutcome(結果)にどのような影響を与えるかを推定するのが因果推論の目的です。common causes(共通原因)は、treatmentとoutcomeの両方に影響を与える変数のことを指します。

因果効果の識別

identify_effectメソッドを使用して、因果効果を識別します。

identified_estimand = model.identify_effect()

因果効果の推定

estimate_effectメソッドを使用して、識別された因果効果を推定します。

estimate = model.estimate_effect(identified_estimand, method_name="backdoor.propensity_score_matching")

性別が生存に与える因果効果の推定値は下記の通りになりました。

−0.443820224719101

因果効果の符号(プラスまたはマイナス)は、treatment(この場合は性別)がoutcome(生存率)に与える影響の方向を示します。

プラスの符号は、性別が男性(Sex = 1)であることが生存率(Survived = 1)を増加させることを意味します。つまり、男性であることが生存率を上げる方向に働く場合です。逆にマイナスの場合は、性別が男性(Sex = 1)であることが生存率(Survived = 1)を減少させることを意味します。つまり、男性であることが生存率を下げる方向に働く場合です。

今回の推定値は、男性(Sex = 1)であることが女性(Sex = 0)に比べて生存率(Survived = 1)を約44.38%減少させることを示しています。この解釈は、タイタニック号の歴史的背景(女性と子供が優先的に救助されたこと)とも一致しています。

結果の検証

refute_estimateメソッドを使用して、推定された因果効果の信頼性を検証します。ここでは検証方法としてプラセボ検証という方法を指定しています。プラセボ検証は、treatmentの変数を無関係な変数に置き換えて再度因果効果を推定し、outcomeがどの程度変わるかを確認します。

refutation = model.refute_estimate(identified_estimand, estimate, method_name="placebo_treatment_refuter")

print(refutation)

結果は下記の通りになります。

Refute: Use a Placebo Treatment
Estimated effect:-0.4438202247191011
New effect:-0.00526685393258427
p value:0.86

treatmentの変数を無関係な変数に置き換えた場合の推定因果効果は -0.00526685393258427 です。これはほぼゼロに近い値であり、実質的にtreatmentとoutcomeに因果関係がないことを示しています。

プラセボ効果に対するp値が 0.86 です。高いp値は、無関係なtreatmentの変数がoutcomeに有意な影響を与えないことを示しています。結果的に男性が女性に比べて生存率が低いという結論が支持されます。