最近在做这相关的研究,看了不少相关理论与研究,记录一下这几天的调研结果。
说明:协整检验中每个序列要求为单整,单整通俗的说就是做一次差分之后为平稳序列的序列。
需要statsmodels库支持,安装:pip install statsmodels
。
statsmodels的API文档
from statsmodels.stats.diagnostic import unitroot_adf
unitroot_adf(sequence)
返回的值分别是:检验值、p-value、滞后阶数、自由度、(常数)显著性表
(-18.366072596009424, 2.2226297238330224e-30, 27, 3448, {‘1%’: -3.4322479625901536, ‘5%’: -2.8623786111734746, ‘10%’: -2.567216407968438}, -25430.320661028072)
差分的方法获取平稳序列,一次不行就多次。但是,一旦差分其实我们丢失了原始序列的一些信息,而且往往很难从实际的意义上去解释差分后拟合的结果。
seq = seq[1:] - seq[:-1]
对残差进行异常值过滤(四分位数法)是个不错的滑动平均滤波方法。
# 四分位数滤波
def _diff_smooth(ts, timedelta=None):
if timedelta is None:
timedelta = lambda minutes: minutes
dif = ts.diff().dropna() # 差分序列
td = dif.describe() # 描述性统计得到:min,25%,50%,75%,max值
high = td['75%'] + 1.5 * (td['75%'] - td['25%']) # 定义高点阈值,1.5倍四分位距之外
low = td['25%'] - 1.5 * (td['75%'] - td['25%']) # 定义低点阈值,同上
# 变化幅度超过阈值的点的索引
forbid_index = dif[(dif > high) | (dif < low)].index
i = 0
while i < len(forbid_index) - 1:
n = 1 # 发现连续多少个点变化幅度过大,大部分只有单个点
start = forbid_index[i] # 异常点的起始索引
print(i, n)
while forbid_index[i+n] == start + timedelta(minutes=n):
n += 1
if i+n >= len(forbid_index):
break
i += n - 1
end = forbid_index[i] # 异常点的结束索引
# 用前后值的中间值均匀填充
value = np.linspace(ts[start - timedelta(minutes=1)], ts[end + timedelta(minutes=1)], n)
# print(value, start, end)
ts[start: end+1] = value
i += 1
这里引用一下:
第一,格兰杰因果检验是检验统计上的时间先后顺序,并不表示而这真正存在因果关系,是否呈因果关系需要根据理论、经验和模型来判定。
第二,格兰杰因果检验的变量应是平稳的,如果单位根检验发现两个变量是不稳定的,那么,不能直接进行格兰杰因果检验,所以,很多人对不平稳的变量进行格兰杰因果检验,这是错误的。
第三,协整结果仅表示变量间存在长期均衡关系,那么,到底是先做格兰杰还是先做协整呢?因为变量不平稳才需要协整,所以,首先因对变量进行差分,平稳后,可以用差分项进行格兰杰因果检验,来判定变量变化的先后时序,之后,进行协整,看变量是否存在长期均衡。
第四,长期均衡并不意味着分析的结束,还应考虑短期波动,要做误差修正检验。
代码:api
from statsmodels.tsa.stattools import grangercausalitytests
# sequence应该为 (seq_len, 2) 这样的序列数据,这个函数测试第二列是否导致第一列
# maxlag是要测试的滞后值范围,F 值越大表示
grangercausalitytests(sequence, maxlag=1, verbose=True)
参考:CSDN博客:时间序列分析之协整检验
主要意义:
这里考虑Engel-Granger 两步协整检验法和 Johansen 协整检验法,它们二者的区别在于 Engler-Granger 采用的是一元方程技术,而 Johansen 则是多元方程技术,所以Johansen 协整检验法受限更小。
代码:
from statsmodels.tsa.stattools import coint
# 返回coint_t, pvalue, crit_value(1%, 5%, 10%)
# pvalue是接收原假设的几率,可以通过coint_t和不同显著度时的值crit_value进行比较
coint(sequence, exp54[:200, 17])
from statsmodels.tsa.seasonal import seasonal_decompose
# 计算趋势、周期、残差
dec = seasonal_decompose(obs, freq=period, two_sided=False)
trend = dec.trend
seasonal = dec.seasonal
residual = dec.resid
利用Auto ARIMA构建高性能时间序列模型(附Python和R代码)
Xgboost模型