Mann-Kendall突变检测(mk突变检测)

% Mann-Kendall突变检测
% 数据序列y
% 结果序列UFk,UBk2
%--------------------------------------------
%读取excel中的数据,赋给矩阵y
%获取y的样本数
%A为时间和径流数据列

A=xlswrite('数据.xls')
x=A(:,1);%时间序列
y=A(:,2);%径流数据列
N=length(y);
n=length(y);
% 正序列计算---------------------------------
% 定义累计量序列Sk,长度=y,初始值=0

Sk=zeros(size(y));
% 定义统计量UFk,长度=y,初始值=0
UFk=zeros(size(y));
% 定义Sk序列元素s
s = 0;
% i从2开始,因为根据统计量UFk公式,i=1时,Sk(1)、E(1)、Var(1)均为0
% 此时UFk无意义,因此公式中,令UFk(1)=0

for i=2:n
   for j=1:i
         if y(i)>y(j)
           s=s+1;
         else
           s=s+0;
         end;
   end;
   Sk(i)=s;
   E=i*(i-1)/4;                       % Sk(i)的均值
  Var=i*(i-1)*(2*i+5)/72;       % Sk(i)的方差
  UFk(i)=(Sk(i)-E)/sqrt(Var);
end;
% ------------------------------正序列计算end
% 逆序列计算---------------------------------
% 构造逆序列y2,长度=y,初始值=0

y2=zeros(size(y));
% 定义逆序累计量序列Sk2,长度=y,初始值=0
Sk2=zeros(size(y));
% 定义逆序统计量UBk,长度=y,初始值=0
UBk=zeros(size(y));
% s归0
s=0;
% 按时间序列逆转样本y
% 也可以使用y2=flipud(y);或者y2=flipdim(y,1);
for i=1:n
    y2(i)=y(n-i+1);
end;
% i从2开始,因为根据统计量UBk公式,i=1时,Sk2(1)、E(1)、Var(1)均为0
% 此时UBk无意义,因此公式中,令UBk(1)=0

for i=2:n
   for j=1:i
         if y2(i)>y2(j)
           s=s+1;
         else
           s=s+0;
         end;
   end;
   Sk2(i)=s;
   E=i*(i-1)/4;                   % Sk2(i)的均值
  Var=i*(i-1)*(2*i+5)/72;   % Sk2(i)的方差
% 由于对逆序序列的累计量Sk2的构建中,依然用的是累加法,即后者大于前者时s加1,
% 则s的大小表征了一种上升的趋势的大小,而序列逆序以后,应当表现出与原序列相反
% 的趋势表现,因此,用累加法统计Sk2序列,统计量公式(S(i)-E(i))/sqrt(Var(i))
% 也不应改变,但统计量UBk应取相反数以表征正确的逆序序列的趋势

  UBk(i)=0-(Sk2(i)-E)/sqrt(Var);
end;
% ------------------------------逆序列计算end
% 此时上一步的到UBk表现的是逆序列在逆序时间上的趋势统计量
% 与UFk做图寻找突变点时,2条曲线应具有同样的时间轴,因此
% 再按时间序列逆转结果统计量UBk,得到时间正序的UBk2,做图用

UBk2=zeros(size(y));
% 也可以使用UBk2=flipud(UBk);或者UBk2=flipdim(UBk,1);
for i=1:n
   UBk2(i)=UBk(n-i+1);
end;
% 做突变检测图时,使用UFk和UBk2
% 写入目标xls文件:f:\test2.xls
% 目标表单:Sheet1
% 目标区域:UFk从A1开始,UBk2从B1开始

xlswrite('f:\test2.xls',UFk,'Sheet1','A1');
xlswrite('f:\test2.xls',UBk2,'Sheet1','B1');
figure(3)                       %画图
plot(x,UFk,'r-','linewidth',1.5);
hold on
plot(x,UBk2,'b-.','linewidth',1.5);
plot(x,1.96*ones(N,1),':','linewidth',1);
axis([min(x),max(x),-5,5]);
legend('UF统计量','UB统计量','0.05显著水平');
xlabel('t (year)','FontName','TimesNewRoman','FontSize',12);
ylabel('统计量','FontName','TimesNewRoman','Fontsize',12);
title(StationID)  %添加标题
hold on
%hold on
grid(gca,'minor')% 画出次格网
plot(x,0*ones(n,1),'-.','linewidth',1);
plot(x,1.96*ones(n,1),':','linewidth',1);
plot(x,-1.96*ones(n,1),':','linewidth',1);


