相関分析
田中VPoE「マーケティング部門から『広告費を増やすと売上が上がるので、もっと広告費を増やしたい』という提案が来ている。」
あなた「広告費と売上に相関があるなら、いいんじゃないですか?」
田中VPoE「相関があるからといって、因果関係があるとは限らない。これはデータ分析で最も陥りやすい罠の1つだ。相関と因果の違いを理解しよう。」
相関とは
相関(Correlation)は、2つの変数の間の線形的な関係の強さと方向を表す指標です。
ピアソン相関係数
最も一般的な相関係数で、2つの変数間の線形関係の強さを測定します。
import pandas as pd
import numpy as np
from scipy import stats
# ピアソン相関係数
corr, p_value = stats.pearsonr(df['ad_spend'], df['revenue'])
print(f"ピアソン相関係数: {corr:.3f}")
print(f"p値: {p_value:.4f}")
相関係数の解釈
| 相関係数(r) | 解釈 |
|---|---|
| 0.7 ~ 1.0 | 強い正の相関 |
| 0.4 ~ 0.7 | 中程度の正の相関 |
| 0.2 ~ 0.4 | 弱い正の相関 |
| -0.2 ~ 0.2 | ほぼ無相関 |
| -0.4 ~ -0.2 | 弱い負の相関 |
| -0.7 ~ -0.4 | 中程度の負の相関 |
| -1.0 ~ -0.7 | 強い負の相関 |
相関行列
複数変数間の相関を一覧で確認します:
# 相関行列の計算
numeric_cols = ['amount', 'quantity', 'age', 'days_since_registration']
corr_matrix = df[numeric_cols].corr()
print(corr_matrix)
# ヒートマップで可視化
import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(8, 6))
sns.heatmap(corr_matrix, annot=True, cmap='RdBu_r', center=0, vmin=-1, vmax=1)
plt.title('相関行列')
plt.tight_layout()
plt.show()
スピアマン順位相関係数
ピアソン相関が線形関係のみを捉えるのに対し、スピアマン相関は**単調な関係(常に増加 or 常に減少)**を捉えます。
# スピアマン順位相関
corr_spearman, p_value = stats.spearmanr(df['ad_spend'], df['revenue'])
print(f"スピアマン相関係数: {corr_spearman:.3f}")
使い分け
| 相関係数 | 適する場面 | 前提 |
|---|---|---|
| ピアソン | 正規分布に近いデータ | 線形関係を仮定 |
| スピアマン | 順序データ、外れ値が多いデータ | 単調関係を仮定 |
実務のヒント:まずピアソンとスピアマンの両方を計算し、大きく異なる場合は散布図で関係の形を確認しましょう。
相関と因果の違い
「相関は因果ではない(Correlation does not imply causation)」
これはデータ分析の最も重要な原則の1つです。
見せかけの相関の例
| 変数A | 変数B | 相関 | 実際の関係 |
|---|---|---|---|
| アイスクリーム売上 | 溺死事故数 | 正の相関 | 交絡変数(気温)が原因 |
| 広告費 | 売上 | 正の相関 | 売上が好調だから広告費を増やした(逆因果) |
| サイト滞在時間 | 購入率 | 正の相関 | 購入意欲が高い人が長く滞在する |
因果関係の3条件
- 時間的先行:原因が結果より先に起きている
- 相関関係:2つの変数に統計的な関連がある
- 交絡の排除:第3の変数の影響を排除できている
交絡変数
気温(交絡変数)
↙ ↘
アイスクリーム売上 溺死事故
←(見せかけの相関)→
偏相関
交絡変数の影響を取り除いた相関を偏相関と呼びます。
# 偏相関の計算(手動)
def partial_correlation(df, x, y, covariates):
"""x と y の偏相関(covariates の影響を除去)"""
from sklearn.linear_model import LinearRegression
# x から covariates の影響を除去
model_x = LinearRegression().fit(df[covariates], df[x])
residual_x = df[x] - model_x.predict(df[covariates])
# y から covariates の影響を除去
model_y = LinearRegression().fit(df[covariates], df[y])
residual_y = df[y] - model_y.predict(df[covariates])
# 残差間の相関
return stats.pearsonr(residual_x, residual_y)
# 季節(月)の影響を除いた広告費と売上の偏相関
corr, p = partial_correlation(df, 'ad_spend', 'revenue', ['month'])
print(f"偏相関係数: {corr:.3f}, p値: {p:.4f}")
pingouin ライブラリを使う方法
import pingouin as pg
# 偏相関
result = pg.partial_corr(data=df, x='ad_spend', y='revenue', covar='month')
print(result)
散布図での確認
相関係数だけでなく、必ず散布図で関係を視覚的に確認しましょう。
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# 線形関係
axes[0].scatter(df['x1'], df['y1'], alpha=0.5)
axes[0].set_title(f'線形関係 (r={df["x1"].corr(df["y1"]):.2f})')
# 非線形関係(相関係数は低いが関係あり)
axes[1].scatter(df['x2'], df['y2'], alpha=0.5)
axes[1].set_title(f'非線形関係 (r={df["x2"].corr(df["y2"]):.2f})')
# 外れ値の影響
axes[2].scatter(df['x3'], df['y3'], alpha=0.5)
axes[2].set_title(f'外れ値あり (r={df["x3"].corr(df["y3"]):.2f})')
plt.tight_layout()
plt.show()
アンスコムの四重奏:同じ相関係数でも、データの形はまったく異なることがあります。数値だけで判断せず、必ず可視化しましょう。
まとめ
| 項目 | ポイント |
|---|---|
| ピアソン相関 | 線形関係の強さを測定。正規分布データに適する |
| スピアマン相関 | 単調関係を測定。外れ値に頑健 |
| 相関 != 因果 | 交絡変数や逆因果に注意する |
| 偏相関 | 第3変数の影響を除いた相関 |
| 可視化 | 必ず散布図で関係の形を確認する |
チェックリスト
- ピアソンとスピアマンの相関係数の違いを説明できる
- 相関と因果の違いを具体例で説明できる
- 交絡変数の概念を理解している
- 偏相関の意味と使い方を知っている
次のステップへ
相関分析を学びました。次は演習で、NetShop社のA/Bテスト結果を統計的に分析してみましょう。
推定読了時間:30分