Mann-Kendall 突变检验是一种非参数的假设检验方法,用于检验时间序列数据中的趋势性变化。该检验方法通过比较每个数据点与其之前数据点的大小,来检测时间序列数据中的单调趋势(上升、下降或没有趋势)。具体来说,Mann-Kendall测试将时间序列中的每个数据点与所有之前的数据点进行比较,计算出每个数据点之前比它小的数据点数目和比它大的数据点数目,然后比较这两个数量的大小关系,以确定是否存在单调趋势。
Mann-Kendall检验的优点是不需要对数据进行任何假设,可以用于各种类型的时间序列数据,包括非正态数据。但是它的缺点是无法检测出具体的趋势形式,如线性、非线性等。此外,它对时间序列数据中的周期性变化不敏感。
Mann-Kendall检验是一种非参数检验方法,用于检验时间序列数据中的趋势性变化。其原假设为序列是独立同分布的,备择假设为存在单调趋势。Mann-Kendall检验的统计量S计算如下:
其中,xi和xj分别为第i和j时间序列对应的观测值,且i<j,sgn()是符号函数:
当n≥8时,统计量S大致服从正态分布,因此,我们可以将S标准化为Z,以便进行显著性检验。在不考虑序列存在等值数据点的情况下,其均值E(S)=0,方差Var(S)=n(n−1)(2n+5)/18。标准化后的检验统计量Z计算如下:
其中,Var(S)是S的方差,S是Mann-Kendall检验的检验统计量。当S>0时,Z为正值;当S<0时,Z为负值;当S=0时,Z=0。如果我们设显著性水平为α,则在双侧检验中,如果∣Z∣大于等于标准正态分布的第(1−α/2)个百分位数,则拒绝原假设,认为存在单调趋势。例如,在α=0.05的情况下,如果∣Z∣大于等于1.96,则拒绝原假设。
import numpy as np
from scipy.stats import norm
def mann_kendall_test(x):
"""
Mann-Kendall trend test for a given data sequence x.
Args:
x: A list or numpy array of data sequence.
Returns:
trend: The calculated trend (positive, negative or no trend).
p_value: The p-value of the test.
"""
n = len(x)
s = 0
for i in range(n - 1):
for j in range(i + 1, n):
s += np.sign(x[j] - x[i])
# Calculate the variance of the test statistic.
var_s = (n * (n - 1) * (2 * n + 5)) / 18
# Calculate the standardized test statistic.
if s > 0:
z = (s - 1) / np.sqrt(var_s)
elif s < 0:
z = (s + 1) / np.sqrt(var_s)
else:
z = 0
# Calculate the p-value of the test.
p_value = 2 * (1 - norm.cdf(abs(z)))
# Determine the trend based on the sign of the test statistic.
if z > 0:
trend = 'increasing'
elif z < 0:
trend = 'decreasing'
else:
trend = 'no trend'
return trend, p_value
一般情况下: