相関係数#

ピアソンの積率相関係数#

ピアソンの積率相関係数

r=Cov(X,Y)σYσY
  • Cov(X,Y):XとYの共分散

  • σY,σY:XとYの標準偏差

ピアソンの積率相関係数(標本レベル)

r^=(xix¯)(yiy¯)(xix¯)2(yiy¯)2
  • r^:相関係数。r[1,1]

  • xi:標本における変数xの値

  • x¯:変数xの値の平均

  • yi:標本における変数yの値

  • y¯:変数yの値の平均

どうやって[1,1]の範囲に収まるよう正規化しているのか?#

結論:コーシー・シュワルツの不等式を確率変数にあてはめている。

前提:内積#

ベクトル空間(要素間の和と定数倍が定義された集合であり、和と定数倍の結果もまた集合の要素であるような集合)における内積について触れておく。

(参考)内積の定義

R 上のベクトル空間 V において、任意の2つのベクトル a,b に対して実数 a,b が定まり、次の(1)~(4)を満たすとき、a,bab の 内積 という。

(1) a,b=b,a

(2) a+b,c=a,c+b,c

(3) ka,b=ka,b(kR)

(4) a,a0 で,a,a=0a=0

また、内積a,bとノルムa=a,a についての定理のひとつで コーシー・シュワルツの不等式

|a,b|ababa,bab1a,bab1

というものが存在する。

なお、a,babコサイン類似度 と呼ばれ、ベクトル間の類似性を示すのでデータサイエンスの世界でよく使われる。

具体的な内積の例#

実数空間R上のベクトル空間における内積の定義を満たす関数の例は次の通り。x,yRnに対し、

x,y=i=1nxiyi

標本レベルの話#

n個の観測値からなるベクトル x=(x1,x2,,xn)y=(y1,y2,,yn) があるとする。

またそれらから平均値x¯,y¯を引いたベクトルを x¯=(x1x¯,x2x¯,,xnx¯)y¯=(y1y¯,y2y¯,,yny¯)とする。

標本共分散Cov^

Cov^=1Ni=1n(xix¯)(yiy¯)=1Nx¯,y¯

x,yそれぞれの標本標準偏差は

σ^x=1Ni=1n(xix¯)2=1Ni=1nx¯2=1Nx¯,x¯σ^y=1Ni=1n(yiy¯)2=1Ni=1ny¯2=1Ny¯,y¯

よって

r^=Cov^σ^xσ^y=1Nx¯,y¯1Nx¯,x¯1Ny¯,y¯=x¯,y¯x¯y¯

したがってコーシー・シュワルツの定理

1a,bab1

より、相関係数の範囲は[1,1]に収まる。

期待値と内積#

つづいて母集団レベルの話。

確率変数X,YL2空間の要素(確率空間上の二乗可積分な関数)とすると、その積の期待値E[XY]は内積の性質を満たす。

(1) X,Y=E[XY]=E[YX]=Y,X

(2) X+Y,Z=X,Z+Y,Z

(3) kX,Y=kX,Y(kR)

(4) X,X=E[X2]0 かつ E[X2]=0X=0 a.s.

相関係数の導出#

コーシー・シュワルツの不等式の内積a,b を確率変数A,Bの積の期待値 E[AB] に置き換える。ノルムは例えば確率変数XについてX=X,X=E[X2]と置き換える。こうしてコーシー・シュワルツの不等式を置き換えた

|E[AB]|2E[A2]E[B2]

を用いる。

A=(XE[X]),B=(YE[Y])

とおくと

|E[(XE[X])(YE[Y])]|2E[(XE[X])2]E[(YE[Y])2]|Cov(X,Y)|2Var(X)Var(Y)1Cov(X,Y)Var(X)Var(Y)1

幾何学的解説#

(出所:Pearson correlation coefficient - Wikipedia

注意点#

データの関係性をざっくり表すのが相関係数の良さだが、散布図でみると全然異なるデータであってもたまたま同じ相関係数になることがある。また外れ値にひっぱられる特性もある。

下の図はアンスコムの例と呼ばれる、線形回帰をしたときに同じ傾き係数になるデータセット。 相関係数だと線形回帰と違って切片部分がないため係数は若干異なるがだいたい同じになる。

Hide code cell source
import statsmodels.api as sm
import pandas as pd
anscombe = sm.datasets.get_rdataset("anscombe").data

import matplotlib.pyplot as plt
import seaborn as sns
fig, axes = plt.subplots(ncols=2, nrows=2, figsize=[8,8], dpi=70)
axes = axes.flatten()
fig.subplots_adjust(hspace=0.3)
for i in range(4):
    corr = anscombe.filter(regex=f"{i+1}").corr().iloc[0,1]
    sns.regplot(data=anscombe, x=f"x{i+1}", y=f"y{i+1}", ax=axes[i],
                ci=None, scatter_kws={"s": 50, "alpha": 0.7})
    axes[i].set(title=f"corr = {corr:.3f}")
../_images/eb74a7dc27c8ee0544701ccf4007eb5cdd322b852637dfe47d6654ae3946b0db.png