时间序列趋势判断
判断时间序列数据是上升还是下降是我们常见的问题。比如某个股票在过去一年整体趋势是上升还是下降。我们可以通过画图的方式直接观测出上升还是下降。但每次观测图片非常的麻烦,有没有一些数学方法进行检验?
方案一:直接统计法
假设A序列有N个数。则:$S= \sum_{m=1}^{n}(|A_m-A_{m-1}|)$
当序列单调时:$S = |A_n-A_0|$,否则$ S > |A_n-A_0|$。
求$\frac{|A_n-A_0|}{S}$可以大概标识震荡的幅度,你可以设置阈值来判断即可。
该方法存在的问题,又有取得差值的绝对值,所以无法确定时上升还是下降。但是可以确切的知道震荡的幅度。
方案二:斜率法
斜率方法比较的简单,核心时使用最小二乘法将序列拟合成直线。后根据直线的斜率k去取得序列的走势。例如:
- k > 0.1763 表示上升
- k < -0.1763 表示下降
- 其他,则表示平稳或震荡
上面的判断中的0.1763 实际含义为:tan 10°=0.1763,即直线的倾斜角度,你也可以使用其他的值进行替换。
最后,如果想要评定震荡幅度情况,则可以通过残差平方和SSE进行评估。
方案三:Cox-Stuart趋势检验
Cox-Stuart是一种不依赖趋势结构的快速判断趋势是否存在的方法。Cox-Stuart趋势存在性检验的理论基础是符号检验。它的检验思想是:直接考虑数据的变化趋势,若数据有上升趋势,那么排在后面的数据的值要比排在前面的数据的值显著的大,反之,若数据有下降趋势,那么排在后面的数据的值要比排在前面的数据的值显著的小,利用前后两个时期不同数据的差值正负来判断数据总的变化趋势。为保证数对同分布,前后两个数的间隔应固定。这就意味着将数据一分为二,自然形成前后数对。Cox-Staut提出最优的拆分点是数列中位于中间位置的数。
检验步骤:可以把每一个观察值和相隔大约n/2的另一个观察值配对比较,因此大约有n/2个对子。然后看增长的对子和减少的对子多少来判断总的趋势。
具体做法:
- 取$x_i$和$x_{i+c}$组成一对$(x_i, x_{i+c})$。这里如果n为偶数,则$c=n/2$,如果n是奇数,则c=(n+1)/2。当n为偶数时,共有n’=c对,而n是奇数时,共有 n’=c-1对。
- 用每一对的两元素差$D_i= x_i-x_{i+c}$的符号来衡量增减。令$S^+$为正的$D_i$的数目,$S^-$为负的$D_i$的数目。显然当正号太对时有下降趋势,反之有增长趋势。在没有趋势的零假设下他们因服从二项分布b(n’,0.5)。
- 用p(+)表示取到正数的概率,用p(-)表示取到负数的概率,这样我们就得到符号检验方法来检验序列是否存在趋势性。
双侧检验 | H0:无趋势 | H1:有增长或减少趋势 |
左侧检验 | H0:无减少趋势 | H1:有减少趋势 |
右侧检验 | H0:无增加趋势 | H1:有增加趋势 |
对于显著性水平$\alpha$,如果p值<$\alpha$,拒绝零假设,否则不能拒绝。
方案四:Mann-Kendall趋势检验法
Mann-Kendall(MK)检验(test)(Mann 1945, Kendall 1975, Gilbert 1987) 的目的是统计评估我们所感兴趣的变量,随着时间变化,是否有单调上升或下降的趋势。单调上升(下降)的趋势意味着该变量随时间增加(减少),但此趋势可能是、也可能不是线性的。MK test可替代参数线性回归分析——线性回归可检验线性拟合直线的斜率是否不为零。回归分析要求拟合回归线的残差是正态分布的,MK检验不需要这种假设,MK检验是非参数检验(不要求服从任何分布-distribution free)
以下这些假设是MK检验的基础:
- 当没有趋势时,随时间获得的数据是独立同分布的。独立的假设是说数据随着时间不是连续相关的。
- 所获得的时间序列上的数据代表了采样时的真是条件。(样本具有代表性)
- 样本的采集、处理和测量方法提供了总体样本中的无偏且具有代表性的观测值。
MK检验不要求数据是正态分布,也不要求变化趋势——如果存在的话——是线性的。如果有缺失值或者值低于一个或多个检测限制,是可以计算MK检测的,但检测性能会受到不利影响。独立性假设要求样本之间的时间足够大,这样在不同时间收集的测量值之间不存在相关性。
MK检验是检验是否拒绝零假设(null hypothesis: $H_0$),并接受替代假设(alternative hypothesis: $H_a$):
- $H_0$:没有单调趋势
- $H_a$:存在单调趋势
最初的假设是:$H_0$为真,在拒绝$H_0$并接受$H_a$之前,数据必须要超出合理怀疑——要到达一定的置信度。MK检验的流程:
- 将数据按采集时间列出:$x_1,x_2,…,x_n$,即分别在时间1,2,…,n得到的数据。
- 确定所有n(n-1)/2个$x_j-x_k$差值的符号,其中j > k
- 令$sgn(x_j-x_k)$作为指示函数,依据$x_j-x_k$的正负号取值为1,0或-1
- 计算$S = \sum_{k-1}^{n-1}\sum_{j-k+1}^{n}sgn(x_j-x_k)$。即差值为正的数量减去差值为负的数量。如果S是一个正数,那么后一部分的观测值相比之前的观测值会趋向于变大;如果S是一个负数,那么后一部分的观测值相比之前的观测值会趋向于变小。
- 如果n\leq10,依据Gilbert (1987, page 209, Section 16.4.1)中所描述,要在概率表 (Gilbert 1987, Table A18, page 272) 中查找S。如果此概率小于$\alpha$(认为没有趋势时的截止概率),那就拒绝零假设,认为趋势存在。如果在概率表中找不到n(存在结数据——tied data values——会发生此情况),就用表中远离0的下一个值。比如S=12,如果概率表中没有S=12,那么就用S=13来处理也是一样的。如果n > 10,则依以下步骤6-10来判断有无趋势。这里遵循的是Gilbert (1987, page 211, Section 16.4.2)中的程序。
- 计算S的方差如下:$\text{VAR}(S)=\frac{1}{18}[n(n-1)(2n+5)-\sum_{p-1}^{g}t_p(t_p-1)(2t_p+5)]$。其中g是结组(tied groups)的数量,$t_p$是第p组的观测值的数量。例如:在观测值的时间序列{23, 24, 29, 6, 29, 24, 24, 29, 23}中有g = 3个结组,相应地,对于结值(tiied value)23有$t_1= 2$、结值24有$t_2=3$、结值29有$t_3=S3$。当因为有相等值或未检测到而出现结时,VAR(S)可以通过Helsel (2005, p. 191)中的结修正方法来调整。
- 计算MK检验统计量Z_{MK}:
$$Z_{M K}=\left\{\begin{array}{cl}{\frac{S-1}{\sqrt{V A R(S)}},} & {S>0} \\{0} & {,\quad S=0} \\{\frac{S+1}{\sqrt{V A R(S)}},} & {S<0}\end{array}\right.$$
- 设想我们要测试零假设。$H_0$(没有单调趋势)对比替代假设$H_a$(有单调增趋势),其1型错误率为$\alpha$,$0<\alpha<0.50$(注意$\alpha$是MK检验错误地拒绝了零假设时可容忍的概率——即MK检验拒绝了零假设是错误地,但这个事情发生概率是$\alpha$,我们可以容忍这个错误)。如果$Z_{MK}\geq Z_{1-\alpha}$,就拒绝零假设$H_0$,接受替代假设$H_a$,其中$Z_{1-\alpha}$是标准正态分布的$100(1-\alpha)^{th}$百分位。
- 测试上面的$H_0$与$H_a$(有单调递减趋势),其1型错误率为$alpha$,$0<\alpha<0.5$,如果Z$Z_{MK}\leq – Z_{1-\alpha}$,就拒绝零假设$H_0$,接受替代假设$H_a$
- 测试上面的$H_0$与$H_a$(有单调递增或递减趋势),其1型错误率为$alpha$,$0<\alpha<0.5$,如果$|Z_{MK}|\geq Z_{\frac{1-\alpha}{2}}$,就拒绝零假设$H_0$,接受替代假设$H_a$,其中竖线代表绝对值。
方案五:Cochran-Armitage趋势检验
Cochran-Armitage (CA) 趋势检验是一种用于分析1个二分类变量和1个有序分类变量(等级变量)关联性的统计方法,由Cochran和Armtiage创建和完善。线性趋势检验中最常用的一种方法就是Cochran-Armitage趋势检验。因为二分类变量和有序分类变量可以用列联表的形式表示,所以很多人将针对于这类资料的趋势检验称为趋势卡方检验。更简单来说他面向对象是两个变量,其中一个变量有两个可选值,另一个变量是有序排列的。
方案六:numpy.polyfit()
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)
如果返回的是正数则为增长,如果返回的是负数,则为下降,如果为0则表示没有趋势。具体原理还没有研究。
以上是目前梳理的一些方案,有些方案比较绕,目前自己也没有搞清楚。先记录下来,后续慢慢再研究。如果你有这方面经验。欢迎留下你的评论。
参考连接:
- https://wenku.baidu.com/view/cec731b981c758f5f61f6760.html
- https://wenku.baidu.com/view/47df1180d4d8d15abe234edb
- https://blog.csdn.net/liuchengzimozigreat/article/details/87931248
- https://github.com/zhukov-msu/TrendAlgorithms
- https://stackoverflow.com/questions/55649356/how-can-i-detect-if-trend-is-increasing-or-decreasing-in-time-series
- https://pypi.org/project/trendet/
Related posts: