相関係数

相関係数の中で一番よく使われるのは、Pearson(ピアソン)の(積率)相関係数です。これは、二つのベクトルを、平均が 0、長さが 1 になるように標準化したものの内積で、取り得る値は $-1$ から $1$ までです。

例えば $x = (1,2,3,4,5)$、$y = (1,3,2,5,4)$ について、平均が 0 になるようにそれぞれから 3 を引いて $x' = (-2,-1,0,1,2)$、$y' = (-2,0,-1,2,1)$ とすると、長さの2乗はどちらも $(-2)^2 + (-1)^2 + 0^2 + 1^2 + 2^2 = 10$ ですから、それぞれを $\sqrt{10}$ で割って長さを 1 にします。内積 $((-2)(-2) + (-1)0 + 0(-1) + 1\cdot 2 + 2\cdot 1) / 10 = 0.8$ が相関係数です。式で書けば次のようになります:

\[ r = \frac{\sum (x_i - \bar{x})(y_i - \bar{y})}{\sqrt{\sum (x_i - \bar{x})^2} \sqrt{\sum (y_i - \bar{y})^2}} \]

Python で相関係数を計算する方法はいくつかあります。NumPy を使う方法:

import numpy as np

x = [1, 2, 3, 4, 5]
y = [1, 3, 2, 5, 4]
np.corrcoef(x, y)
array([[1. , 0.8],
       [0.8, 1. ]])

このように相関係数の行列を出力します。

pandas で求める方法:

import pandas as pd

df = pd.DataFrame({"x": x, "y": y})
df.corr()
     x    y
x  1.0  0.8
y  0.8  1.0

これも行列の形で出力します。オプションで Kendall や Spearman の相関係数も求められます。また、df.corrwith() という関数もあります。

SciPy では scipy.stats.pearsonr を使います:

from scipy import stats

r = stats.pearsonr(x, y)
r
PearsonRResult(statistic=0.8, pvalue=0.10408803866182785)

このように $p$ 値も出力します。それぞれの値は r.statisticr.pvalue として取り出せます。95% 信頼区間も求められます:

r.confidence_interval()
ConfidenceInterval(low=-0.279640041969355, high=0.9861961933012714)

これも下限・上限を r.confidence_interval().lowr.confidence_interval().high で取り出せます。

Python 3.10 以降の標準ライブラリ statistics にも相関係数を求める関数が追加されました:

import statistics as st

st.correlation(x, y)
0.8