参数统计方法的局限
需要事先明确假定的总体分布:t检验,方差分析
总体分布未知,或分布不符合要求时无法使用,比如时间明显是偏态分布的
结果为有序分类变量时无法使用
样本数据两端有不确定值,比如实验测含量,含量很低时无法用精确数值表示,只能说小于某个数值
非参数分析方法的特点
不依赖总体分布的具体形式
不是对分布参数进行估计或者假设检验,而是对总体的分布位置/形状进行估计或者假设检验
适用范围广,几乎用于任何情况
当资料符合参数检验方法的适用条件时,使用非参数方法的检验效能较低,效能最高的秩和检验效能可达到参数方法的90%~95%
非参方法的两种分类
分布类型/形状的检验方法,亦称为拟合优度检验方法,检验样本所在总体是否服从已知的理论分布
多项分类变量分布的卡方检验
二项分类变量分布的二项分布检验
考察连续变量是否服从各种常用分布的单样本K-S检验
检验样本序列随机性的Runs(游程)过程
分布的中心位置的检验方法,检验样本所在的总体的分布位置(集中趋势)是否相同,平时说的非参数检验方法实际上就是指这一类方法
两个独立样本/多个独立样本中心位置的检验
秩和检验:用的最多,检验效能最高
中位数检验:检验效能很低,一般不用
两样本的K-S检验:不只是检验集中趋势,同时考察总分分布情况
两相关样本(配对)/多个相关样本中心位置(配伍)的检验
配对秩和检验
配伍Friedman双向秩方差分析:校验效能很低,实际使用价值不大
非参数检验的一些概念
首先明确数据确实无法使用效率更高的参数方法
可以考虑使用的信息量
中位数:大于/小于基于H0的中位数的样本个数分布是否均匀
次序关系:数值和中位数的距离可以提供进一步的信息
顺序统计量:非参数检验的理论基础
通过对数据从小到大排序,并用排序号代替原始数值进行统计分析
秩(Rank):排序号在统计学上称为秩(秩次)
结(ties):绝对值相等称为结,又称同秩,一般取平均秩次
成组样本比较的非参数方法
Wilcoxon两样本秩和检验
H0:两总体所在中心位置相等,中位数可以代表中心位置,但是只使用中位数的话信息量太少
基于H0假定:混合编秩,分组求秩和
考察各组秩和的大小是否明显偏离H0
在非参数检验方法中效能最高
Mann-Whitney U:大u检验使用更多,计算效能更高
大样本下基本等价于两样本秩和检验
可近似理解为基于秩次进行了两样本的t检验
Kolmogorov-Smirnov Z
两样本的K-S检验,检验效能不高
考察的是整个分布是否相同,而不是只针对中心位置,即使中心位置相同也会得出总体分布不一致的结论
Kruskal-Wallis H检验
本质上就是基于秩次的单因素方差分析,可用于两组或者多组
多组比较的事后两两比较
本质上仍需要考虑如何控制总的一类错误
样本量较小时,因为非参本身会损失样本信息,所以统计学家倾向于不做检验水准的校正
import scipy.stats as ss # 两两比较的非参数方法 # ss.median_test() 中位数检验,两组或者多组时均可使用 # ss.ranksums(a, b) wilcox秩和检验,相对使用较少 # ss.mannwhitneyu(a, b, use_continuity, alternative) a,b要比较的序列值,use_continuity是否进行连续性的校正,默认true,大样本无所谓小样本一定要,alternative指的是进行单侧还是双侧 # ss.ks_2samp(data1, data2) 两样本ks检验 ss.mannwhitneyu(ccss.Qa3[ccss.s7=='未婚'], ccss.Qa3[ccss.s7=='已婚']) # statistic大u统计量
MannwhitneyuResult(statistic=121516.5, pvalue=0.0016970638386570689)
ss.ranksums(ccss.Qa3[ccss.s7=='未婚'], ccss.Qa3[ccss.s7=='已婚']) # p值同大u相比有变化,但是给出的统计结论是相同的
RanksumsResult(statistic=2.7604079036339764, pvalue=0.005772923211835386)
vss.median_test(ccss.Qa3[ccss.s7=='未婚'], ccss.Qa3[ccss.s7=='已婚']) # p值大于0.05,统计结论跟大u相反,可见检验效能非常低,尽量少使用
(2.6726310409335143, 0.10208713262673606, 100.0, array([[158, 321], [185, 469]], dtype=int64))
ss.ks_2samp(ccss.Qa3[ccss.s7=='未婚'], ccss.Qa3[ccss.s7=='已婚']) # ks检验的是总体分布的形状是否一致,在空间上找两个分布差异最大的作为检验统计量,因此检验效能较低,很浪费样本信息量
Ks_2sampResult(statistic=0.07164630770934052, pvalue=0.16475982515811638)
# 多组样本比较 # ss.kruskal(sample1, sample2,.....,nan_policy='propagate') # propagate,缺失值处理 ss.kruskal(ccss.query("s0 =='北京' & time=='200704'").Qa3, ccss.query("s0 =='北京' & time=='200712'").Qa3, ccss.query("s0 =='北京' & time=='200812'").Qa3, ccss.query("s0 =='北京' & time=='200912'").Qa3 ) # p值显示四组中是有差异的,所以要进行事后的两两比较
KruskalResult(statistic=11.773756778518651, pvalue=0.008199757256201149)
# 事后的两两比较 ss.mannwhitneyu(ccss.query("s0 =='北京' & time=='200704'").Qa3, ccss.query("s0 =='北京' & time=='200712'").Qa3)
MannwhitneyuResult(statistic=4576.5, pvalue=0.11076591017086002)
ss.mannwhitneyu(ccss.query("s0 =='北京' & time=='200704'").Qa3, ccss.query("s0 =='北京' & time=='200812'").Qa3) # 这两组有区别
MannwhitneyuResult(statistic=4108.0, pvalue=0.0047485836175626865)
ss.mannwhitneyu(ccss.query("s0 =='北京' & time=='200704'").Qa3, ccss.query("s0 =='北京' & time=='200912'").Qa3)
MannwhitneyuResult(statistic=3543.5, pvalue=0.24866367569455522)
连续型变量两配对样本比较:wilcoxon符号秩检验,一般不是用的很多,因为连续型变量一般都不违反正态性等,可以使用参数方法
求出各组配对差值
基于H0假定成立,差值应当围绕0上下对称分布
按照差值绝对值计算秩次,然后分正、负组分别计算秩和
考察正负秩和的大小是否明显偏离H0
配伍样本比较的非参方法
Fridman双向秩方差分析,校验效能差,只使用于连续型分类变量或者有序分类变量
Kendall`s W 主要用于计算Kendall和协系数,用于表示K个指标间的关联程度
Cochran`s Q 是McNemar检验针对多组的推广,只适用于两分类资料
# 配对样本非参方法实现 # ss.wilcoxon(a, b, zero_method='wilcox', correction=False) # zero_method参数,pratt检验中包含0差值相对保守,wilcox丢弃0差值,一般选这个作为检验效能低的补偿,zsplit将0差值对半分入两组 ccss_p = pd.read_excel(r"E:360DownloadsSoftware ableauCCSS_Sample.xlsx", sheet_name='CCSS_pair') ccss_p.head()
time | id | s2 | s3 | Qa3 | Qa4 | Qa8 | Qa10 | Qa16 | index1 | index1a | index1b | Qa3n | Qa4n | Qa8n | Qa10n | Qa16n | index1n | index1an | index1bn | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 200704 | 22 | 2 | 59 | 100 | 100 | 100 | 100 | 50 | 70.296024 | 66.026939 | 72.642743 | 50 | 100 | 100 | 100 | 100 | 70.296024 | 66.026939 | 72.642743 |
1 | 200704 | 40 | 2 | 28 | 150 | 150 | 150 | 150 | 100 | 109.349371 | 110.044898 | 108.964114 | 150 | 100 | 100 | 200 | 100 | 101.538702 | 110.044898 | 96.856991 |
2 | 200704 | 45 | 1 | 55 | 100 | 50 | 50 | 100 | 200 | 78.106694 | 132.053878 | 48.428495 | 150 | 100 | 150 | 150 | 100 | 101.538702 | 110.044898 | 96.856991 |
3 | 200704 | 69 | 1 | 26 | 150 | 200 | 150 | 50 | 100 | 101.538702 | 110.044898 | 96.856991 | 150 | 100 | 150 | 200 | 200 | 124.970710 | 154.062858 | 108.964114 |
4 | 200704 | 98 | 1 | 63 | 100 | 200 | 150 | 150 | 100 | 109.349371 | 88.035919 | 121.071238 | 150 | 150 | 100 | 0 | 100 | 78.106694 | 110.044898 | 60.535619 |
ss.wilcoxon(ccss_p.Qa4, ccss_p.Qa4n)
WilcoxonResult(statistic=414.0, pvalue=0.02601583794073107)
ss.wilcoxon(ccss_p.Qa8, ccss_p.Qa8n)
WilcoxonResult(statistic=400.0, pvalue=0.03382421088468342)
ss.wilcoxon(ccss_p.Qa10, ccss_p.Qa10n)
WilcoxonResult(statistic=699.5, pvalue=0.6937576785525135)
# 配伍样本,frifriedman卡方检验,至少需要提供三组数据 ss.friedmanchisquare(ccss.query("s0=='北京' & time=='200704'").Qa4[:10], ccss.query("s0=='北京' & time=='200712'").Qa4[:10], ccss.query("s0=='北京' & time=='200812'").Qa4[:10], ccss.query("s0=='北京' & time=='200912'").Qa4[:10], )
FriedmanchisquareResult(statistic=5.833333333333344, pvalue=0.12000654765321411)
秩变换分析的基本原理
秩和检验方法都可以看作是基于H0假设求出秩次,然后对秩次完成相应的参数检验
秩变换分析方法,就是利用这一原理,基于H0假设成立的情况,先求原变量的秩次,然后使用秩次代替原变量进行参数分析
当样本量较大时,其分析结果和相应的非参数方法基本一致,差别在于秩变换没有做关于总体等的一些校正,所以p值会略有不同,但不影响结果
但是该方法可以进一步充分利用已知的参数方法,如多组样本的两两比较、多变量回归,从而大大扩展了非参数分析方法的范围
秩变换分析的优缺点
有点
使用范围广,样本量充足的情况下均可使用
分析结果更为稳健,不易受极端值的影响
缺点
检验效能相对稍低,存在信息损失,不适用于中小样本
而且其分析结果相对没有那么“定量”,毕竟其描述的是影响因素对因素对因变量秩次的作用,而不是对因变量本身的作用
# ss.rankdata(a, method='average') # method对结的处理方式,默认average取对应秩次的平均值最好不要对结的方式进行修改,min/max取对应秩次的最小/最大值,dense所有相同的数值只赋予一个秩次,随后继续流水编号,ordinal按照数值出现的顺序依次赋予不同的秩次 dfrank = ccss.loc[ccss.s0=='北京', ['time', 'Qa3']] dfrank.head()
time | Qa3 | |
---|---|---|
0 | 200704 | 100 |
1 | 200704 | 100 |
3 | 200704 | 150 |
5 | 200704 | 200 |
6 | 200704 | 100 |
# 编秩要基于H0假设 dfrank["qa"] = ss.rankdata(dfrank.Qa3) dfrank.head() ss.f_oneway(dfrank[dfrank.time==200704].qa3r, dfrank[dfrank.time == 200712].qa3r, dfrank[dfrank.time == 200812].qa3r, dfrank[dfrank.time == 200912].qa3r ) # 进行两两比较 import scikit_posthocs as sp sp.posthoc_conover(dfrank, val_col='qa3r', group_col='time', p_adjust='bonferroni')
200704 | 200712 | 200812 | 200912 | |
---|---|---|---|---|
200704 | -1.000000 | 1.000000 | 0.054946 | 1.000000 |
200712 | 1.000000 | -1.000000 | 1.000000 | 0.349435 |
200812 | 0.054946 | 1.000000 | -1.000000 | 0.010739 |
200912 | 1.000000 | 0.349435 | 0.010739 | -1.000000 |