EDA365电子论坛网

标题: 利用MATLAB实现Mann-Kendall突变检测(mk突变检测) [打印本页]

作者: haidaowang    时间: 2020-2-3 09:40
标题: 利用MATLAB实现Mann-Kendall突变检测(mk突变检测)
  H# U2 j( u  y
%最近写论文需要用到MK检验法,网上收集到大量的matlab代码,但是没有一个代码能够) b1 o" w& T  c( j2 F
%完全正确运行或者分析信息不全,结合多位网友编写的MK检验法,经过我的改编,顺利得到$ r2 v4 a9 ~+ }
%正确的运行结果,谢谢各位网友,希望对有需要的盆友有帮助7 m& k, h! x0 r# D2 A
% Mann-Kendall突变检测7 Y$ z+ L) k& u; D
% 数据序列y* _5 ?7 |% ]$ o9 h
% 结果序列UFk,UBk2# R/ v$ O. E% p; _
%--------------------------------------------
/ f: c5 S% C6 W4 \7 I%读取excel中的数据,赋给矩阵y
+ J$ w! q- l) j* p% Z%获取y的样本数
6 r+ o$ Y7 F* k0 Y6 S$ t! J8 c%A为时间和径流数据列8 y; p! i: N" H6 m1 S4 l# g
A=xlswrite('数据.xls')  d$ c6 ?* }4 Y% e
x=A(:,1);%时间序列! Z+ C4 L" G, U, t
y=A(:,2);%径流数据列
  p( H) J' ]2 |, m& ?; r; }N=length(y);, o4 ]$ B; `! {0 x9 t
