scipy.stats.mstats.

pearsonr#

scipy.stats.mstats.pearsonr(x, y)[source]#

皮爾森相關係數與用於檢定無相關性的 p 值。

皮爾森相關係數 [1] 衡量兩個資料集之間的線性關係。p 值的計算依賴於每個資料集都呈常態分佈的假設。(關於輸入的非常態性對相關係數分佈的影響的討論,請參見 Kowalski [3]。)與其他相關係數一樣,此係數的值介於 -1 和 +1 之間,0 表示無相關性。-1 或 +1 的相關性表示精確的線性關係。

參數:
x(N,) 類陣列

輸入陣列。

y(N,) 類陣列

輸入陣列。

回傳值:
r浮點數

皮爾森相關係數。

p 值浮點數

雙尾 p 值。

警告:
ConstantInputWarning

如果輸入為常數陣列則會引發。在這種情況下未定義相關係數,因此會回傳 np.nan

NearConstantInputWarning

如果輸入「幾乎」為常數則會引發。如果 norm(x - mean(x)) < 1e-13 * abs(mean(x)),則陣列 x 會被視為幾乎為常數。在這種情況下,計算 x - mean(x) 中的數值誤差可能會導致 r 的計算不準確。

參見

spearmanr

Spearman 等級順序相關係數。

kendalltau

Kendall's tau,用於序數資料的相關性度量。

註解

相關係數的計算方式如下

\[r = \frac{\sum (x - m_x) (y - m_y)} {\sqrt{\sum (x - m_x)^2 \sum (y - m_y)^2}}\]

其中 \(m_x\) 是向量 x 的平均值,而 \(m_y\) 是向量 y 的平均值。

在 x 和 y 從獨立常態分佈中抽取的假設下(因此母體相關係數為 0),樣本相關係數 r 的機率密度函數為 ([1], [2])

\[f(r) = \frac{{(1-r^2)}^{n/2-2}}{\mathrm{B}(\frac{1}{2},\frac{n}{2}-1)}\]

其中 n 是樣本數,而 B 是 beta 函數。這有時被稱為 r 的精確分佈。這是 pearsonr 中用於計算 p 值的分布。此分佈是區間 [-1, 1] 上的 beta 分佈,其形狀參數 a = b = n/2 - 1 相等。就 SciPy 的 beta 分佈實作而言,r 的分佈為

dist = scipy.stats.beta(n/2 - 1, n/2 - 1, loc=-1, scale=2)

pearsonr 回傳的 p 值是雙尾 p 值。p 值大致表示一個不相關的系統產生資料集的機率,這些資料集的皮爾森相關性至少與從這些資料集計算出的相關性一樣極端。更精確地說,對於給定相關係數 r 的樣本,p 值是從零相關母體中抽取的隨機樣本 x' 和 y' 的 abs(r') 大於或等於 abs(r) 的機率。就上面顯示的 dist 物件而言,對於給定的 r 和長度 n,p 值可以計算為

p = 2*dist.cdf(-abs(r))

當 n 為 2 時,上述連續分佈未明確定義。可以將 beta 分佈的極限解釋為形狀參數 a 和 b 接近 a = b = 0,作為在 r = 1 和 r = -1 處具有相等機率質量的離散分佈。更直接地說,可以觀察到,給定資料 x = [x1, x2] 和 y = [y1, y2],並假設 x1 != x2 且 y1 != y2,則 r 的唯一可能值為 1 和 -1。由於長度為 2 的任何樣本 x' 和 y' 的 abs(r') 都將為 1,因此長度為 2 的樣本的雙尾 p 值始終為 1。

參考文獻

[1] (1,2)

「皮爾森相關係數」,維基百科,https://en.wikipedia.org/wiki/Pearson_correlation_coefficient

[2]

Student,「相關係數的可能誤差」,Biometrika,第 6 卷,第 2-3 期,1908 年 9 月 1 日,第 302-310 頁。

[3]

C. J. Kowalski,「關於非常態性對樣本積差相關係數分佈的影響」,皇家統計學會期刊。C 系列(應用統計),第 21 卷,第 1 期 (1972),第 1-12 頁。

範例

>>> import numpy as np
>>> from scipy import stats
>>> from scipy.stats import mstats
>>> mstats.pearsonr([1, 2, 3, 4, 5], [10, 9, 2.5, 6, 4])
(-0.7426106572325057, 0.1505558088534455)

如果 y = a + b*x + e,則 x 和 y 之間存在線性依賴關係,其中 a,b 是常數,而 e 是隨機誤差項,假設與 x 獨立。為了簡單起見,假設 x 是標準常態分佈,a=0,b=1,並讓 e 遵循平均值為零且標準差 s>0 的常態分佈。

>>> s = 0.5
>>> x = stats.norm.rvs(size=500)
>>> e = stats.norm.rvs(scale=s, size=500)
>>> y = x + e
>>> mstats.pearsonr(x, y)
(0.9029601878969703, 8.428978827629898e-185) # may vary

這應該接近於以下給定的精確值

>>> 1/np.sqrt(1 + s**2)
0.8944271909999159

對於 s=0.5,我們觀察到高度相關。一般來說,雜訊的較大變異數會降低相關性,而當誤差的變異數接近於零時,相關性會接近於 1。

重要的是要記住,除非 (x, y) 是聯合常態分佈,否則沒有相關性並不意味著獨立性。當存在非常簡單的依賴結構時,相關性甚至可能為零:如果 X 遵循標準常態分佈,則讓 y = abs(x)。請注意,x 和 y 之間的相關性為零。實際上,由於 x 的期望值為零,因此 cov(x, y) = E[x*y]。根據定義,這等於 E[x*abs(x)],由於對稱性,它為零。以下幾行程式碼說明了這個觀察結果

>>> y = np.abs(x)
>>> mstats.pearsonr(x, y)
(-0.016172891856853524, 0.7182823678751942) # may vary

非零相關係數可能會產生誤導。例如,如果 X 具有標準常態分佈,則當 x < 0 時定義 y = x,否則定義 y = 0。一個簡單的計算顯示 corr(x, y) = sqrt(2/Pi) = 0.797…,表示高度相關

>>> y = np.where(x < 0, x, 0)
>>> mstats.pearsonr(x, y)
(0.8537091583771509, 3.183461621422181e-143) # may vary

這是違反直覺的,因為如果 x 大於零,則 x 和 y 之間沒有依賴關係,如果我們對 x 和 y 進行抽樣,則大約在一半的情況下會發生這種情況。