首先说什么是置换检验?
总体意思就是:对于两个样本,先计算两个样本的原始均值差,然后进行放回性的抽取样本操作,每一次抽取的时候,都计算两个组的均值差,这样有多少次抽样就有多少个均值差,然后看看有多少个均值差在实际均值差之上,也就是得到实际均值差在这里的位置,根据位置就得到了P值。因为多个均值差的排列接近正态分布。
适用范围:对于小样本试验,用T检验或者wilcox检验都有误差,不太准确,因而使用置换检验比较恰当。这里的小样本一般统计学情况下是指的10个,就是小于等于10个的样本建议使用置换检验而不是t检验。
当然,在核磁领域,一般都是用置换检验会更好一点。
介绍coin包:
- Exact Wilcoxon-Mann-Whitney test(wilcox检验):(wt <- wilcox_test(pd ~ age, data = diffusion, distribution = “exact”, conf.int = TRUE))
- 查看上述的检验值:statistic(wt, type = “linear”)
- expectation(wt);covariance(wt);pvalue(wt);confint(wt)。查看一些p值,置信区间
- kruskal_test(pd ~ age, data = diffusion, distribution = “exact”)
- Asymptotic Fisher-Pitman test(渐进的permutation test): oneway_test(pd ~ age, data = diffusion)
- Approximative (Monte Carlo) Fisher-Pitman test(蒙特卡洛法的近似置换检验):pvalue(oneway_test(pd ~ age, data = diffusion, distribution = approximate(nresample = 10000)))
- Exact Fisher-Pitman test(精确的置换检验):pvalue(ot <- oneway_test(pd ~ age, data = diffusion, distribution = “exact”))
- Exact Brown-Mood median test with different mid-scores(不同中位数的精确布朗情绪中位数测试):mt1 <- median_test(y ~ x, data = ex, distribution = “exact”)
- Approximative (Monte Carlo) Kruskal-Wallis test(蒙特卡洛法的近似Kruskal-Wallis检验):kruskal_test(length ~ site, data = yoy, distribution = approximate(nresample = 10000))
举例:
1 10:10
A = 20,34,67,53,12,13,55,89,73, 62
B = 23,45,12,56,23,67,22,66,65,41
student t 检验结果, 0.596
wilcox的结果 p=0.7334
精确的置换检验的结果 0.5987
模特卡洛模拟的置换检验结果 0.5942
可以看出,置换检验其实很有用,能比较多的降低p值,其结果接近甚至比t检验更小。
可能有的人会说,你这精确的置换检验比t检验还大。但是要明白,这是10个值的sample,这里的t是student t,它有比较严格的假设前提,但是一般实际情况下,你是没办法用student t的,因为范围不符合,只能用wilcox,这样p值就比较大了。而置换检验不要求假设前提,不要求数据分布,并且它计算出来的p都非常小,所以置换检验很有用,值得学习。
而精确的置换检验和蒙特卡洛模拟的置换检验差了一点点,很正常,因为蒙特卡洛模拟具有随机性。
本来想附上python的代码,但是发现python没有现成的permutation test包,这就很尴尬了,在统计方面还是R强。但其实自己写代码实现permutation test也很简单,就是把A和B合并成一个序列,从中放回的随机抽A个样本,计算A的均值和剩下样本的均值,然后计算均值差,重复10000次,再计算实际A和B的统计量差在这个的位置,就得到了p值。
附上网上别人的代码。
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
def exact_mc_perm_test(xs, ys, nmc):
n, k = len(xs), 0
diff = np.abs(np.mean(xs) - np.mean(ys))
zs = np.concatenate([xs, ys])
list=np.empty(nmc)
for j in range(999):
np.random.shuffle(zs)
list[j]=np.abs(np.mean(zs[:n]) - np.mean(zs[n:]))
k += diff < np.abs(np.mean(zs[:n]) - np.mean(zs[n:]))
return list
xs = np.array([24,43,58,67,61,44,67,49,59,52,62,50])
ys = np.array([42,43,65,26,33,41,19,54,42,20,17,60,37,42,55,28])
list_a=exact_mc_perm_test(xs, ys, 999)
print(list_a)
作者:qtey
链接:https://www.jianshu.com/p/2fdb3bd07b6f
来源:简书