n=length(y);
) z/ C6 b$ T2 w0 ?1 t' F% 正序列计算---------------------------------+ A" C+ t. |. @/ i
% 定义累计量序列Sk,长度=y,初始值=0
: }' L, ?) {. f; |) pSk=zeros(size(y));4 K& K3 o0 S: P+ {6 U$ @
% 定义统计量UFk,长度=y,初始值=0; U; J% d( m* b; k. g/ T
UFk=zeros(size(y));
7 D. ^5 M3 Q, Z6 T. J" W# {% 定义Sk序列元素s! U( g0 T9 a9 s4 C: z0 j8 ]& N
s = 0;
7 [) [# A- ^( f( Z1 H6 Z1 |% i从2开始,因为根据统计量UFk公式,i=1时,Sk(1)、E(1)、Var(1)均为0
! ^1 {3 v: S. ~8 h% 此时UFk无意义,因此公式中,令UFk(1)=03 \: v- X# \7 c$ Y- F$ Q  N
for i=2:n8 ?0 e# K! j3 B. U
   for j=1:i
+ c1 J" Q& G1 v) {( q3 Q         if y(i)>y(j)% O1 S" x9 C. v7 }. o
           s=s+1;
! T! K  P  D8 Q' @- [) }' u         else
* j$ I# M7 e. v3 Y6 t4 i' H! n, F; Y           s=s+0;
" d% q! }3 a1 O         end;: X/ h1 W: a% `$ ^! C: [
   end;
+ v/ e5 {* J" p" E! }   Sk(i)=s;0 N9 @! {. R/ p& a, W
   E=i*(i-1)/4; % Sk(i)的均值3 q+ B: r8 |; o
  Var=i*(i-1)*(2*i+5)/72; % Sk(i)的方差
& g8 o. {3 b+ P' _# p# [  UFk(i)=(Sk(i)-E)/sqrt(Var);
% X% |* o  b1 m: aend;" F$ T/ {7 T% M
% ------------------------------正序列计算end! U7 J5 Y0 g5 b
% 逆序列计算---------------------------------- b, l  m9 E2 s* i
% 构造逆序列y2,长度=y,初始值=0
( {- _: c% ], }; U$ t' jy2=zeros(size(y));/ y  l, Z/ K8 B* H
% 定义逆序累计量序列Sk2,长度=y,初始值=0
9 U+ I8 Q6 t7 s3 r9 xSk2=zeros(size(y));7 e' j4 d+ g, J$ l
% 定义逆序统计量UBk,长度=y,初始值=0
; U1 F  p  E, t2 T* u" s' [+ CUBk=zeros(size(y));
5 R% o- q0 X3 @; g' k; p3 n5 G% s归08 w" f5 n; T/ n0 S' y& R
s=0;$ [% X$ d. E/ E5 h
% 按时间序列逆转样本y4 d" S4 I) W! Q$ M: F' Q3 Q5 c7 L% S. S
% 也可以使用y2=flipud(y);或者y2=flipdim(y,1);7 D# I  \! V" y& r8 @& s  T/ y
for i=1:n5 q6 R. s2 w6 o0 @" k+ L
    y2(i)=y(n-i+1);* t# H! b+ d9 h) e6 E. T- ]
end;
# E2 u% D4 ^, }0 n( g% i从2开始,因为根据统计量UBk公式,i=1时,Sk2(1)、E(1)、Var(1)均为0
3 ?! C  S! n+ V6 A8 z% 此时UBk无意义,因此公式中,令UBk(1)=04 S( {5 Q* G- a5 Z
for i=2:n
) Q+ I1 t7 `$ z9 R   for j=1:i
, l% D6 g% ?' [7 j2 O         if y2(i)>y2(j); l# l1 M* }, z; p. p; @2 c( b
           s=s+1;
9 X( H& \( l4 B. B# ]         else
# Q' {9 I5 q  {+ g           s=s+0;
% W/ X! }8 r% e         end;
; P. H, c& F8 Z5 s. ^, M# a   end;
& F/ C$ n% w/ s: C, Q   Sk2(i)=s;/ L+ g: c, U6 x9 [" X, F
   E=i*(i-1)/4; % Sk2(i)的均值9 |: c; Y4 ?' R3 R% f- ^$ K
  Var=i*(i-1)*(2*i+5)/72; % Sk2(i)的方差
0 j3 `" u8 J, c8 f1 n% 由于对逆序序列的累计量Sk2的构建中,依然用的是累加法,即后者大于前者时s加1,
$ `, m  C5 S% ?+ D6 r% 则s的大小表征了一种上升的趋势的大小,而序列逆序以后,应当表现出与原序列相反; w% V" R8 p' X
% 的趋势表现,因此,用累加法统计Sk2序列,统计量公式(S(i)-E(i))/sqrt(Var(i)), \! s+ `# F7 r, l' G
% 也不应改变,但统计量UBk应取相反数以表征正确的逆序序列的趋势
1 R' j) [: i, w  UBk(i)=0-(Sk2(i)-E)/sqrt(Var);
5 A8 z8 D( y; oend;' ]9 D+ H7 |  k6 F+ o. ^
% ------------------------------逆序列计算end
# F# a* A0 \6 _! n# X; [7 ~% 此时上一步的到UBk表现的是逆序列在逆序时间上的趋势统计量
" n& ^) b2 S+ t% 与UFk做图寻找突变点时,2条曲线应具有同样的时间轴,因此
' X! W0 N8 s0 \+ c) |8 j1 Q: t) r% D% 再按时间序列逆转结果统计量UBk,得到时间正序的UBk2,做图用
2 F8 q; b& y1 Q4 y) kUBk2=zeros(size(y));
/ o- A( g: Y5 M8 g- k. R3 ~% 也可以使用UBk2=flipud(UBk);或者UBk2=flipdim(UBk,1);. [+ @  N' q: a
for i=1:n; b: n* M7 {! _: _+ J" A+ Y
   UBk2(i)=UBk(n-i+1);
6 C  s# H+ N  G) X  U; tend;
9 @) e5 q4 l4 `. c+ \2 @% K0 T% 做突变检测图时,使用UFk和UBk2
3 M+ @0 n: n/ u% 写入目标xls文件:f:\test2.xls% I0 f6 S* c/ E$ T& W/ i% ?( R
% 目标表单:Sheet1
% W- d4 x* f" N5 P% 目标区域:UFk从A1开始,UBk2从B1开始$ g/ K6 q$ ?6 K7 \: z9 `
xlswrite('f:\test2.xls',UFk,'Sheet1','A1');* @; R0 p2 g7 ?* i9 z
xlswrite('f:\test2.xls',UBk2,'Sheet1','B1');4 y, h0 y  [  l* g5 t3 E
figure(3)%画图# Q7 {) q0 |. E4 k5 j( @8 C, l
plot(x,UFk,'r-','linewidth',1.5);% q/ j7 ?3 h2 Z/ y, T
hold on
; ], G) z9 H2 t5 Q( Gplot(x,UBk2,'b-.','linewidth',1.5);
: N% [9 M4 k$ Aplot(x,1.96*ones(N,1),':','linewidth',1);- G# R, j: N; n# D' }4 J( i! i
axis([min(x),max(x),-5,5]);* |' ]) \: w9 n( _
legend('UF统计量','UB统计量','0.05显著水平');5 Q" k/ F$ {- b! H
xlabel('t (year)','FontName','TimesNewRoman','FontSize',12);
% q- C+ c7 C2 oylabel('统计量','FontName','TimesNewRoman','Fontsize',12);
$ c+ @# _8 ?% S. n%grid on
1 v  R  X- F) }hold on
1 I- W4 w" |) U7 E7 V8 zplot(x,0*ones(N,1),'-.','linewidth',1);
: V; c+ K7 _% p! s  X, ]3 jplot(x,1.96*ones(N,1),':','linewidth',1);2 z0 N5 \1 n" B! x: V) k
plot(x,-1.96*ones(N,1),':','linewidth',1);
+ S, v3 [& o% @( w$ _) X* D" u3 b# x1 o) `% B1 ^% C+ V3 a" \

4 M5 x+ e; N: N, g0 m3 J: T. c, e! `" k- f* c0 n2 b! s: U

作者: ExxNEN    时间: 2020-2-3 19:03
谢谢分享程序




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2