Pythonで因果推論(1)~相関関係と因果関係と疑似相関~
はじめに
相関や因果、疑似相関の発生パターンを具体例やPythonによる実装を交えてまとめました。タイトルには"因果推論"とありますが、今回の記事は因果推論の手法に関する内容ではなく、因果推論を行うにあたっての事前知識の確認的なものとなっております。内容について誤り等がありましたら、コメントにてご指摘いただけますと幸いです。
相関関係
2つの変数の傾向を表した関係。
2つの変数
- 「
が大きいほど、X も大きい」とき「正の相関がある」Y - 「
が大きいほど、X は小さい」とき「負の相関がある」Y
と表現します。
X )とアイスクリームの売上(Y )の関係
具体例: ビールの売上(擬似的に作成した、とある飲食店のビールの売上ととあるスーパーのアイスクリームの売上の散布図(下図)を見てみると、あたかも「ビールの売上(
しかし、「飲食店でビールを飲んだから、スーパーでアイスクリームを買った」とは考えづらいですよね。その逆も然りで、「スーパーでアイスクリームを買ったから、飲食店でビールを飲んだ」と考えるのも不自然です。
このような場合に、「ビールの売上とアイスクリームの売上には正の相関がある」と考えます。
因果関係
2つの変数において、一方が原因、もう一方が結果となっている関係。
2つの変数
- 「他の条件を一定としたときに、
を変化させるとZ も変化する」とき「変数Y から変数Z に因果がある」Y
と表現します。
Z )と試験の成績(Y )の関係
具体例: 学習時間(疑似的に作成した、あるクラスの学生30人の学習時間と試験の成績の散布図(下図)を見てみると、「学習時間が長ければ長いほど、試験の成績も高くなっている」ように見えると思います。
先ほどの「ビールの売上とアイスクリームの売上の関係」とは異なり、「学習時間が長いから、試験の成績も高い」というのは直感的にも納得できると思います。
また、このように因果関係がある場合、(他の条件を全く同じにして)学習時間だけ増加させると、試験の成績も高くなります。例えば、もとの学習時間における試験の成績と、すべての学生が一律に学習時間を20時間増加させた時の試験の成績を箱ひげ図で比較してみると、下記の通りになります。
明らかに、学習時間を20時間増加させた方が、試験の成績が増加しているということが分かると思います。
疑似相関
直接の因果関係のない2つの変数に相関関係が見られること。
疑似相関の生じ方は、大きく以下の3パターンが存在します。
逆の因果
一見「変数
Z )地域と犯罪の発生件数(Y )の関係
具体例: 警察官の数が多い(逆の因果については「警察官が多い地域ほど、犯罪の発生件数が多い」という話が有名です。
この文章だけ読むと、まるで「警察官が多いから、犯罪の発生件数が多い」と言っているようですが、本当にそうなんでしょうか?いいえ、違います。逆なんです。「犯罪の発生件数が多いから、警察官をたくさん配置した」というのが正しい因果なんです。
Pythonによる実装
Pythonを使って、逆の因果によって発生する疑似相関を散布図で表現してみます。
2つの変数
-
は、標準正規分布に従うものとする(Y に依存しない)Z -
は、Z で表わされるものとする(Z = 2Y + noise に依存する)Y -
は一様分布noise に従うものとする(-1, 1)
# ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import japanize_matplotlib
# シードの設定
np.random.seed(0)
# データのサイズ
size = 30
# 変数Zの生成(Yに依存しない)
Y = np.random.randn(size)
# 変数Yの生成(Zに依存する)
Z_noise = np.random.uniform(-1, 1, size)
Z = 2*Y + Z_noise
# 散布図をプロット
plt.scatter(Z, Y)
plt.xlabel("Z")
plt.ylabel("Y")
plt.show()
(出力結果)
散布図は変数
交絡因子
共通する別の変数
Z )と長生き(Y )の関係
具体例: メタボ診断(「メタボ診断を定期的に受ける人ほど長生きする」というデータがあります。一見これは因果関係のようですが、実は違うんです。
もし、これが因果関係であるならば「メタボ診断を受けたから、寿命が伸びた」ということになります。しかし、よくよく考えてみるとメタボ診断そのものが寿命に何か働きかけるということはないですよね?このような場合には交絡因子が存在しているパターンが多々あります。
今回の例で言うと、「そもそも健康への意識が高いからメタボ診断を受けており、健康への意識が高いから長生きする」というように、メタボ診断と長生きに対して「健康への意識の高さ」という交絡因子が存在していると考えられるのです。
Pythonによる実装
Pythonを使って、交絡因子によって発生する疑似相関を散布図で表現してみます。
交絡因子
-
は、標準正規分布に従うものとするX -
は、Z で表わされるものとする(交絡因子Z = 5X + noise に依存する)X -
は、Y で表わされるものとする(交絡因子Y = 5X + noise に依存する)X -
は一様分布noise に従うものとする(-1, 1)
# ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import japanize_matplotlib
# シードの設定
np.random.seed(0)
# データのサイズ
size = 30
# 交絡因子
X = np.random.randn(size)
# 変数Zの生成
Z_noise = np.random.uniform(-1, 1, size)
Z = 5*X + Z_noise
# 変数Yの生成
Y_noise = np.random.uniform(-1, 1, size)
Y = 5*X + Y_noise
# 散布図をプロット
plt.scatter(Z, Y)
plt.xlabel("Z")
plt.ylabel("Y")
plt.show()
(出力結果)
変数
合流点での選抜
もともとは関係性がなく独立で、相関関係がなかったにもかかわらず、合流点で選抜されたデータにあたかも相関関係が生じてしまっている状態。
X )と英語(Y )の得点の関係
具体例: 合格者の数学(ある学校は、数学と英語の入学試験(各々100点満点)を課しており、その合計点が120点以上の受験者を合格としています。
このとき、受験者全体の数学と英語の得点間に相関関係が見られないにもかかわらず、合格者だけの数学と英語を見てみると、数学と英語の得点にまるで相関関係があるように見えることがあります。これを合流点での選抜と言います。
本当にそうなるのか、Pythonにて実装しながら確認していきます。
Pythonによる実装
Pythonを使って、合流点での選抜によって発生する疑似相関を散布図で表現してみます。
数学の得点
- 数学の得点
は、平均55, 標準偏差20の正規分布に従うとするX - 英語の得点
は、平均65, 標準偏差15の正規分布に従うとするY - 数学と英語の得点の合計が120点以上を合格とする
まずは、データを生成し、受験者全員の数学および英語の得点の散布図を描画してみます。
# ライブラリのインポート
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import japanize_matplotlib
# シードの設定
np.random.seed(0)
# データのサイズ
size = 100
# 数学の得点
X_noise = np.random.normal(55, 20, size)
X = np.clip(X_noise, 0, 100)
# 英語の得点
Y_noise = np.random.normal(65, 15, size)
Y = np.clip(Y_noise, 0, 100)
# 受験者全員の数学と英語の得点を散布図をプロット
plt.scatter(X, Y)
plt.title("受験者全員の数学と英語の得点")
plt.xlabel("数学の得点")
plt.ylabel("英語の得点")
plt.xlim(0, 105)
plt.ylim(0, 105)
plt.show()
(出力結果)
散布図を見ると、受験者全員の数学と英語の得点間には相関がありません。
次に、数学と英語の合計点が120点以上の受験者を合格者とし、合格者だけの数学と英語の得点の散布図をプロットしてみます。
# 合流点を作成
total = X + Y
# 合格者だけを格納するための空のarrayを用意
X_passed = np.array([])
Y_passed = np.array([])
# 合格者の数学と英語の得点をそれぞれ格納
for i in range(size):
if total[i] >= 120:
X_passed = np.append(X_passed, X[i])
Y_passed = np.append(Y_passed, Y[i])
# 合格者の数学と英語の得点の散布図を描画
plt.scatter(X_passed, Y_passed)
plt.title("合格者の数学と英語の得点")
plt.xlabel("数学の得点")
plt.ylabel("英語の得点")
plt.xlim(0, 105)
plt.ylim(0, 105)
plt.show()
(出力結果)
こちらの散布図を見ると、まるで「数学の得点が高い人は、英語の得点が低い」あるいは「英語の得点が高い人は、数学の得点が低い」というような負の相関が存在しているように見えます。これが合流点による選抜によって現れる疑似相関です。
参考文献
- 中室、津川「原因と結果の経済学」ダイヤモンド社(2017)
- 伊藤「データ分析の力 因果関係に迫る思考法」光文社新書(2017)
- 岩波データサイエンス刊行委員会編「岩波データサイエンスVol.3-[特集]因果推論-実世界のデータから因果を読む」岩波新書(2016)
おわりに
データ分析を行っていると、多かれ少なかれ「ただの相関関係なのか、はたまた因果関係なのか」を考えなければならない場面が出てきます。そのような場面で、どのようなメカニズムで疑似相関が発生するのかを理解していると、因果関係ミスリーディングリスクを大きく下げることができるはずです。
他にも下記のような記事を書いています。ご一読いただけますと幸いです。
- 反実仮想と因果効果
- 介入とランダム化比較試験
- 回帰分析を用いた効果検証
- 層別解析を用いた効果検証
- 傾向スコアを用いた効果検証
- 操作変数を用いた効果検証
- 回帰不連続デザインを用いた効果検証
- 差分の差分法を用いた効果検証
- 機械学習を用いた効果検証
また、過去にLTや勉強会で発表した資料は下記リンクにまとめてあります。ぜひ、ご一読くださいませ。
Discussion