環境:Windows 10 專業版
歸類:algorithm/mk
簡介:整理記錄Mann-Kendall趨勢檢驗算法,主要是趨勢分析和突變點分析。
重點:魏鳳英老師的《現代氣候統計診斷與預測技術》中關于Mann-Kendall的突變點計算E[Sk]公式與許多論文中的公式不一致,且按照書中數據和公式繪制的圖與書中的圖不一致。
Mann-Kendall檢驗是一種非參數檢驗(無分布檢驗),其優點是不要求樣本遵從一定的分布,也不受少數異常值的干擾。常用于對降水、徑流、氣溫和水質等要素時間序列變化趨勢和突變點分析。
1. 趨勢分析
MK檢驗是檢驗是否拒絕零假設(null hypothesis:H0),并接受替代假設(alternative hypothesis:H1):
H0:沒有單調趨勢
H1:存在單調趨勢
最初的假設是:H0為真,在拒絕H0并接受H1之前,數據必須要超出合理懷疑——要到達一定的置信度。
-
在MK檢驗中,原假設H0為時間序列數據(X1,X2,...Xn),是n個獨立的、隨機變量同分布的樣本;備選假設H1是雙邊檢驗,對于所有的i,j≤n,且i≠j,Xi和Xj的分布是不相同的,檢驗的統計量S計算如下:
其中,Xi、Xj分別為第i、j時間序列對應的觀測值,且i<j,sgn()是符號函數:
- 當n≥8時,統計量S大致的服從正態分布,在不考慮序列存在等值數據點的情況下,其均值E(S)=0,方差Var(S)=n(n-1)(2n+5)/18。標準化后的檢驗統計量Z計算如下:
在雙邊趨勢檢驗中,對于給定的置信水平(顯著性水平)α,若|Z|≥Z1-α/2,則原假設H0是不可接受的,即在置信水平α(顯著性檢驗水平)上,時間序列數據存在明顯的上升或下降趨勢。Z為正值表示上升趨勢,負值表示減少趨勢,Z的絕對值在大于等于1.645,1.96,2.576時表示分別通過了置信度90%,95%,99%的顯著性檢驗。計算過程:以α=0.1為例,Z1-α/2=Z0.95,查詢標準正態分布表Z0.95=1.645,故Z≥1.645時通過90%的顯著性檢驗,H0假設不成立,Z>0,序列存在上升趨勢。
-
方差Var簡化前計算公式:
減法后面方程式含義:將觀測到的數據按照相同元素進行分組,g為分組數,tp為每一組元素個數,之后分別計算求和。
舉例:如一組數據(1,1,2,2,2,3,4,4,4,4),其中可以分為4組,以(元素,元素個數)格式顯示,分別是(1,2個)、(2,3個)、(3,1個)、(4,4個),則g=4,依次帶入求和:2(2-1)(2×2+5)+3(3-1)(2×3+5)+1(1-1)(2×1+5)+4(4-1)(2×4+5),由公式可知,若序列中每個元素只出現一次,則求和部分結果為0,方差方程式就簡化為Var(S)=n(n-1)(2n+5)/18。 -
衡量趨勢大小的指標,用傾斜度β表示為:
median表示中位值,β為正值表示“上升趨勢”,β為負值表示“下降趨勢”。
2.突變檢測
設要素時間序列為X1,X2,...Xn,Sk表示第j個樣本Xj>Xi(1≤i≤j)的累計數,定義統計量Sk:
-
在時間序列隨機獨立的假定下,Sk的均值和方差分別為:
魏鳳英老師的《現代氣候統計診斷與預測技術》中關于Mann-Kendall的突變點計算E[Sk]公式是:k(k+1)/4。與很多發表的論文中公式都不一致,采用論文中公式。
-
將Sk標準化:
其中UF1=0,給定顯著性水平α,若|UFk|>Uα,則表明序列存在明顯的趨勢變化。所有UFk可組成一條曲線。將此方法引用到反序列,將反序列Xn,Xn-1,....,X1表示為X'1,X'2,....,X'n。
j表示第j個樣本Xj大于Xi(j≤i≤n)的累計數。當j'=n+1-j時,
j=r'j,則反序列的UBk為:
其中UB1=0。UBk不是簡單的等于UFk負值,而是進行了倒置再取負,此處UFk是根據反序列算出來的。
給定顯著性水平,若α=0.05,那么臨界值為±1.96,繪制UFk和UBk曲線圖和±1.96倆條直線再一張圖上,若UFk得值大于0,則表明序列呈現上升趨勢,小于0則表明呈現下降趨勢,當它們超過臨界直線時,表明上升或下降趨勢顯著。超過臨界線的范圍確定為出現突變的時間區域。如果UFk和UBk兩條曲線出現交點,且交點在臨界線內,那么交點對應的時刻便是突變開始的時間。
3.舉例說明
利用經典數據:用Mann-Kendall法檢測1900-1990年上海年平均氣溫序列,給出趨勢及突變點分析,給定的顯著性水平α=0.05,即U0.05=±1.96。
3.1 使用EXCEL分析
3.1.1 趨勢分析
步驟:(具體請參考附錄3中Excel表格)
1.初始化數據
A列A2“年份”,A3-A93放<年份值>,B2“平均氣溫”,B3-B93放<氣溫值>
B列B1“年份”,C1-CO1放<年份值>,B2“平均氣溫”,C2-CO2放<氣溫值>
簡單講,就是AB列空一行放年份和平均氣溫,然后通過EXCEL粘貼轉置成空一列在12行放置年份和平均氣溫,形成網格狀。
2.D3插入公式:
=D$2-$B3
然后在網狀格沿著D3對角線,全部粘貼復制,公式會自動變化。即在E4,F5,...,CO92上直接將公式粘貼復制。3.將第3行,D3后面的行直接應用D3公式,通過EXCEL往后填充。同樣,E4按行往后鼠標往后拖,自動填充。F5...,一直到CO92
4.最終填充完,會填充n(n-1)/2=91*90/2=4095個格子。C3和CO93是空的。
5.在CO列后面增加兩列,CP,CQ,分別填入公式:
=countif(D3:CO3,">0")
,=countif(D3:CO3,"<0")
,應用整列。6.計算S=CP列和-CQ列和=2561-1306=1255
7.令n=91,(從1900-1990共91年的數據),計算Var(S)=n(n-1)(2n+5)/18=85085
8.由于S>0,且n≥8,計算Z=(S-1)/sqrt(Var(s))=4.299
9.由于Z>2.576>0,所以趨勢向上,且通過了99%的顯著性檢驗。
傾斜度β分析
1.由上面計算出來D3-CO92區域的(Xj-Xi)值,將其分別除以(j-i),然后計算中位數即可
2.新增CR列,CR2填入“β值”,CS2-GD2填入1,2,3,....90的序列
3.在CS3填入公式:
=D3/CS2
,向后應用4.在CS3對角線分別填入
=E4/CS2
=F5/CS2
=G6/CS2
...暫時不能粘貼復制,然后直接按行填充5.在CR3填入公式:
=MEDIAN(CS3:GD3)
向下填充6.根據AB列年份、平均氣溫和CR列β值繪制雙坐標曲線。
7.β最低點和最高點分別表示氣溫變化劇烈的點,并非突變點。
3.1.2 突變分析
1.在A-M列分別存儲年份,平均氣溫,k,r,Sk,E(Sk),Var(Sk),UF(k),逆序列,r',S'k,UF'(k),UB(k)數據,以及輔助畫線列N、O列“α=0.05上限(1.96)”、“α=0.05下限(-1.96)”。
2.在k列一次輸入1,2,3,...,91
3.在r列輸入公式
=COUNTIF($B$2:B2,"<"&B3)
,r1=0,向下填充4.在Sk列輸入公式
=D3+E2
,S1=0,向下填充。5.在E(Sk)列輸入公式
=C3*(C3-1)/4
,E(S1)=0,向下填充。6.在Var(Sk)列輸入公式
=C3*(C3-1)*(2*C3+5)/72
,Var(S1)=0,向下填充。7.在UF(k)列輸入公式
=(E3-F3)/SQRT(G3)
,UF(1)=0,向下填充。8.在逆序列中輸入與平均氣溫順序相反的數據
9.在r'列輸入公式
=COUNTIF($I$2:I2,"<"&I3)
,r'1=0,向下填充。10.在S'k列輸入公式
=J3+K2
,S'1=0,向下填充。11.在UF'(k)列輸入公式
=(K3-F3)/SQRT(G3)
,UF'(1)=0,向下填充。12.將UF'(k)列的數據順序顛倒然后加負號填入UB(k)列,UB(1)=-UF'(92)
13.選擇UF(k)、UB(k)、α四列數據,繪制曲線。
3.2 使用PYTHON分析
3.2.1 趨勢分析
1.需要python3.0以上
2.pip install pymannkendall
3.編寫腳本
import pymannkendall as mk data=[] #數據 mk.original_test(data)
4.結果解讀
Mann_Kendall_Test(trend='increasing', h=True, p=0.020044668622627437, z=2.3255106965997814, Tau=0.6, s=27.0, var_s=125.0, slope=25.75, intercept=3034.125)
trend:是否存在趨勢,no trend 無趨勢,increasing 上升,decreasing 下降
h:是否拒絕原假設,True 拒絕原假設H0,False 接受原假設
p:顯著性檢驗水平,p<0.05,越小表示接受H1假設概率越高,即存在趨勢越顯著。
z:標準化后的統計量Z
tau:Kendall's tau,反映兩個序列的相關性,接近1的值表示強烈的正相關,接近-1的值表示強烈的負相關
【引用網上對tau的解釋,供大家參考】 Kendall's tau是數學統計中一個常用的系數,用來描述兩個序列的相關系數。如果兩個序列完全一致,則Kendall's tau值為1,兩個毫不相關的序列的Kendall's tau值為0,而兩個互逆的序列的Kendall's tau系數為-1. <br /> 具 體的計算方式為: 1 - 2 * symDif / (n * (n -1)),其中n為排列的長度(兩個序列的長度相同),symDif為對稱距離。對稱距離的計算方式如下: 對于兩個給定的序列S1 = {a,b,c,d}; S2 = {a, c, b, d}. 分別找出兩個序列的二元約束集。在這個例子中S1的所有二元約束集為{(a,b), (a,c), (a,d), (b,c), (b,d), (c,d)}, S2的所有二元約束集為{(a,c), (a,b), (a,d), (c,b), (c,d), (b,d)},比較兩個二元約束集,其中不同的二元約束有兩個(b,c)和(c,b),所以對稱距離為2。代入上面的計算公式可以得到這兩個序列的相關系 數為: 1 - 2 * 2 / (4 * 3) = 2 / 3 = 0.667
這是一個很有用的參數,可以用來比較兩個序列的相似性,例如可以用于搜索引擎的排序結果的好壞。比較一個序列與一個類似標準答案的排序序列的相似性(人工評價),得出排序序列的有效性。
s:統計量S
var_s:方差Var(S)
slope:sen's slope,就是上文的傾斜率β,正值表示上升,負值表示下降
3.2.2 突變分析
暫無。留待有時間再研究
附錄:
-
標準正態分布表
20210820&001 - 置信水平
20210820&002
注意附錄中的置信水平是1-α,等于文檔中的置信水平α - 舉例EXCEL文件存儲
202108020Mann-Kendall舉例