savepath=['D:\',num2str(StationID),'.png']%保存路径
saveas(StationID,savepath)%保存为png文件
<think>嗯,用户问的是关于MK突变检验在MATLAB中的应用,特别是如何确定具体的突变年份。首先,我需要回忆一下MK检验的基本原理和步骤。MK检验是一种非参数检验方法,用于检测时间序列数据中的趋势变化或突变点。用户已经得到了突变点,但不知道如何确定具体的年份,这可能涉及到检验统计量的分析。 首先,我应该确认用户是否正确地进行了MK检验,并正确计算了UF和UB统计量。通常,MK检验的突变点是通过UF和UB曲线的交点来确定的,尤其是当交点位于显著性水平范围内时。需要提醒用户检查这两个统计量的图形是否有交点,并确认交点是否在置信区间内。 接下来,用户可能需要知道如何在MATLAB中绘制UF和UB曲线,并找到它们的交点。这可能涉及到对计算结果的后处理,比如使用find函数或者差值方法来定位交点的位置。同时,需要提醒用户注意时间序列的时间轴是否正确对齐,比如数据年份是否与索引对应,避免索引与年份混淆导致的错误。 另外,用户可能对显著性水平不了解,需要解释常用的显著性水平(比如α=0.05对应的临界值±1.96),并说明交点是否在临界值范围内才能视为显著的突变点。如果交点不在临界值内,可能突变点不显著,或者需要结合其他方法验证。 还有可能需要考虑多个交点的情况,这时候应该选择第一个显著的突变点,或者根据研究背景判断最合理的突变年份。此外,建议用户结合其他突变检验方法(如Pettitt检验、滑动t检验等)进行交叉验证,确保结果可靠。 最后,可能需要提供一个简单的MATLAB代码示例,展示如何计算UF和UB,绘制曲线,并标注交点对应的年份。这样用户可以直接参考代码,调整自己的数据和分析步骤。</think>在MATLAB中利用Mann-KendallMK突变检验确定具体突变年份,需结合UF和UB统计量曲线的交点及显著性水平。以下是分步说明: --- ### **1. MK突变检验的核心步骤** - **UF统计量**:正向序列统计量,反映数据上升趋势 - **UB统计量**:逆向序列统计量(将原序列倒序后计算) - **显著性水平**:通常取α=0.05,对应临界值±1.96 --- ### **2. 确定突变年份的关键方法** #### **(1) 交点法** - **条件**:UF与UB曲线在置信区间(如±1.96)内存在交点 - **操作**: 1. 绘制UF和UB曲线图 2. 找到两者交点对应的**横坐标位置(索引)** 3. 将索引转换为实际年份(注意时间序列起始年份) - **MATLAB示例代码片段**: ```matlab % 假设年份存储在向量year中,UF和UB为计算结果 plot(year, UF, 'b-', 'LineWidth', 1.5); hold on; plot(year, UB, 'r--', 'LineWidth', 1.5); plot(year, 1.96*ones(size(year)), 'k:'); plot(year, -1.96*ones(size(year)), 'k:'); xlabel('Year'); ylabel('统计量'); legend('UF', 'UB', '显著性水平'); % 寻找交点 [x_intersect, y_intersect] = intersections(year, UF, year, UB); intersect_years = x_intersect(abs(y_intersect) < 1.96); % 筛选显著交点 ``` #### **(2) 突变点验证** - **条件**:交点后UF统计量持续超出临界值 - **操作**:观察交点后UF是否保持显著趋势(如持续大于1.96或小于-1.96) --- ### **3. 注意事项** - **时间对齐问题**:确保数据索引与年份严格对应(如数据从1950年开始,则索引1对应1950年) - **多个交点处理**:选择第一个显著交点作为主突变点,或结合其他检验方法交叉验证 - **临界值调整**:若数据长度较短,需查表获取精确临界值 --- ### **4. 完整流程示例** ```matlab % 假设数据:year = 1950:2020; data = randn(71,1); % 计算UF和UB(需自行实现MK检验函数或调用工具箱) [UF, UB] = MK_Test(data); % 绘图与交点检测 figure; plot(year, UF, 'b-', year, UB, 'r--', year, 1.96, 'k:', year, -1.96, 'k:'); legend('UF', 'UB', 'α=0.05'); % 使用intersections函数找交点(需下载此函数) [x_int, y_int] = intersections(year, UF, year, UB); valid_idx = find(abs(y_int) < 1.96); % 筛选显著交点 mut_year = x_int(valid_idx(1)); % 取第一个显著交点 disp(['显著突变年份: ', num2str(mut_year)]); ``` --- ### **5. 交叉验证建议** - **方法对比**:结合Pettitt检验、滑动T检验等 - **分段趋势分析**:对比突变前后数据的均值、方差变化 - **实际背景分析**:结合气象事件、政策变化等外部因素 --- ### **6. 常见问题解决** - **无显著交点**:可能无突变点,或数据噪声过大 - **多个交点**:需结合统计量持续性和实际意义判断主次 - **UF/UB震荡**:建议平滑数据或增加样本长度 需要可运行的MK检验MATLAB函数代码,可进一步提供具体实现细节。
评论 32
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值