統計的仮説検定

Pythonで相関分析|相関係数と散布図の求め方

記事内に広告が含まれています。

この記事でわかること

  • scipy.statsで相関係数とp値を同時に求める手順
  • ピアソンとスピアマンの使い分けと、Pythonでの書き分け
  • pandasで複数変数の相関を一括計算する方法と、散布図の描き方

📌 前提知識:Python統計解析入門|Excelとの使い分けと学び方を読んでいると理解しやすくなります

切削条件を振ったテストの結果が、手元に8条件ぶん溜まっているとします。速度を上げると表面粗さが良くなっている気配はあるものの、それを数字で示さないまま「たぶん効いています」と報告するわけにはいきません。

条件が8つなら電卓でも足りますが、これが製品ごと・ロットごとに何十回と続くなら話が変わります。この記事では、相関係数と散布図をPythonで求める手順を、切削速度と表面粗さの例題で整理します。

Pythonで相関分析をする場面

Pythonが効いてくるのは、次のような場面です。

  • 測定項目が多く、どの組み合わせに関係があるかを総当たりで見たいとき
  • 同じ分析をロット別・製品別に何度も繰り返すとき
  • 相関係数と有意性の判定を一度に出したいとき(Excelでは関数を分けて計算する必要がある)

NG例(△): 2変数の相関を1回だけ確認するなら、ExcelのCORREL関数のほうが早く終わります。手順は相関分析のやり方と結果の見方で解説しています。「繰り返すかどうか」が最初の判断基準です。

使うライブラリと役割

相関分析では次の3つを組み合わせます。

  • pandas:データの読み込みと整形。複数変数の相関行列も担当
  • scipy.stats:相関係数とp値の計算。pearsonrspearmanr
  • matplotlib:散布図の描画

読み込みはpandas、検定はscipy、作図はmatplotlibという役割分担を覚えておくと、コードが何をしているか追いやすくなります。

例題|切削速度と表面粗さ

切削速度を8水準に振り、そのときの表面粗さRaを測定したデータです。

切削速度 v(m/min) 表面粗さ Ra(μm)
100 3.3
120 3.0
140 2.9
160 2.5
180 2.6
200 2.2
220 2.0
240 1.9

まずデータを用意します。

import pandas as pd
from scipy import stats
import matplotlib.pyplot as plt

df = pd.DataFrame({
    "v":  [100, 120, 140, 160, 180, 200, 220, 240],
    "Ra": [3.3, 3.0, 2.9, 2.5, 2.6, 2.2, 2.0, 1.9],
})

ピアソンの相関係数を求める

ピアソンの相関係数は、共分散を2つの標準偏差で割って単位を消したものです。

\[r = \frac{\text{Cov}(X,Y)}{\sigma_X \sigma_Y}\]

Pythonでは scipy.stats.pearsonr が対応します。相関係数とp値が同時に返るのがExcelとの大きな違いです。

r, p = stats.pearsonr(df["v"], df["Ra"])
print(f"r = {r:.4f}")
print(f"p = {p:.6f}")

結果は r = −0.9826 です。マイナスなので、速度を上げると粗さの値が下がる(表面が滑らかになる)関係を示しています。決定係数 r² は0.9655で、粗さのばらつきの約97%が速度で説明できる計算です。

相関係数の大きさをどう解釈するかは相関係数の読み方|強弱の目安で解説しています。

スピアマンの順位相関係数を求める

外れ値があるときや、関係が直線的でないときはスピアマンを使います。値そのものではなく順位に置き換えて計算する方法です。

rho, p_s = stats.spearmanr(df["v"], df["Ra"])
print(f"rho = {rho:.4f}")

結果は rho = −0.9762 で、ピアソンの−0.9826とわずかに違います。この差が出た理由は、速度160と180のところで粗さが2.5→2.6と1か所だけ順位が入れ替わっているためです。

2つの値が大きく食い違う場合は、外れ値か曲線的な関係が隠れているサインです。手法の詳しい違いはスピアマン順位相関係数の求め方で扱っています。

散布図で形を確認する

相関係数だけを見て判断するのは危険です。数値が小さくてもU字型の関係が隠れていることがあるため、必ず散布図で形を見ます。

plt.scatter(df["v"], df["Ra"])
plt.xlabel("cutting speed (m/min)")
plt.ylabel("Ra (um)")
plt.grid(True)
plt.show()

軸ラベルに日本語を使うと文字化けすることがあるため、フォント設定をしていない環境では英字で書くほうが確実です。

複数変数の相関を一括で見る

測定項目が増えたときは、pandasの corr で総当たりの相関行列を一度に作れます。ここがPythonを使う利点の出やすいところです。

df.corr()              # ピアソン(既定)
df.corr(method="spearman")   # スピアマン

項目が10個あれば45通りの組み合わせですが、この1行で全部埋まります。Excelで同じことをする手順は相関行列の作り方で解説しています。

その相関が偶然でないかを確かめる

サンプル数が少ないと、本当は関係がなくても相関係数が大きく出ることがあります。pearsonr が返すp値がその判定に使えます。

判定のもとになる検定統計量は次の式です。

\[t = r\sqrt{\frac{n-2}{1-r^2}}\]

この式に今回の値を入れると、自由度は n−2 = 6、統計量は次のとおりです。

\[t = -0.9826 \times \sqrt{\frac{6}{1-0.9655}} \approx -12.96\]

自由度6・有意水準5%(両側)の臨界値は約2.447なので、これを大きく超えています。相関がないという仮説は棄却され、意味のある関係だと判断できます。pearsonr のp値も同じ結論を返します。

検定の考え方そのものは相関係数の有意性検定で詳しく解説しています。

よくある質問

Q. pearsonrが返すp値は何を意味していますか?

「母集団の相関がゼロだと仮定したとき、手元のデータ以上に強い相関が偶然出る確率」です。この値が有意水準(通常0.05)を下回れば、相関がないという仮説を棄却します。相関の強さそのものではない点に注意してください。

Q. 欠損値があるとエラーになります。

scipy.stats.pearsonr は欠損値を自動では除きません。df.dropna() であらかじめ取り除くか、pandasの corr を使います。corr は欠損のある行を組み合わせごとに自動で除外します。

Q. 相関が強ければ、原因と結果の関係だと言ってよいですか?

言えません。両方が第三の要因に影響されているだけのこともあります。今回の例でも、速度以外に工具の摩耗が同時に進んでいれば、その影響が混ざります。判断を分けたいときは偏相関係数を使います。

まとめ

  • 相関係数とp値は scipy.stats.pearsonr で同時に求まる。Excelと違い検定まで一度で終わる
  • 外れ値や非直線の関係が疑われるときは spearmanr。2つの値が食い違ったら散布図を確認する
  • 複数変数の総当たりは df.corr() の1行。項目が増えるほどPythonの利点が出る
  • 相関係数だけで判断せず、必ず散布図で形を見る

2変数を1回だけ確認するならExcel、項目が多いか繰り返すならPython、という使い分けです。どの相関手法を選ぶかで迷ったら相関分析総まとめ|手法の選び方と使い分けを先に読むと判断しやすくなります。さらに体系的に学びたい方向けに、レベル別のおすすめ書籍を統計学・実験計画法のおすすめ本まとめで紹介しています。

タイトルとURLをコピーしました