參數統計方法的局限
需要事先明確假定的總體分布: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:\360Downloads\Software\tableau\CCSS_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 |