秩和檢驗(rank sum test)及其Python實現
不是成對的符號秩和檢驗
秩和檢驗
假設我們有兩組數據A和B,每組數據的樣本數爲何,我們想要檢驗的空假設是A與B具有相同的分佈。
首先我們給出秩的定義,如果將一組數據按從小到達排列,那麼某觀測值的順序就是該觀察值的秩。如假設有一組數據:1, 21, 9, 4, 3,將其按照從小到大的順序排列,結果爲1, 3, 4, 9, 21。那麼觀測值1的秩就是1,觀測值9的秩就是4,以此類推。Wilcoxon 秩和檢驗的統計量就是一組數據所有觀測值的秩的和。這裏,我們定義爲數據集A中的秩和。
例,收集到數據集如下:
A: 8.50,9.48,8.65,8.16,8.83,7.76,8.63
B: 8.27,8.20,8.25,8.14,9.00,8.10,7.20,8.32,7.70
將兩組數據混合在一起進行排序,得到序列:7.2 , 7.7 , 7.76, 8.1 , 8.14, 8.16, 8.2 , 8.25, 8.27, 8.32, 8.5 , 8.63, 8.65, 8.83, 9. , 9.48
則可以得到統計量
接下來的問題是如何得到統計量對應的p值。如果空假設成立,即A與B的數據來自同一分佈,那麼A中數據的秩應該均勻的,我們可以通過秩和檢驗表獲得,下面根據備選假設的討論如下:
- 如果備選假設是,那麼如果備選假設成立,,因而對應的p值爲
- 如果備選假設是,那麼如果備選假設成立,,因而對應的p值爲
- 對於備選假設,應該進行雙邊檢驗,如果偏小,對應的p值應該檢驗爲,如果偏大,對應的p值應該檢驗爲
其中通過查找秩和表得到。
Python實現
爲了更加直觀的理解秩和檢驗的過程,我們不適用查表的方法來得到,而是通過仿真的方法來獲得近似的的分佈。仿真的代碼如下:
import numpy as np
import matplotlib.pyplot as plt
a=np.array([8.50,9.48,8.65,8.16,8.83,7.76,8.63])
b = np.array([8.27,8.20,8.25,8.14,9.00,8.10,7.20,8.32,7.70])
c=np.hstack((a,b))
c.sort()
na = a.shape[0]
nb = b.shape[0]
# 仿真計算H0成立的前提下,WA的分佈
N = 100000
randrk = np.zeros((N,))
for i in range(N):
tmp = np.random.permutation(na+nb) + 1 #出現順序隨機,注意這裏需要加1
randrk[i] = tmp[:na].sum()
plt.hist(randrk, bins=10)
p = 2*randrk[randrk>=75].shape[0]/N # 雙邊檢驗的t值
#=> 0.1178
這裏我們觀測到的爲75,進行雙邊檢驗得到的p值爲:0.1178。我們與scipy.stats
庫中的秩和檢驗進行對比,代碼如下:
t, p = stats.ranksums(a, b) # p=>0.1
注意,這裏標準庫的算法假設數據量足夠大,利用近似服從正態分佈得到的結果。均值和方差如下: