2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

scipy.stats: 点双列相関係数 pointbiserialr

Posted at

scipy.stats: 点双列相関係数 pointbiserialr

特別な名前がついているが,ピアソンの積率相関係数において,片方の変数が 2 値データの場合ということである。

pointbiserialr は point biserial correlation coefficient r で,訳すと,点双列相関係数ということである。

2 値変数は連続変数なので(知らない人も多いかもしれないが),当たり前なのだが,その昔,計算環境が劣悪だった頃は,特別な場合に簡単な計算式で計算できるということで誕生したものかな。

普通に(数値に変換しなければならないかもしれないが) scipy.stats.pearsonr を使えばよい。

import numpy as np

a = np.array([0, 0, 0, 1, 1, 1, 1])
b = np.arange(7)

1. 点双列相関係数

pointbiserialr(x, y)

戻り値はピアソンの積率相関係数と無相関検定($H_0:\rho=0$)の両側検定の $p$ 値である。

from scipy.stats import pointbiserialr

pointbiserialr(a, b)
PointbiserialrResult(correlation=0.8660254037844387, pvalue=0.011724811003954626)

ちなみに,相関係数が $r$,サンプルサイズが $n$ のとき無相関検定の両側検定の $p$ 値は以下のように求められる。

from scipy.stats import t

def pvalue(r, n):
    return t.sf(abs(r) * np.sqrt(n - 2) / np.sqrt(1 - r**2), n-2) * 2 if r**2 != 0 else 1

pvalue(0.8660254037844387, len(a))
0.011724811003954614

2. ピアソンの積率相関係数

pearsonr(x, y)

戻り値はピアソンの積率相関係数と無相関検定($H_0: \rho = 0$)の両側検定の $p$ 値である。

from scipy.stats import pearsonr

pearsonr(a, b)
(0.8660254037844387, 0.011724811003954626)

3. numpy の corrcoef

numpy には corrcoef がある。

corrcoef(x, y=None, rowvar=True, bias=<no value>, ddof=<no value>, *, dtype=None)

np.corrcoef(a, b)[0,1]
0.8660254037844385

ちなみに,np.corrcoef() は相関係数行列を求めることができる。無相関検定の結果は得られない。

x = [[2,1,2,3,4], [3,2,1,2,3], [5,4,3,4,5], [2,1,3,4,5]]
r = np.corrcoef(x)
print(r)
[[1.         0.41931393 0.41931393 0.97072534]
 [0.41931393 1.         1.         0.18898224]
 [0.41931393 1.         1.         0.18898224]
 [0.97072534 0.18898224 0.18898224 1.        ]]

以下のような関数で $p$ 値の行列を求めることができる(前出の pvalue() を使用する)。

def r(x):
    k, n = np.array(x).shape
    p = np.ones((k, k))
    r = np.corrcoef(x)
    for i in range(k):
        for j in range(i+1, k):
            p[i, j] = p[j, i] = pvalue(r[i, j], n)
    return p

r(x)
array([[1.00000000e+00, 4.82198952e-01, 4.82198952e-01, 5.98625570e-03],
       [4.82198952e-01, 1.00000000e+00, 1.40426542e-24, 7.60820376e-01],
       [4.82198952e-01, 1.40426542e-24, 1.00000000e+00, 7.60820376e-01],
       [5.98625570e-03, 7.60820376e-01, 7.60820376e-01, 1.00000000e+00]])

4. φ 係数

ファイ係数は,2変数がともに 2 値データのときのピアソンの積率相関係数の絶対値に該当する。

さらに,2×2 分割表の場合には $\phi$ 係数は scipy.stats.contingency のデフォルトで得られる クラメールの $V$ に一致する。

import numpy as np
np.random.seed(1234)
from scipy.stats import uniform
x = uniform.rvs(size=100) > 0.5
y = uniform.rvs(size=100) > 0.5
import pandas as pd
df = pd.DataFrame({'x': x, 'y': y})
tbl = pd.crosstab(df['x'], df['y'])
print(tbl)
y      False  True
x                 
False     17    26
True      27    30
from scipy.stats.contingency import association

association(tbl)
0.07812845233116676
from scipy.stats import pearsonr

pearsonr(x, y)
(-0.07812845233116661, 0.43973315252059714)

なお,$\phi$ 係数に適切な符号を付けてピアソンの積率相関係数と同じにするには,分割表の 4 つのマス目の数値を a, b, c, d としたとき,$a\cdot d - b \cdot c$ の符号をつければよい。

例の場合だと 17*30 - 26*27 = -192 なので,0.07812845233116676 の符号は - である。

同じ分割表 tbl に基づく検定は,相関係数の検定の他に独立性の検定(いわゆる $\chi^2$ 検定)もある。同じ結果になるだろうか?

独立性の検定は scipy.stats.chi2_contingency で行える。
連続性の補正は correction で指定できる(デフォルトで  True)。
戻り値は,$\chi^2$ 値,$p$ 値,自由度,期待値行列である。

from scipy.stats import chi2_contingency
chi2_contingency(tbl)
(0.3338817445304601,
 0.5633822668015476,
 1,
 array([[18.92, 24.08],
        [25.08, 31.92]]))
chi2_contingency(tbl, correction=False)
(0.6104055063663398,
 0.43463517068036106,
 1,
 array([[18.92, 24.08],
        [25.08, 31.92]]))

同じ $p$ 値になるわけではないということか。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?