继续前两期关于外生刺激复杂多变条件下时间序列数据结构变化处理的讨论。本期介绍第3种需求场景及其建模方法。
场景描述
(1)时间序列具有季节周期,且季节项估计误差使得趋势项估计存在明显的异方差
(2)时间序列的随机项波幅较大,时间序列的趋势容易被剧烈的非周期波动掩盖
(3)需要敏感识别时间序列当前趋势状态,即敏感识别时间序列当前n阶差分正负偏向
(4)对时间序列当前趋势状态的判定需要足够的时间步数据进行验证
(5)对未经足够时间步数据验证的数据突变持保守态度
(6)区分趋势明确的部分和趋势模糊的部分
(7)对时间序列的未来估计只考虑符合当前趋势的最新信息
(8)环境多变,数据稀疏量少,暴力型大数据算法不适用
建模方法
第一步,针对第(1)(2)点需求,按移动平均窗口MW对时间序列进行移动平均预处理,获得移动平均序列。为消除季节项估计误差导致的异方差问题,可将移动平均窗口MW设置为季节周期的倍数。
第二步,针对第(3)点需求,计算的n阶差分序列。因为实际应用过程中,时间序列趋势变化一般以线性变化为主(例如往期上市公司利润表历史数据研究案例),除随机变化情况外,差分序列偏向大多出现在1阶和2阶,极少出现3阶以上的差分偏向。所以,本期的建模方法根据时间序列的1阶和2阶差分序列的正负偏向分析时间序列当前趋势状态,即计算1阶差分
和2阶差分
。
第三步,针对第(4)点需求,设置判定时间序列当前趋势状态需要的最小时间步MS,即与最新时间点数据连续的最少数据样本量。
第四步,针对第(6)点和第(7)点需求,从1阶差分的最新时间点开始向前回溯:
(a)若全大于0,
且,
且(或
),
则判定当前趋势状态1阶为正(+),且为当前趋势状态1阶序列;
(b)若全小于0,
且,
且(或
),
则判定当前趋势状态1阶明确为负(-),且为当前趋势状态1阶序列;
(c)若既有大于0也有小于0或
,
且不存在使得(
全大于0或全小于0),
且[或(
全大于0或全小于0)],
则当前趋势状态1阶为无(n),且为当前趋势状态1阶序列。
第五步:若当前趋势状态1阶状态为正或负,则对2阶差分 进行相同的分析步骤,识别当前趋势状态2阶状态和当前趋势状态2阶序列。但不再进行3阶以后差分
分析。
至第四步结束,已经解决了第(1)(2)(3)(4)(5)(6)点需求,并且完成时间序列当前趋势结构-即当前趋势状态和当前趋势序列的识别。建模者可结合识别结果和习惯使用的参数估计方法进行后续工作,也可按接下来的步骤进行参数估计。
第五步:满足第(7)(8)点需求,建立以下时间序列推演模型(预测模型):
(a)当前趋势状态2阶为正(+)或负(-),计算当前趋势状态2阶序列的均值为2阶变化值G,取1阶差分最新值
为1阶变化值D,取时间序列最新值
为基期值A。将A、D、G作为时间序列推演模型参数,基期
,则模型的未来推演序列(预测序列)的计算公式为:
(b)当前趋势状态1阶为正(+)或负(-),计算当前趋势状态1阶序列的均值为1阶变化值D,取时间序列最新值
为基期值A。将A、D作为时间序列推演模型参数,基期
,则模型的未来推演序列(预测序列)的计算公式为:
(c)当前趋势状态1阶为无(n),取时间序列的均值为基期值A。将A作为时间序列推演模型参数,则模型的未来推演序列(预测序列)的计算公式为:
为了方便记忆及与后续介绍的建模方法进行区分,称该方法为移动平均严格状态更新模型Ma Strict Latest Status Model,可以直接使用Python库valuequant实现,分析者可在终端执行命令pip install valuequant安装该模块。详细使用方法请查阅BoomEvolve官网valuequant文档。
代码实现的简单示例
构建前两期提到的因季节乘数导致异方差影响实际趋势结构识别的含2阶差分变化的时间序列作为测试序列。
>>> #构建测试序列
>>> import pandas as pd
>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> series=pd.Series((pow(np.arange(1, 40 + 1),2)*(-0.1)+np.arange(1, 40 + 1) * 10 +10 + np.random.normal(0, 0.01, 40))*np.tile([1.05,1.1,0.95,0.9],10), index=pd.date_range(start='2012-03-31',freq='Q-DEC',periods=40))
>>> #调用valuequant并登录账号,登录账号可在https://www.boomevolve.com注册获得
>>> import valuequant as vq
>>> vq.login(name=<账户名称>,pswd=<账户密码>) 登录成功
>>> #构建移动平均严格状态更新模型,mawindow参数是移动时间窗,minstep参数是判定时间序列当前趋势状态需要的最小时间步
>>> model=vq.Models.ma_strict_latest_status_model(series,mawindow=4,minstep=8,seasonal=True)
>>> #获取建模结果
>>> model.model()
{'method': 'l2', 'step': 40, 'params': {'l2_diff': -0.199262, 'l1_latest': 2.948742999999979, 'value_latest': 250.041689}, 'status': {'l1': '+', 'l2': '-'}, 'seasonal': {'12': 0.899887, '3': 1.048504, '6': 1.102474, '9': 0.953146}, 'qorder': ['3', '6', '9', '12']}
结果显示,经过移动平均处理的模型则能够降低异方差对2阶变化识别的影响。在实际应用过程中,时间序列经过低阶移动平均处理后,异方差在更高阶的差分序列中依然存在,最高阶的判别影响尤其大,因此还需要根据实际情况进行后续更多的处理。
移动平均严格状态更新模型同样可以设置anneal参数分配时间权重,也可以设置conservative参数进行保守估计。具体使用请参照前期严格状态更新模型的相关叙述,在此不再赘述。
移动平均严格状态更新模型的局限性
局限1:该模型不能直接识别参数突变的情况。
局限2:容易忽视长期趋势方向。
这两点缺陷与严格状态更新模型相似,在此不再赘述。
本专栏后续还会穿插数期关于处理时间序列结构变化的模型方法介绍,分析者需要解决上述问题或需要应对与该模型不同的需求场景,请阅读后续文章。