python秩和检验
1 Python中的秩和检验
https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.ranksums.html
1.1 scipy.stats.ranksums说明
wilcoxon秩和检验的原假设(H0)是两组数据来自相同的分布(即两组数据没有显著差异)。对应的备择假设(H1)为两组数据中的有一组比另一组大(即两组数据存在显著差异)。
1.1.1 输入参数
x和y是要比较的两组数据。x和y的数据量可以不相同。
alternative表示备择假设的情况。默认alternative = ‘two-sided’。
- alternative = ‘two-sided’ 表示备择假设(H1)为两组数据有显著差异;
- alternative = ‘less’表示备择假设(H1)为 x<y;
- alternative = ‘greater’ 表示备择假设(H1)为 x>y;
其中,alternative = ‘two-sided’称为双边检验,在这种模式下,只能判断x和y有没有差别,不能判断x和y哪个大。alternative = ‘less’ 和alternative = ‘greater’ 称为单边检验,可以判断x和y哪一个更大。
1.1.2 输出参数
输出参数是统计量和p值。根据p值判断是接受H0还是接受H1。p>0.05表示接受原假设H0,p<0.05表示拒绝原假设(接受备择假设H1)。
1.2 python测试
import random
import scipy.stats as ss
x = [random.random() for i in range(8)]
# x = [0.16910235172664467, 0.2020437094569132, 0.6924720854383165, 0.5262249846925307, 0.7309038310126759, 0.972498016667232, 0.6576645372688086, 0.6169914457716444]
y = [random.random() + 5 for i in range(10)]
# y = [5.060202647284982, 5.7298963211653895, 5.0386386764253155, 5.625106039575542, 5.962911362302517, 5.731971211803443, 5.4344784457821005, 5.6345062250337, 5.847658639360786, 5.7380763398004735]
stats1, p1 = ss.ranksums(x,y,alternative='two-sided')
stats2, p2 = ss.ranksums(x,y,alternative='greater')
stats3, p3 = ss.ranksums(x,y,alternative='less')
print('p1:',p1)
print('p2:',p2)
print('p3:',p3)
运行结果如下:
p1 < 0.05 :说明拒绝原假设H0,接受备择假设H1,结论是x和y有显著差异
p2 > 0.05:说明接受原假设H0,拒绝备择假设H1,结论是x不是比y大
p3 < 0.05:说明拒绝原假设H0,接受备择假设H1,结论是x比y小
- 注意到,p1和p2的结论相结合,与p3的结论是一致的。而如果只看p2,只能说明x不比y大,并不能说明x比y小。
2 Python和Matlab秩和检验的对比
在Matlab中对上述相同的x和y进行检验,运行秩和检验函数ranksum()函数,发现得到的p值不一样:
x = [0.16910235172664467, 0.2020437094569132, 0.6924720854383165, 0.5262249846925307, 0.7309038310126759, 0.972498016667232, 0.6576645372688086, 0.6169914457716444]
y = [5.060202647284982, 5.7298963211653895, 5.0386386764253155, 5.625106039575542, 5.962911362302517, 5.731971211803443, 5.4344784457821005, 5.6345062250337, 5.847658639360786, 5.7380763398004735]
[p,h] = ranksum(x,y)
得到以下结果:
matlab中默认进行双边检验,但是得到的p值和上述python中ranksums()函数结果中的p1是不一样的。查阅了一些资料,发现python的ranksums()和matlab中的ranksum()p值的计算方式略有区别。参考matlab的ranksum和python scipy包下的ranksum分析
要想在python中得到和matlab一样的p值,需要用scipy.stats.mannwhitneyu()函数:
import scipy.stats as ss
x = [0.16910235172664467, 0.2020437094569132, 0.6924720854383165, 0.5262249846925307, 0.7309038310126759, 0.972498016667232, 0.6576645372688086, 0.6169914457716444]
y = [5.060202647284982, 5.7298963211653895, 5.0386386764253155, 5.625106039575542, 5.962911362302517, 5.731971211803443, 5.4344784457821005, 5.6345062250337, 5.847658639360786, 5.7380763398004735]
stats_m,p_m = ss.mannwhitneyu(x,y,alternative='two-sided')
print('p_m:',p_m)
这时得到的结果就是完全一样的。
- 综上所述,虽然python的ranksums()和matlab的ranksum()计算的p值有差异,但是不影响结论,两者得到的结论是一致的。