mk趋势检验具体计算公式
时间: 2025-01-07 14:39:22 浏览: 186
### Mann-Kendall 趋势检验计算公式
Mann-Kendall (MK) 趋势检验是一种非参数统计测试,用于检测时间序列数据中的单调趋势。此方法不需要假设数据服从特定分布,并能有效处理缺失值和重复值的情况。
#### 计算步骤
定义时间为 \( t \),样本总数为 \( n \)[^2]。对于每一个观测值 \( X_i \),其中 \( i=1,2,...,n \),考虑所有后续的观测值 \( X_j \),\( j=i+1,i+2,...,n \)。如果 \( X_j > X_i \),则记为 +1;如果 \( X_j < X_i \),则记为 -1;如果两者相等,则记为 0。这样可以得到一系列差分符号组成的向量 S:
\[ S = \sum_{k=1}^{n-1}\sum_{j=k+1}^{n}sgn(X_j-X_k) \]
这里 sgn 函数表示符号函数,当输入大于零返回 +1,小于零返回 -1,等于零时返回 0[^3]。
为了评估显著性水平,还需要计算方差 Var(S):
\[ Var(S)=\frac{1}{18}[n(n-1)(2n+5)-\sum_{p=1}^{q}tp(tp-1)(2tp+5)] \]
其中 q 表示相同数值组的数量,而 tp 是第 p 组内相同数值的数量。最后一步是标准化 Z 值:
\[ Z=\left\{\begin{matrix}
\dfrac{S-1}{\sqrt{Var(S)}} & 当 S>0 \\
0& 当 S=0 \\
\dfrac{S+1}{\sqrt{Var(S)}} & 当 S<0
\end{matrix}\right.\]
这个 Z 値近似遵循标准正态分布 N(0,1),因此可以根据选定置信度查表获得临界值来判断是否存在明显上升或下降趋势。
```python
import numpy as np
from scipy.stats import norm
def mann_kendall_test(x):
"""
Perform the Mann-Kendall trend test on a time series.
Parameters:
x : array_like
A one-dimensional data sequence.
Returns:
tuple of float and bool
The normalized score z-value and boolean indicating whether there is an increasing or decreasing trend at alpha level 0.05.
"""
n = len(x)
s = 0
for k in range(n-1):
for j in range(k+1,n):
s += np.sign(x[j]-x[k])
unique_x = np.unique(x)
g = len(unique_x)
if n==g: # no tie situation
var_s = (n*(n-1)*(2*n+5))/18
else:
tp = np.zeros(g)
for i in range(len(unique_x)):
tp[i]= sum(x==unique_x[i])
var_s=n*(n-1)*(2*n+5)
for i in range(len(tp)):
var_s=var_s-(tp[i]*(tp[i]-1)*(2*tp[i]+5))
var_s=var_s/18
if s>0:
z=(s-1)/np.sqrt(var_s)
elif s<0:
z=(s+1)/np.sqrt(var_s)
else:
z=0
p_value=2*(1-norm.cdf(abs(z)))
h=p_value<=0.05
return round(z,4),h
```
阅读全文
相关推荐


















