r = +0.972 と書いてあれば、まさにこれです。このページは 26 章あります。 読みたいところへ直接飛べるよう、 章の一覧を置きます。
🍰 まずはやさしく
2つのデータの関係を測るものさしです。
どれだけ一緒に動くかを知るために使います。
勉強時間とテストの点数の関係に似ています。
まずはこの数字が何を表すかを確認しましょう。
論文の表や本文で、こんな数字を見たはずです:
この r が 相関係数(Pearson の積率相関係数)。−1 から +1 の値 を取り、「2つの量がどれだけ一緒に動くか」 を 1 つの数字に集約します。ここではまず「何を見ている数字か」を 30 秒で押さえます。
🍰 まずはやさしく
関係の強さを表すシンプルな数字です。
データのつながりを素早く判断するために使います。
スマホの利用時間と睡眠時間の関係などです。
数字の読み方と注意点をまとめました。
🍰 まずはやさしく
データの並び方を表す地図のようなものです。
見た目で関係の強さをつかむために使います。
部活の練習量と試合結果のグラフで考えます。
数字によって図がどう変わるかを見てみましょう。
具体的に「r の数字が違うと、散布図はどう違って見えるのか」を、実データの SSDSE-B(47都道府県・2023年)で確かめてみましょう。
ポイントは 「r=+0.97 と |r|≈0.5(図の (b)(c))は同じ「相関あり」でも別物」 ということ。 |r| が高いほど、x の値だけで y の値をかなり予測できますが、|r|=0.3〜0.4 程度では「言うほど予測できない」状態です。
この強い相関は、47都道府県 1点ずつ見ても、ほぼ「右上がりの直線」に並びます。
ここまでは「出来上がった散布図」を眺めてきました。今度は自分で点を動かして、r がリアルタイムでどう変わるかを触って確かめましょう。
外部ライブラリを使わない素の JavaScript で動くので、オフラインでもそのまま動きます。
おもちゃで感覚を掴んだら、実データの数字と結びつけましょう。以下はすべて encoding='cp932' / skiprows=[1](コード行をヘッダに採用)で読み込んだ SSDSE-B-2026 の 2023 年・47都道府県から実測した値です。
| x | y | Pearson r | 相関の型 |
|---|---|---|---|
| 総人口 (A1101) | 一般診療所数 (I5102) | +0.972 | 強い正の線形。人口が多い県ほど診療所も多い(規模効果) |
| 高齢化率 (A1303/A1101) | 粗死亡率 (A4200/A1101) | +0.972 | 強い正の線形(このページ図2の主役) |
※ 総人口×一般診療所数は Pearson r=0.9717(p≈7.7×10⁻³⁰)、Spearman ρ=0.982。ただし「総人口が多いほど診療所が多い」のはほぼ定義的な規模効果であって、診療所が人口を増やすわけではない——これも典型的な「強い相関だが素朴な因果解釈は危険」な例です。人口あたり(診療所数÷総人口)にすると関係はまったく違って見えます。
🍰 まずはやさしく
計算で導き出す正確なルールです。
客観的な数値として関係を出すために使います。
買い物で使う金額と個数の関係などを計算します。
相関係数を求めるための式を学びましょう。
2変数 $x$ と $y$ の n 個の観測ペア $(x_1, y_1), (x_2, y_2), \dots, (x_n, y_n)$ に対して:
同じものを 共分散・標準偏差 で書くと、もっと意味が見えます:
数式を眺めるだけだとピンと来ないので、各部品が どんな仕事をしているか を分解しましょう。
視覚的に確認してみましょう。各都道府県の点を、平均線(点線)で分けた 4象限 で色分けしました:
「公式を見ただけでは分かった気がしない」のは普通です。5都道府県のミニデータで手計算してみましょう(高齢化率 % と死亡率 ‰)。
| 都道府県 | $x_i$(高齢化率) | $y_i$(死亡率) | $x_i-\bar{x}$ | $y_i-\bar{y}$ | 積 |
|---|---|---|---|---|---|
| 秋田 | 39.1 | 19.2 | +8.54 | +5.32 | +45.43 |
| 高知 | 36.3 | 17.2 | +5.74 | +3.32 | +19.06 |
| 大阪 | 27.7 | 12.0 | −2.86 | −1.88 | +5.38 |
| 神奈川 | 25.9 | 10.7 | −4.66 | −3.18 | +14.82 |
| 沖縄 | 23.8 | 10.3 | −6.76 | −3.58 | +24.20 |
| 平均→ | $\bar{x}=30.56$ | $\bar{y}=13.88$ | 積の合計→ | +108.89 | |
※ 値は SSDSE-B-2026 の 2023 年度データから、高齢化率 = A1303(65歳以上人口)÷ A1101(総人口)× 100、死亡率(粗死亡率)= A4200(死亡数)÷ A1101 × 1000 で算出し、小数第1位に丸めたもの。
解釈: 「高齢化率が高い県ほど、死亡率も高い」傾向が、たった 5 県のサンプルからもクッキリ読み取れる。なお、この 5 県は高齢化率の高い側(秋田・高知)と低い側(神奈川・沖縄)の両端を含むため、47県全部の r=+0.972 よりさらに直線に近い値が出ている。どの標本を選ぶかで r は変わる点にも注目。
もし分母(規格化)がなければ、それは 共分散 という量です:
共分散にも「正の相関なら正、負の相関なら負」という符号情報はあります。 ですが、共分散には致命的な欠点があります:
これを解決するため、各変数の標準偏差で割って規格化したのが相関係数。 これで 必ず −1 ≤ r ≤ +1 に収まり、違う組み合わせ同士でも強さを比較できるのです。
「相関係数」と一言で言うとき、たいてい Pearson の積率相関係数(ここまで説明したもの)を指します。 ただし、もう 1 つメジャーなのが Spearman の順位相関係数です。
| 項目 | Pearson(積率相関) | Spearman(順位相関) |
|---|---|---|
| 測るもの | 直線関係の強さ | 単調関係の強さ(増えれば増える、減れば減る) |
| 計算方法 | 値そのものから計算 | 値を 順位(rank) に変換してから Pearson と同じ計算 |
| 外れ値の影響 | 強く受ける(1点で r が大きく動く) | 受けにくい(順位だから極端値が緩和される) |
| 非直線でも検出? | 苦手(直線でないと小さくなる) | 得意(単調なら直線でなくても高い値が出る) |
| 適する状況 | 正規分布に近い数値データ/直線関係を想定 | 順位データ/外れ値あり/非直線の単調関係を疑う場合 |
使い分けのコツ:両方計算してみて、 r_Pearson ≈ r_Spearman なら直線関係。 r_Spearman > r_Pearson なら「単調だけど曲線」または「外れ値の影響」を疑うサイン。
相関係数を使う上で最も重要な戒め。 「2変数に強い相関がある」と分かっても、 そこから「A が B を引き起こしている」と結論するのは論理的飛躍です。 この節では、 実際のデータで「疑似相関がどう発生するか」「どう見抜くか」を体験します。
例1:「アイスクリームの売上」と「水難事故件数」
米国データで両者の相関は r ≈ +0.8 と強い正相関。 「アイスを食べると溺れやすい?」もちろん違う。 真犯人は 「夏の気温」。 暑い日には:
気温という第3変数が両方の原因なので、 アイスと水難事故は見かけ上だけ連動する。 これが 疑似相関(spurious correlation) の典型例。
例2:「コウノトリの数」と「出生率」
ドイツ地方都市データで r ≈ +0.6。 民話「赤ちゃんはコウノトリが運ぶ」を裏付ける?もちろん違う。 真犯人は「農村度」。 農村部ほど(i) コウノトリの巣作り場所が多く、 (ii) 出生率も高い(家族規模が大きい)。
本データセット(47都道府県・2023年)で、 「有効求人倍率」と「死亡率」の相関を計算してみると:
※ SSDSE-B には「有効求人倍率」という列は直接収録されていないため、ここでは F3103(月間有効求人数)÷ F3102(月間有効求職者数)で構成した代理値を「有効求人倍率」として用いています。
この数字だけ見れば「景気の良い県ほど、 人が死んでいる」という驚くべき結論になります。 国土交通省や厚労省にとってホラー的な結果。 しかし、 これは典型的な疑似相関です。
真犯人を疑うべき第3変数:「高齢化率」。 なぜなら:
つまり「高齢化率」が両方を引き上げているために、 求人倍率と死亡率に見かけの相関が生まれた。 これを重回帰で確認します:
モデル1(単純相関):
死亡率 = 10.13 + +2.94×求人倍率 + ε
求人倍率の係数 = +2.94 (有意 p=0.035)
モデル2(高齢化率を制御後):
死亡率 = −5.39 + +0.30×求人倍率 + 0.60×高齢化率 + ε
求人倍率の係数 = +0.30 (非有意 p=0.40)、高齢化率 = +0.60 (p<0.001 ***)
解釈:高齢化率を制御すると、 求人倍率の係数は +2.94 → +0.30 と急減し、 統計的有意性も消失。 「求人倍率と死亡率の単純相関は、 ほぼ全て高齢化率を介した疑似相関だった」と判明。 これが交絡(confounding)の典型例で、 観察データの解釈で常に警戒すべき罠です。
観察データから「因果」を語ることの困難さを整理した枠組み:
| レベル | 問い | 手段 |
|---|---|---|
| 1. 関連付け | 「X と Y は連動するか?」 | 相関係数、 散布図、 単純な観察 |
| 2. 介入 | 「X を操作したら Y はどうなる?」 | ランダム化実験、 自然実験、 DiD |
| 3. 反実仮想 | 「過去に X がこうだったら、 Y はどうなっていた?」 | 構造的因果モデル、 操作変数法、 RDD |
本サイトの論文のほとんどは「レベル1の関連付け」。 「相関を発見した」「関連を観察した」と慎重に表現し、 「因果関係」と書くのは控えめにするのが学術論文の作法です。
💡 鉄則:相関係数を見たら、 必ず「第3変数の可能性」を疑う癖をつけましょう。 これだけで、 統計分析の信頼性が一段上がります。 「相関がある」と「因果がある」の橋を渡るには、 観察データだけでは足りないのです。
r = +0.308 (p<0.05) の有意な正相関がある。「景気の良い県ほど死ぬ?」――そんなはずはない。 高齢化率を制御する重回帰を回すと、求人倍率の効果は消える。これは見かけ上の 疑似相関(spurious correlation)。
上の「4つの落とし穴」に加えて、 論文・レポートで実際によくやらかす2つの罠を、 SSDSE-B の実データで確認します。 どちらも「r の数字を額面通り受け取る」と結論を誤るタイプです。
相関係数は、 x(や y)のばらつきが大きいほど大きく、 ばらつきを人為的に削ると小さくなります。 「似た者ばかりを集めた標本」で相関を測ると、 母集団では確かに存在する関係が見えなくなる——これが範囲制限(選抜効果とも)です。 選択バイアスの一種で、 「合格者だけ」「一定以上の県だけ」などx で足切りした標本で頻発します。
SSDSE-B-2026(2023年・47都道府県)の 消費支出(L3221)と食料費(L322101)で実演します(encoding='cp932' / skiprows=[1] で読み込んだ実測値):
| 標本 | n | x(消費支出)の幅 | Pearson r | p 値 |
|---|---|---|---|---|
| 47都道府県ぜんぶ | 47 | 223,423 〜 344,092 円 | +0.679 | 1.6×10⁻⁷(有意) |
| 消費支出が「中くらい」の県だけ (第1〜第3四分位に挟まれた中央50%) | 23 | 279,506 〜 307,502 円 | +0.354 | 0.098(有意でない) |
※ 中央50%は消費支出の第1四分位(≈279,506円)以上・第3四分位(≈307,502円)以下の県。 上位・下位の県を落として x の幅を約12万円→2.8万円に狭めただけで、 データ自体はいじっていません。
なぜ縮むのか(直感):r の分母には x と y の標準偏差(=ばらつき)が入っています。 標本を均質にすると分子の共変動より先に分母の「x の広がり」が痩せ、 信号(傾き)はそのままでも相対的にノイズが目立つため r が小さく出ます。
このページの r はすべて都道府県という「集団」を1点にした集計データの相関です。 集計レベルで計算した相関を生態学的相関と呼び、 それをそのまま個人に当てはめると誤りになります(生態学的誤謬 / ecological fallacy、 Robinson 1950)。 前掲のシンプソンのパラドックスと親戚の罠です。
たとえば本ページで見た実測値:
これらは「食料費が多い県では教育費も多い」という県の性質を語っているだけで、 「食費をたくさん使う個人ほど教育費も多い」を意味しません。 集団を平均すると個人内のばらつき(消し合い)が消え、 集計相関は個人相関より大きく(時に符号すら逆に)出るのが普通だからです。
※ 「食料費と教育費 r=+0.728」「消費支出と教育費 r=+0.575」は本ページ「相関行列とヒートマップ」節と同じ SSDSE-B-2026 実測値。 個人単位の数値はデータに存在しないため、 ここではあえて示していません(捏造を避けるため)。
本サイトの再現論文集の中で、相関係数が中心的役割を果たすものを 3 つピックアップしました:
1973年、 統計学者 Frank Anscombe は「相関係数だけで判断する危険」を示すため、 同じ統計量を持つ4組のデータを示しました。 これが Anscombe の四つ組(Anscombe's quartet) です。
4つのデータセット I, II, III, IV は、 まったく違う散布図に見えますが、 計算すると次の値がすべて同じ:
| 統計量 | 4組共通の値 |
|---|---|
| x の平均 | 9.0 |
| y の平均 | 7.5 |
| x の分散 | 11.0 |
| y の分散 | 4.12 |
| 相関係数 r | 0.816 |
| 回帰直線 | y = 3.0 + 0.5x |
「r=0.816 で強い正の相関」だけ見れば4つは同じ関係に見えます。 しかし散布図を描くと:
相関係数を計算する前に、 必ず散布図を描け。 計算した後にも、 もう一度散布図を確認しろ。 数値だけで判断すると、 まったく違う構造を持つデータを同じものと扱ってしまう。 統計分析の最初の儀式は可視化。
2017年に Matejka と Fitzmaurice が拡張:12個のデータセットが平均・分散・相関係数すべて同じなのに、 散布図は恐竜・星・X字・線などまったく違う形を示します。 Anscombe を21世紀的に発展させた教訓的データ。 「数値の同一性」と「分布の同一性」は別物、 という強烈な教訓です。
相関係数 $r$ と単回帰の傾き $\beta$ には、 美しい関係があります:
「高齢化率を1%上げると、 死亡率は約0.61‰上がる」。 単回帰の傾きを、 相関係数から復元できます。
単回帰の決定係数 R² は、 実は相関係数の二乗:
$R^2 = r^2$
r = 0.972 → R² = 0.945。 「y の分散の94.5%が x で説明できる」。 相関係数と説明力が直接結びつく重要な関係です。
「アイス売上と水難事故」のような疑似相関を見抜くには、 第3変数(気温など)を制御する必要があります。 これを統計的に実現するのが 偏相関係数。
SSDSE 47都道府県データ(2023年)で:
偏相関の分子:$0.308 - 0.287 \times 0.972 = +0.029$
分母:$\sqrt{(1-0.287^2)(1-0.972^2)} = \sqrt{0.918 \times 0.055} \approx 0.225$
偏相関 ≈ $0.029 / 0.225 \approx \mathbf{+0.13}$(ほぼゼロ、 有意でない)。 単純相関 +0.308 が、 高齢化率を制御するとほぼ消えることが分かります。 重回帰で求人倍率の係数が非有意(p=0.40)になったことと同じ結論。 これが「求人倍率と死亡率は高齢化率を経由した疑似相関」の数値的な確認です。
論文では偏相関の方が使われることが多い。 Python の pingouin パッケージや R の ppcor で計算可能。
偏相関は複数変数を同時制御することもできる:$r_{xy \cdot z_1, z_2, z_3}$。 さらに多変数を制御するのが重回帰。 「重回帰の偏回帰係数 β は、 偏相関を一般化したもの」と理解できます。
論文で「効果量(effect size)」と書かれているとき、 相関係数 $r$ は最もポピュラーな指標。 サンプルサイズに依存する p値とは違って、 相関係数は効果の大きさそのものを表します。
| |r| の値 | 効果量 | 解釈の目安 |
|---|---|---|
| 0.10〜0.29 | small(小) | 弱い効果。 統計的に有意でも実用的にはわずか |
| 0.30〜0.49 | medium(中) | 中程度の効果。 実用的にも意味ある |
| 0.50 以上 | large(大) | 強い効果。 実用的に大きな影響 |
注意:これは Cohen(1988)の経験則で、 領域による差は大きい。
・物理科学なら r=0.95 でも「やっと使える」
・社会科学なら r=0.3 でも「強い発見」
・金融予測なら r=0.05 でも「価値ある」
絶対基準ではなく、 領域慣習・先行研究との比較基準として使う。
| |r| | p値 | 解釈 |
|---|---|---|
| 大 | 小 | ✅ 強い効果 + 偶然じゃない → 信頼できる発見 |
| 大 | 大 | ⚠️ 効果はあるが、 サンプル不足。 追加調査 |
| 小 | 小 | ⚠️ 統計的有意だが実用的に意味なし(n が大きすぎる) |
| 小 | 大 | ❌ 効果も検出できない |
現代の学術論文では、 「p < 0.05」だけでなく 必ず効果量と信頼区間を報告するのが標準。 American Psychological Association や American Medical Association のガイドラインで明文化されています。 r、 r²(決定係数)、 95%信頼区間の3点セットで報告するのがプロの作法。
相関係数の Python 実装は、 用途に応じて複数のライブラリで選べます。 主要パターンと注意点を整理します。
df を使う)このコードでやること:SSDSE-B-2026 から 2023 年度の 47 都道府県を取り出し、 このページで使う 高齢化率・死亡率・求人倍率・家計 4 変数を作って df に入れる。 以降のブロックはこの df と X をそのまま使う。
📥 入力:data/raw/SSDSE-B-2026.csv(564 行 × 112 列。 47 都道府県 × 2012〜2023 年度)。 高齢化率・死亡率・求人倍率は元データに列が無いので、 ここで割り算して作る。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import pandas as pd # SSDSE-B-2026(47 都道府県 × 12 年)から 2023 年度だけを取り出す raw = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932', header=1) raw = raw[raw['地域コード'].astype(str).str.match(r'^R\d{5}$', na=False)] raw = raw[pd.to_numeric(raw['年度'], errors='coerce') == 2023].reset_index(drop=True) num = lambda c: pd.to_numeric(raw[c], errors='coerce') # このページで使う指標をここで作る(率は自分で計算する必要がある) df = pd.DataFrame({ '高齢化率': num('65歳以上人口') / num('総人口') * 100, # % '死亡率': num('死亡数') / num('総人口') * 1000, # 人口千対 '求人倍率': num('月間有効求人数(一般)') / num('月間有効求職者数(一般)'), '消費支出': num('消費支出(二人以上の世帯)'), '食料費': num('食料費(二人以上の世帯)'), '住居費': num('住居費(二人以上の世帯)'), '教育費': num('教育費(二人以上の世帯)'), }) df.index = raw['都道府県'] # 家計 4 変数だけを取り出したもの(このあとの相関行列で使う) X = df[['消費支出', '食料費', '住居費', '教育費']].dropna() print(df.shape) print(df.head(3).round(2)) |
📤 実行すると次の出力が得られる:
💬 47 行 7 列。 北海道の高齢化率 33.01%、 死亡率 14.75(人口千対)。 この 2 つが以降の相関の主役で、 掲載している r = 0.9720 はこの df から出た値。
1 2 3 4 5 6 7 8 9 10 11 12 | from scipy import stats # Pearson 相関係数 + p値 r, p = stats.pearsonr(df['高齢化率'], df['死亡率']) print(f"r = {r:.4f}, p = {p:.4f}") # r = 0.9720, p = 0.0000 # Spearman 順位相関 + p値 rho, p = stats.spearmanr(df['高齢化率'], df['死亡率']) # Kendall タウ + p値(外れ値にさらに頑健) tau, p = stats.kendalltau(df['高齢化率'], df['死亡率']) |
1 2 3 4 5 6 7 8 9 10 | import seaborn as sns # 相関行列をヒートマップで可視化 sns.heatmap(df.corr(), annot=True, cmap='RdBu_r', vmin=-1, vmax=1) # 散布図 + 回帰直線 + 信頼帯 sns.regplot(data=df, x='高齢化率', y='死亡率') # 散布図 + 周辺分布 sns.jointplot(data=df, x='高齢化率', y='死亡率', kind='reg') |
1 2 3 4 5 6 7 8 | import pingouin as pg # 単純な相関 + 95%CI + 効果量 pg.corr(df['高齢化率'], df['死亡率']) # 出力:n, r, 95% CI, p値, BF10, power が一気に表示 # 偏相関(高齢化率を制御) pg.partial_corr(data=df, x='求人倍率', y='死亡率', covar='高齢化率') |
x と y のいずれかに欠損があるペアは、 自動的に除外されます(scipy.stats.pearsonr)。 ただし、 欠損が「ランダムでない」場合(MNAR)、 推定値にバイアスが入ります。 欠損率が高い変数では多重代入法を検討。
「どの相関係数を使うべきか」を判断する実用フロー。 データの性質と分析目的で選び分けます。
| 手法 | 範囲 | 仮定 | 外れ値 | 非線形 |
|---|---|---|---|---|
| Pearson | -1〜+1 | 直線、 正規分布 | 弱い | 不可 |
| Spearman | -1〜+1 | 単調 | 強い | 単調なら可 |
| Kendall τ | -1〜+1 | 単調 | 非常に強い | 単調なら可 |
| 点双列 | -1〜+1 | 二値 vs 連続 | 中 | 不可 |
| Cramér V | 0〜1 | カテゴリ × カテゴリ | — | 関係なし |
| 相関比 η | 0〜1 | なし | 中 | 非単調OK |
「Pearson と Spearman を併記」が現代の標準。 両者の値がほぼ同じ → 直線関係。 大きく違う → 単調曲線関係 or 外れ値影響、 と診断できます。
相関を扱うときに最も警戒すべき論理の罠の一つ。 同じデータでも、 集計方法によって相関の符号が逆転する現象。
カリフォルニア大学バークレー校(1973年):大学院全体で見ると 男性のほうが合格率が高い → 「性別による差別では?」と訴訟になった。
ところが学部別に集計すると、 多くの学部で女性の合格率の方が高かった!
なぜか:女性は合格率の低い学部(人文系)に多く出願し、 男性は合格率の高い学部(工学系)に多く出願していた。 集計レベルで「学部」という第3変数の影響が消えると、 逆の結論になります。
47都道府県データでも同様の罠がある可能性:
対策:階層構造のあるデータでは、 集計レベルごとに相関を計算し、 結果を比較する(マルチレベル分析)。
「全体での相関」と「部分での相関」は違う符号になることがある。 集計レベルを変えて確認するのが、 観察データを扱うときの最重要技術。 平均的議論で陥りやすい落とし穴。
機械学習で予測モデルを作るとき、 相関係数は2つの方向で活躍します:
説明変数候補が100個あるとき、 全部使うのではなく重要なものだけ選びたい。 「目的変数との相関が高い変数を選ぶ」のが古典的アプローチ:
1 2 3 4 5 6 7 | # 目的変数(ここでは死亡率)と、他のすべての列との相関を一気に見る target = '死亡率' correlations = df.drop(columns=[target]).apply(lambda x: x.corr(df[target])) # 絶対値が大きい順に並べる(相関が強い説明変数の候補) top_features = correlations.abs().sort_values(ascending=False).index print(correlations[top_features].round(3)) |
ただしこれは線形な関係のみを見るため、 ランダムフォレストの feature_importance や SHAP の方が頑健。
説明変数同士が強く相関していると、 重回帰の係数が不安定になります(多重共線性)。 事前に相関ヒートマップで確認:
1 2 3 4 5 6 7 8 9 10 11 12 13 | import seaborn as sns import matplotlib.pyplot as plt # 説明変数間の相関ヒートマップ corr = X.corr() sns.heatmap(corr, annot=True, cmap='RdBu_r', vmin=-1, vmax=1) # 0.7以上の相関があるペアを抽出 high_corr_pairs = [] for i in range(len(corr.columns)): for j in range(i+1, len(corr.columns)): if abs(corr.iloc[i, j]) > 0.7: high_corr_pairs.append((corr.columns[i], corr.columns[j], corr.iloc[i, j])) |
|r| > 0.7 のペアは要警戒。 一方を落とすか、 PCA で合成変数にする検討を。
相関が弱い変数同士を組み合わせて、 新しい特徴量を作る:
新しい特徴量が目的変数と相関するかチェックすることで、 有用な特徴量を発見できます。
「目的変数との相関が高い = 予測に有用」とは限りません。 (i) 外れ値で相関が膨らんでいる、 (ii) 非線形関係で相関は弱いが予測に有用、 (iii) 多変量で見ると重要な変数を見逃す、 などの罠があります。
機械学習では「相関」と「実際の予測精度(CV スコア)」をセットで判断するのが鉄則。
2変数の相関は強力ですが、 実データでは変数が3つ以上あるのが普通。 そんなときに使うのが相関行列と、 それを色で可視化したヒートマップ。 機械学習の前処理でも頻繁に使う、 毎日使う道具です。
SSDSE-B-2026 から、 2023年の47都道府県データ(家計調査)から4変数を選びました。
n = 47都道府県(一部欠損あり)。 これら4変数間で16通りの相関を一度に計算します(自分との相関4個は1.000、 対称なので独立な値は6個)。
4変数の全組合せを4×4のグリッドで一気に可視化したのが散布図行列。 seaborn の sns.pairplot() でよく作るタイプ。
読み方:
4変数なら 4×3/2 = 6 ペア、 10変数なら 45 ペアの関係を一度に把握できる強力な道具です。
相関係数だけを色マトリクスとして可視化したのがヒートマップ。 多変数(10〜30変数)でもパッと全体像が見える、 もっとも使う相関可視化です。
ヒートマップの読み方(3ステップ):
| 消費支出 | 食料費 | 住居費 | 教育費 | |
|---|---|---|---|---|
| 消費支出 | 1.000 | 0.679 *** | 0.081 n.s. | 0.575 *** |
| 食料費 | 0.679 *** | 1.000 | -0.003 n.s. | 0.728 *** |
| 住居費 | 0.081 n.s. | -0.003 n.s. | 1.000 | -0.026 n.s. |
| 教育費 | 0.575 *** | 0.728 *** | -0.026 n.s. | 1.000 |
*** p<0.001、 ** p<0.01、 * p<0.05、 n.s. 有意でない
💡 解釈の注意:これらは都道府県レベルの相関。 「個人で消費支出が大きい人は教育費も大きいか」とは別問題です(生態学的誤謬 ecological fallacy)。 個票データなら別の分析が必要。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 家計4変数を選ぶ X = df[['消費支出', '食料費', '住居費', '教育費']].dropna() # ① 散布図行列(pairplot) sns.pairplot(X, kind='reg', diag_kind='hist', plot_kws={'scatter_kws': {'alpha': 0.5}}) plt.suptitle('家計4変数の散布図行列', y=1.02) plt.show() # ② 相関行列とヒートマップ R = X.corr() # Pearson 相関行列(4×4 DataFrame) print(R.round(3)) plt.figure(figsize=(7, 5)) sns.heatmap(R, annot=True, fmt='.3f', cmap='RdBu_r', vmin=-1, vmax=1, square=True, cbar_kws={'label': '相関係数 r'}) plt.title('相関係数ヒートマップ') plt.tight_layout() plt.show() |
vmin/vmax で変わる。 必ず 数値を表示(annot=True)sns.clustermap() なら相関の似た変数を自動でグルーピングして並び替えてくれる(高次元データで便利)df.corr(method='spearman') で順位相関に切り替え。 非線形・外れ値ありなら Spearman を併記df.dropna() で完全ケースのみにするか、 df.corr(min_periods=...) でペアごとに計算するか標本データで r = 0.6 と出ても、 「母集団でも本当に相関があるのか」「偶然この標本だけそう見えただけじゃないか」が問題です。 これに答えるのが相関の有意差検定。 実務でも論文でも最頻出。
「相関がない(無相関)」を帰無仮説 H₀ として、 「相関がある」と言えるかを判定します:
H₀: ρ = 0(母相関係数はゼロ。 つまり相関なし)
H₁: ρ ≠ 0(相関がある。 両側検定)
Pearson 相関の検定では、 r を t分布に変換します:
$$ t = \frac{r \sqrt{n-2}}{\sqrt{1 - r^2}} \sim t(n-2) $$
読み方:
この t は自由度 n−2 の t分布に従うため、 p値が計算できます。
「食料費 と 消費支出」の場合(47都道府県):
p < 0.001 なので、 「相関係数 = 0」という帰無仮説は強く棄却される → 「相関がある」と結論づけられます。
| 標本サイズ n | r = 0.2 で有意? | r = 0.4 で有意? | r = 0.6 で有意? |
|---|---|---|---|
| 10 | p=0.5796 ❌ n.s. | p=0.2521 ❌ n.s. | p=0.0667 ❌ n.s. |
| 20 | p=0.3979 ❌ n.s. | p=0.0806 ❌ n.s. | p=0.0052 ✅ 有意 |
| 50 | p=0.1638 ❌ n.s. | p=0.0040 ✅ 有意 | p=0.0000 ✅ 強く有意 |
| 100 | p=0.0460 ✅ 有意 | p=0.0000 ✅ 強く有意 | p=0.0000 ✅ 強く有意 |
| 500 | p=0.0000 ✅ 強く有意 | p=0.0000 ✅ 強く有意 | p=0.0000 ✅ 強く有意 |
💡 大事な観察:n が大きいと小さい相関でも有意になります(n=500 なら r=0.2 でも p < 0.001)。 逆に n が小さいと、 強い相関でも有意にならないことが(n=10, r=0.6 でも p > 0.05)。 「有意」≠「効果が大きい」。 効果の大きさは r 自体で判断、 有意性は「偶然じゃない」と保証する補助情報。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | from scipy import stats # Pearson 相関 + p値(両側検定) r, p = stats.pearsonr(X['食料費'], X['消費支出']) print(f'r = {r:.3f}, p = {p:.4e}') # Spearman 順位相関 + p値 rho, p_s = stats.spearmanr(X['食料費'], X['消費支出']) print(f'rho = {rho:.3f}, p = {p_s:.4e}') # Kendall τ + p値 tau, p_k = stats.kendalltau(X['食料費'], X['消費支出']) print(f'tau = {tau:.3f}, p = {p_k:.4e}') # 行列全部のp値を計算 import pandas as pd import numpy as np def corr_pvalue_matrix(df, method='pearson'): cols = df.columns n = len(cols) p_mat = pd.DataFrame(np.zeros((n, n)), columns=cols, index=cols) fn = {'pearson': stats.pearsonr, 'spearman': stats.spearmanr, 'kendall': stats.kendalltau}[method] for i in range(n): for j in range(n): if i != j: _, pv = fn(df.iloc[:, i], df.iloc[:, j]) p_mat.iloc[i, j] = pv return p_mat P_matrix = corr_pvalue_matrix(X) print(P_matrix.round(4)) |
10変数の相関行列は 45ペアの検定をしています。 p=0.05 の有意水準で偶然に有意になるものが平均 45 × 0.05 = 2.25 個出てしまう!
これを防ぐのが多重比較補正:
statsmodels.stats.multitest.multipletests(p, method='fdr_bh')⚠️ 探索的に相関行列の星マークから「面白い相関」を選んで論文化するのは p-hacking の温床。 多重比較補正をかけるか、 事前登録(pre-registration)で防ぐのが現代のベストプラクティス。
結果を書くときの標準的フォーマット:
「食料費と消費支出には中程度〜強い正の相関が認められた(r = 0.679、 p < .001、 n = 47)。」
含めるべき情報:(1) 相関係数 r、 (2) p値、 (3) 標本サイズ n。 信頼区間まで書くと完璧(後述の Fisher's z変換を使う)。
相関係数 r 自体は分布が歪んでいるので、 直接信頼区間は作れません。 Fisher's z変換で正規分布に近づけてから計算:
$$ z = \frac{1}{2} \ln\frac{1+r}{1-r}, \quad SE(z) = \frac{1}{\sqrt{n-3}} $$
z の95%信頼区間: z ± 1.96 × SE(z)、 これを逆変換すれば r の95%CI が得られます。
1 2 3 4 5 6 7 8 9 10 11 12 | import numpy as np from scipy.stats import norm def corr_ci(r, n, alpha=0.05): z = np.arctanh(r) # Fisher's z変換 se = 1 / np.sqrt(n - 3) z_crit = norm.ppf(1 - alpha/2) lo, hi = z - z_crit*se, z + z_crit*se return np.tanh(lo), np.tanh(hi) # 逆変換 ci_low, ci_high = corr_ci(r=0.679, n=47) print(f'95%CI: [{ci_low:.3f}, {ci_high:.3f}]') |
信頼区間がゼロを含めば「相関なし」を棄却できない、 含まなければ「相関あり」と結論できる。 p値と一致しますが、 効果の大きさの範囲も同時に分かるため近年は信頼区間表記が推奨されています。
相関係数 がデータサイエンスの体系の中でどこに位置するかを、 3つの異なる視点で可視化します。 同じ情報でも見方を変えると気付きが変わります。
🌐 統計・データサイエンス › 関連・回帰 › 相関 › 相関係数
中心に 相関係数 を置き、 そこから 共分散・Spearman相関・平均・標準偏差・散布図・単回帰 など 計 19 個の用語へ、 前提・兄弟・発展形といった関係を矢印で結んでいます。 線がどちら向きかを見れば、 先に読むべき用語とあとから読む用語が分かります。 ノードはドラッグで動かせ、 ホイールでズーム、 クリックでその用語のページへ遷移します。
大きな円が小さな円を包含する Circle Packing 図。 「相関係数」は緑色でハイライト。
長方形を入れ子に分割した Treemap 図。 各分野の規模感を面積で比較。 「相関係数」は緑色でハイライト。
| マップ | 分かること | こんな時に見る |
|---|---|---|
| 🔗 関係マップ | 手法間の横の関係(前提→発展→応用) | 「次に何を学べばよい?」 学習順序の判断 |
| ⭕ 包含マップ | 分類体系の入れ子構造(上位⊃下位) | 「この手法はどんなジャンルに属する?」 |
| 🌳 ツリーマップ | 分野の規模比較(面積=ボリューム) | 「データサイエンス全体の俯瞰像」 |
💡 ジャストインタイム学習のヒント:3つの視点を行き来することで、 概念を多角的に理解できます。 包含マップやツリーマップはズーム/ドリルダウンで大分類から細部まで探索できます。
分析中に「思った結果が出ない」「解釈に迷う」とき、 まずは:
これでも解決しない場合は、 統計コンサル、 大学院の指導教員、 Cross Validated(Stack Exchange の統計版)などのコミュニティへ。