时序数据趋势判断
所属分类 quant
浏览量 400
股票指数趋势分析 上涨 下跌 震荡
变化幅度
斜率法
Cox-Stuart趋势检验
Mann-Kendall趋势检验法
变化幅度
通过 区间上涨下跌幅度来判断 趋势强弱
使用最小二乘法将序列拟合成直线,用斜率判断
import numpy as np
def trendline(index,data, order=1):
coeffs = np.polyfit(index, list(data), order)
slope = coeffs[-2]
return float(slope)
index=[1,2,3,4]
List=[1043,6582,5452,7571]
resultent=trendline(index,List)
print(resultent)
Cox-Stuart趋势检验
Cox-Stuart是一种不依赖趋势结构的快速判断趋势是否存在的方法。
Cox-Stuart趋势存在性检验的理论基础是符号检验。
直接考虑数据的变化趋势,若数据有上升趋势,那么排在后面的数据的值要比排在前面的数据的值显著的大,
反之,若数据有下降趋势,那么排在后面的数据的值要比排在前面的数据的值显著的小,
利用前后两个时期不同数据的差值正负来判断数据总的变化趋势。
为保证数对同分布,前后两个数的间隔应固定。这就意味着将数据一分为二,自然形成前后数对。
Cox-Staut提出最优的拆分点是数列中位于中间位置的数。
对于显著性水平𝛼,如果p值<𝛼,拒绝零假设,否则不能拒绝。
import scipy.stats as stats
def cos_staut(list_c,debug=False):
lst=list_c.copy()
raw_len=len(lst)
if raw_len%2==1:
del lst[int((raw_len-1)/2)]
c=int(len(lst)/2)
n_pos=n_neg=0
for i in range(c):
diff=lst[i+c]-lst[i]
if diff>0:
n_pos+=1
elif diff<0:
n_neg+=1
else:
continue
num=n_pos+n_neg
k=min(n_pos,n_neg)
p_value=2*stats.binom.cdf(k,num,0.5)
if debug:
print('fall:%i, rise:%i, p-value:%f'%(n_neg, n_pos, p_value))
if n_pos>n_neg and p_value<0.05:
return 'increasing'
elif n_neg>n_pos and p_value<0.05:
return 'decreasing'
else:
return 'no trend'
Mann-Kendall趋势检验法
Mann-Kendall(MK)检验(test)(Mann 1945, Kendall 1975, Gilbert 1987)
统计评估变量,随着时间变化,是否有单调上升或下降的趋势。
单调上升(下降)的趋势意味着该变量随时间增加(减少),但此趋势可能是、也可能不是线性的。
MK test可替代参数线性回归分析——线性回归可检验线性拟合直线的斜率是否不为零。
回归分析要求拟合回归线的残差是正态分布的,MK检验不需要这种假设,
MK检验是非参数检验(不要求服从任何分布-distribution free)
import math
from scipy.stats import norm, mstats
def mk_test(x, alpha=0.05):
"""
This function is derived from code originally posted by Sat Kumar Tomer
(satkumartomer@gmail.com)
See also: http://vsp.pnnl.gov/help/Vsample/Design_Trend_Mann_Kendall.htm
The purpose of the Mann-Kendall (MK) test (Mann 1945, Kendall 1975, Gilbert
1987) is to statistically assess if there is a monotonic upward or downward
trend of the variable of interest over time. A monotonic upward (downward)
trend means that the variable consistently increases (decreases) through
time, but the trend may or may not be linear. The MK test can be used in
place of a parametric linear regression analysis, which can be used to test
if the slope of the estimated linear regression line is different from
zero. The regression analysis requires that the residuals from the fitted
regression line be normally distributed; an assumption not required by the
MK test, that is, the MK test is a non-parametric (distribution-free) test.
Hirsch, Slack and Smith (1982, page 107) indicate that the MK test is best
viewed as an exploratory analysis and is most appropriately used to
identify stations where changes are significant or of large magnitude and
to quantify these findings.
Input:
x: a vector of data
alpha: significance level (0.05 default)
Output:
trend: tells the trend (increasing, decreasing or no trend)
h: True (if trend is present) or False (if trend is absence)
p: p value of the significance test
z: normalized test statistics
Examples
--------
>>> x = np.random.rand(100)
>>> trend,h,p,z = mk_test(x,0.05)
"""
n = len(x)
# calculate S
s = 0
for k in range(n-1):
for j in range(k+1, n):
s += np.sign(x[j] - x[k])
# calculate the unique data
unique_x, tp = np.unique(x, return_counts=True)
g = len(unique_x)
# calculate the var(s)
if n == g: # there is no tie
var_s = (n*(n-1)*(2*n+5))/18
else: # there are some ties in data
var_s = (n*(n-1)*(2*n+5) - np.sum(tp*(tp-1)*(2*tp+5)))/18
if s > 0:
z = (s - 1)/np.sqrt(var_s)
elif s < 0:
z = (s + 1)/np.sqrt(var_s)
else: # s == 0:
z = 0
# calculate the p_value
p = 2*(1-norm.cdf(abs(z))) # two tail test
h = abs(z) > norm.ppf(1-alpha/2)
if (z < 0) and h:
trend = 'decreasing'
elif (z > 0) and h:
trend = 'increasing'
else:
trend = 'no trend'
return trend
上一篇
下一篇
AIGC术语
numpy polyfit 多项式拟合
沪深300指数和沪深300ETF 对比分析
沪深300 线性回归画趋势线
线性回归中常见的一些统计学术语(RSE RSS TSS ESS MSE RMSE R2 Pearson's r)
线性回归的R方