精华内容
下载资源
问答
  • MATS 工具包的优势在于同时操作多个时间序列和多个度量,还允许设置一系列度量特定参数。 任何操作的帮助都以 html 格式提供。 MATS 的一个主要特点是它跟踪两个列表:包含要分析的标量时间序列集的时间序列列表,...
  • 异常检测标记工具,专门用于多个时间序列(每个类别一个时间序列)。 Taganomaly是用于为异常检测模型创建标记数据的工具。 它允许贴标机选择一个时间序列上的点,通过查看同一时间范围内其他时间序列的行为,或...
  • 时间序列数据是某个个体在多个时间点上收集的数据。分析时间序列的方法构成了数据分析的一个重要领域,即时间序列分析。时间序列根据所研究的依据不同,可产生不同的分类。按照研究对象可以分为一元时间序列和多元...

    时间序列、时间序列分析、时间序列效应分解、平稳时间序列、AIC和BIC

    目录

    时间序列、时间序列分析、时间序列效应分解、平稳时间序列、AIC和BIC

    时间序列

    时间序列分析

    时间序列效应分解

    平稳时间序列

    AIC和BIC


    时间序列

    时间序列数据是某个个体在多个时间点上收集的数据。分析时间序列的方法构成了数据分析的一个重要领域,即时间序列分析。时间序列根据所研究的依据不同,可产生不同的分类。按照研究对象可以分为一元时间序列和多元时间序列;按照时间属性可以分为离散时间序列和连续时间序列;按照序列的平稳特性可以分为平稳时间序列和非平稳时间序列。

     

    时间序列分析

    初级常用的时间序列数据的分析方法有两类:一类为效应分解法,即把时间序列分解为趋势和周期效应,并分别使用曲线拟合。另一类为ARIMA法,其可以针对数据产生的机理构建动态模型,实际上是根据数据扰动项之间相关性结构构建预测模型。

    时间序列效应分解

    时间序列的效应分解分为,长期趋势变动、周期性变动和随机变动。长期趋势是指序列朝着一定的方向持续上升或者下降。周期性或者季节性变动指的是经济周期或者季节、月度、日度的周期变化。随机变动指的是随机因素导致的时间序列的小幅波动。时间序列的效应的组合方式分别为:加法模型和乘法模型。

     

    可以使用Facebook数据科学家团队开发的prophet框架来进行趋势分解分析。

    平稳时间序列

    在统计学中,平稳时间序列分为严格平稳时间序列和宽平稳时间序列。只有平稳时间序列才可以进行分析,因为平稳性保证了时间序列数据都是出自同一分布,这样才有可能计算均值、方差、延迟K期的协方差、延迟K期的相关系数。从分析挖掘的角度来说,平稳时间序列分析在于充分挖掘时间序列之间的关系,当时间序列中的关系被提取出来后,剩下的序列就应该是一个白噪声序列。

     

    用于判断ARMA模型的自相关和偏自相关的函数分别为:自相关函数(ACF)和偏自相关函数(PACF)。

    平稳时间序列主要有:

    自回归模型(Auto Regression Model,简称AR模型
     
    移动平均模型(Moving Average Model),简称MA模型
     
    自回归移动平均(Auto Regression Moving Average Model),简称ARMA模型。

     

    AICBIC

    在实际操作中很难每次都严格遵循自相关函数和偏自相关函数进行参数确定,而且本身过程也有一些难度。而使用AICBIC准则来识别ARMA模型更加的通用和方便。AICBIC统计量都是越小越好。

    AICBIC值越小说明模型效果越好越简洁。

     

     

     

     

     

     

     

     

    展开全文
  • 时间序列分析

    2021-03-21 15:15:45
    时间序列分析和回归分析的区别: 回归分析训练得到的事目标变量y与自变量x(一个或多个)的相关性,然后通过新的自变量x来预测目标变量y。 时间序列得到的是目标变量y与时间的相关性。 回归分析擅长的是多变量与...

    时间序列分析和回归分析的区别:

    • 回归分析训练得到的是目标变量y与自变量x(一个或多个)的相关性,然后通过新的自变量x来预测目标变量y。
    • 时间序列得到的是目标变量y与时间的相关性。
    • 回归分析擅长的是多变量与目标结果之间的分析,往往与时间无关。
    • 时间序列分析建立在时间变化的基础上,分析目标变量的趋势、周期、时期和不稳定因素等。

    经典模型:

    AR、MA、ARMA、ARIMA

    AR(Auto Regressive)中文叫自回归模型,它认为过去若干时刻的点通过线性组合,再加上白噪声就可以预测未来某个时刻的点。AR 模型还存在一个阶数,称为 AR(p)模型,也叫作 p 阶自回归模型。它指的是通过这个时刻点的前 p 个点,通过线性组合再加上白噪声来预测当前时刻点的值。

    MA (Moving Average)中文叫做滑动平均模型,与 AR 模型大同小异,AR 模型是历史时序值的线性组合,MA 是通过历史白噪声进行线性组合来影响当前时刻点。MA 模型也存在一个阶数,称为 MA(q) 模型,也叫作 q 阶移动平均模型。

    ARMA (Auto Regressive Moving Average)中文叫做自回归滑动平均模型,也就是 AR 模型和 MA 模型的混合。相比 AR 模型和 MA 模型,它有更准确的估计。ARMA 模型存在 p 和 q 两个阶数,称为 ARMA(p,q) 模型。

    ARIMA (Auto Regressive Integrated Moving Average)中文叫差分自回归滑动平均模型,也叫求合自回归滑动平均模型。相比于 ARMA,ARIMA 多了一个差分的过程,作用是对不平稳数据进行差分平稳,在差分平稳后再进行建模。ARIMA 的原理和 ARMA 模型一样。相比于 ARMA(p,q) 的两个阶数,ARIMA 是一个三元组的阶数 (p,d,q),称为 ARIMA(p,d,q) 模型。其中 d 是差分阶数。

    构建函数

    from statsmodels.tsa.arima_model import ARMA
    
    ARMA(endog, order, exog=None)
    • endog:英文是 endogenous variable,代表内生变量,又叫非政策性变量,它是由模型决定的,不被政策左右,可以说是要分析的变量,或者说是项目中需要用到的变量。
    • order:代表是 p 和 q 的值,也就是 ARMA 中的阶数。
    • exog:英文是 exogenous variables,代表外生变量。外生变量和内生变量一样是经济模型中的两个重要变量。相对于内生变量而言,外生变量又称作为政策性变量,在经济机制内受外部因素的影响,不是模型要研究的变量。

    模型判断标准:

    引入 AIC 准则,也叫作赤池消息准则,衡量统计模型拟合好坏的一个标准,数值越小代表模型拟合得越好。

    例子

    import pandas as pd
    import statsmodels.api as sm
    import matplotlib.pyplot as plt
    from statsmodels.tsa.arima_model import ARMA
    
    # 创建数据
    data = [5922, 5308, 5546, 5975, 2704, 1767, 4111, 5542, 4726, 5866, 6183, 3199, 1471, 1325, 6618, 6644, 5337, 7064, 2912, 1456, 4705, 4579, 4990, 4331, 4481, 1813, 1258, 4383, 5451, 5169, 5362, 6259,
            3743, 2268, 5397, 5821, 6115, 6631, 6474, 4134, 2728, 5753, 7130, 7860, 6991, 7499, 5301, 2808, 6755, 6658, 7644, 6472, 8680, 6366, 5252, 8223, 8181, 10548, 11823, 14640, 9873, 6613, 14415,
            13204, 14982, 9690, 10693, 8276, 4519, 7865, 8137, 10022, 7646, 8749, 5246, 4736, 9705, 7501, 9587, 10078, 9732, 6986, 4385, 8451, 9815, 10894, 10287, 9666, 6072, 5418]
    data = pd.Series(data)
    # 绘制数据图
    data_index = sm.tsa.datetools.dates_from_range('1901', '1990')
    data.index = pd.Index(data_index)
    data.plot(figsize=(12, 8))
    plt.show()
    
    # 创建ARMA模型
    arma = ARMA(data, (7, 0)).fit()
    print('AIC: {:.4f}'.format(arma.aic))
    # 模型预测
    predict_y = arma.predict('1990', '2000')
    # 绘制预测结果
    fig, zx = plt.subplots(figsize=(12, 8))
    ax = data['1901':].plot()
    predict_y.plot(ax=ax)
    plt.show()
    

    运行结果:

    AIC: 1619.6323

                                 

    实际项目中,可以给 p 和 q 指定一个范围,让 ARMA 都运行一下,然后选择最适合的模型。

    实例:对比特币走势进行预测

    数据:https://github.com/cystanford/bitcoin

    from itertools import product
    import matplotlib.pyplot as plt
    import pandas as pd
    from statsmodels.tsa.arima_model import ARMA
    import warnings
    from datetime import datetime
    
    warnings.filterwarnings('ignore')
    
    df = pd.read_csv(r'D:\Study\数据分析实战\master\bitcoin-master\bitcoin_2012-01-01_to_2018-10-31.csv')
    # 将时间作为df的索引
    df.Timestamp = pd.to_datetime(df.Timestamp)
    df.index = df.Timestamp
    
    # 按照月、季度、年来统计
    df_month = df.resample('M').mean()
    df_Q = df.resample('Q-DEC').mean()
    df_year = df.resample('A-DEC').mean()
    
    # 按照天、月、季度、年来显示比特币的走势
    fig = plt.figure(figsize=[15, 7])
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.suptitle('比特币金额(美金)', fontsize=20)
    plt.subplot(221)
    plt.plot(df.Weighted_Price, '-', label='按天')
    plt.legend()
    plt.subplot(222)
    plt.plot(df_month.Weighted_Price, '-', label='按月')
    plt.subplot(223)
    plt.plot(df_Q.Weighted_Price, '-', label='按季度')
    plt.legend()
    plt.subplot(224)
    plt.plot(df_year.Weighted_Price, '-', label='按年')
    plt.legend()
    plt.show()
    
    # 设置参数范围
    ps = range(0, 3)
    qs = range(0, 3)
    parameters = product(ps, qs)
    parameters_list = list(parameters)
    
    # 寻找最优ARMA模型参数,即best_aic最小
    results = []
    best_aic = float('inf')
    for param in parameters_list:
        try:
            model = ARMA(df_month.Weighted_Price, order=(param[0], param[1])).fit()
        except ValueError:
            print('参数错误:', param)
            continue
        aic = model.aic
        if aic < best_aic:
            best_model = model
            best_aic = aic
            bet_param = param
        results.append([param, model.aic])
    
    # 输出最优模型
    result_table = pd.DataFrame(results)
    result_table.columns = ['parameters', 'aic']
    print('最优模型:', best_model.summary())
    
    # 比特币预测
    df_month2 = df_month[['Weighted_Price']]
    date_list = [datetime(2018, 11, 30), datetime(2018, 12, 31), datetime(2019, 1, 31), datetime(2019, 2, 28),
                 datetime(2019, 3, 31), datetime(2019, 4, 30), datetime(2019, 5, 31), datetime(2019, 6, 30)]
    future = pd.DataFrame(index=date_list, columns=df_month.columns)
    df_month2 = pd.concat([df_month2, future])
    df_month2['forecast'] = best_model.predict(start=0, end=91)
    
    # 比特币预测结果显示
    plt.figure(figsize=(20, 7))
    df_month2.Weighted_Price.plot(label='实际金额')
    df_month2.forecast.plot(color='r', ls='--', label='预测金额')
    plt.legend()
    plt.title('比特币金额(月)')
    plt.xlabel('时间')
    plt.ylabel('美金')
    plt.show()
    

    当对一个数值进行预测的时候,如果考虑的是多个变量和结果之间的关系,可以采用回归分析,如果考虑单个时间维度与结果的关系,可以使用时间序列分析。

    展开全文
  • - 从finance.yahoo.com下载金融时间序列数据并执行各种时间序列分析操作的工具 - 下一版本要遵循的功能文档 - 随着时间的推移,将添加更功能。 在评论或 cpass82 (at) gmail.com 中提出建议 - 代码需要缩短和...
  • python时间序列分析

    2020-09-01 16:05:32
    时间序列简单的说就是各时间点上形成的数值序列,时间序列分析就是通过观察历史数据预测未来的值。在这里需要强调一点的是,时间序列分析并不是关于时间的回归,它主要是研究自身的变化规律的(这里不考虑含外生...

    什么是时间序列

          时间序列简单的说就是各时间点上形成的数值序列,时间序列分析就是通过观察历史数据预测未来的值。在这里需要强调一点的是,时间序列分析并不是关于时间的回归,它主要是研究自身的变化规律的(这里不考虑含外生变量的时间序列)。

    为什么用python

      用两个字总结“情怀”,爱屋及乌,个人比较喜欢python,就用python撸了。能做时间序列的软件很多,SAS、R、SPSS、Eviews甚至matlab等等,实际工作中应用得比较多的应该还是SAS和R,前者推荐王燕写的《应用时间序列分析》,后者推荐“基于R语言的时间序列建模完整教程”这篇博文(翻译版)。python作为科学计算的利器,当然也有相关分析的包:statsmodels中tsa模块,当然这个包和SAS、R是比不了,但是python有另一个神器:pandas!pandas在时间序列上的应用,能简化我们很多的工作。

    环境配置

      python推荐直接装Anaconda,它集成了许多科学计算包,有一些包自己手动去装还是挺费劲的。statsmodels需要自己去安装,这里我推荐使用0.6的稳定版,0.7及其以上的版本能在github上找到,该版本在安装时会用C编译好,所以修改底层的一些代码将不会起作用。

    时间序列分析

    1.基本模型

      自回归移动平均模型(ARMA(p,q))是时间序列中最为重要的模型之一,它主要由两部分组成: AR代表p阶自回归过程,MA代表q阶移动平均过程,其公式如下:

         

      

                        依据模型的形式、特性及自相关和偏自相关函数的特征,总结如下:   

      

    在时间序列中,ARIMA模型是在ARMA模型的基础上多了差分的操作。

    2.pandas时间序列操作

    大熊猫真的很可爱,这里简单介绍一下它在时间序列上的可爱之处。和许多时间序列分析一样,本文同样使用航空乘客数据(AirPassengers.csv)作为样例。

    数据读取:

    # -*- coding:utf-8 -*-
    import numpy as np
    import pandas as pd
    from datetime import datetime
    import matplotlib.pylab as plt
    # 读取数据,pd.read_csv默认生成DataFrame对象,需将其转换成Series对象
    df = pd.read_csv('AirPassengers.csv', encoding='utf-8', index_col='date')
    df.index = pd.to_datetime(df.index)  # 将字符串索引转换成时间索引
    ts = df['x']  # 生成pd.Series对象
    # 查看数据格式
    ts.head()
    ts.head().index 

       

    查看某日的值既可以使用字符串作为索引,又可以直接使用时间对象作为索引

    ts['1949-01-01']
    ts[datetime(1949,1,1)]

    两者的返回值都是第一个序列值:112

    如果要查看某一年的数据,pandas也能非常方便的实现

    ts['1949']

        

    切片操作:

    ts['1949-1' : '1949-6']

        

    注意时间索引的切片操作起点和尾部都是包含的,这点与数值索引有所不同

    pandas还有很多方便的时间序列函数,在后面的实际应用中在进行说明。

    3. 平稳性检验

    我们知道序列平稳性是进行时间序列分析的前提条件,很多人都会有疑问,为什么要满足平稳性的要求呢?在大数定理和中心定理中要求样本同分布(这里同分布等价于时间序列中的平稳性),而我们的建模过程中有很多都是建立在大数定理和中心极限定理的前提条件下的,如果它不满足,得到的许多结论都是不可靠的。以虚假回归为例,当响应变量和输入变量都平稳时,我们用t统计量检验标准化系数的显著性。而当响应变量和输入变量不平稳时,其标准化系数不在满足t分布,这时再用t检验来进行显著性分析,导致拒绝原假设的概率增加,即容易犯第一类错误,从而得出错误的结论。

    平稳时间序列有两种定义:严平稳和宽平稳

    严平稳顾名思义,是一种条件非常苛刻的平稳性,它要求序列随着时间的推移,其统计性质保持不变。对于任意的τ,其联合概率密度函数满足:

         

    严平稳的条件只是理论上的存在,现实中用得比较多的是宽平稳的条件。

    宽平稳也叫弱平稳或者二阶平稳(均值和方差平稳),它应满足:

    • 常数均值
    • 常数方差
    • 常数自协方差

    平稳性检验:观察法和单位根检验法

    基于此,我写了一个名为test_stationarity的统计性检验模块,以便将某些统计检验结果更加直观的展现出来。

    # -*- coding:utf-8 -*-
    from statsmodels.tsa.stattools import adfuller
    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
    
    # 移动平均图
    def draw_trend(timeSeries, size):
        f = plt.figure(facecolor='white')
        # 对size个数据进行移动平均
        rol_mean = timeSeries.rolling(window=size).mean()
        # 对size个数据进行加权移动平均
        rol_weighted_mean = pd.ewma(timeSeries, span=size)
    
        timeSeries.plot(color='blue', label='Original')
        rolmean.plot(color='red', label='Rolling Mean')
        rol_weighted_mean.plot(color='black', label='Weighted Rolling Mean')
        plt.legend(loc='best')
        plt.title('Rolling Mean')
        plt.show()
    
    def draw_ts(timeSeries):
        f = plt.figure(facecolor='white')
        timeSeries.plot(color='blue')
        plt.show()
    
    '''
      Unit Root Test
       The null hypothesis of the Augmented Dickey-Fuller is that there is a unit
       root, with the alternative that there is no unit root. That is to say the
       bigger the p-value the more reason we assert that there is a unit root
    '''
    def testStationarity(ts):
        dftest = adfuller(ts)
        # 对上述函数求得的值进行语义描述
        dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used'])
        for key,value in dftest[4].items():
            dfoutput['Critical Value (%s)'%key] = value
        return dfoutput
    
    # 自相关和偏相关图,默认阶数为31阶
    def draw_acf_pacf(ts, lags=31):
        f = plt.figure(facecolor='white')
        ax1 = f.add_subplot(211)
        plot_acf(ts, lags=31, ax=ax1)
        ax2 = f.add_subplot(212)
        plot_pacf(ts, lags=31, ax=ax2)
        plt.show()

     

    观察法,通俗的说就是通过观察序列的趋势图与相关图是否随着时间的变化呈现出某种规律。所谓的规律就是时间序列经常提到的周期性因素,现实中遇到得比较多的是线性周期成分,这类周期成分可以采用差分或者移动平均来解决,而对于非线性周期成分的处理相对比较复杂,需要采用某些分解的方法。下图为航空数据的线性图,可以明显的看出它具有年周期成分和长期趋势成分。平稳序列的自相关系数会快速衰减,下面的自相关图并不能体现出该特征,所以我们有理由相信该序列是不平稳的。

                  

         

     

    单位根检验:ADF是一种常用的单位根检验方法,他的原假设为序列具有单位根,即非平稳,对于一个平稳的时序数据,就需要在给定的置信水平上显著,拒绝原假设。ADF只是单位根检验的方法之一,如果想采用其他检验方法,可以安装第三方包arch,里面提供了更加全面的单位根检验方法,个人还是比较钟情ADF检验。以下为检验结果,其p值大于0.99,说明并不能拒绝原假设。

          

    3. 平稳性处理

    由前面的分析可知,该序列是不平稳的,然而平稳性是时间序列分析的前提条件,故我们需要对不平稳的序列进行处理将其转换成平稳的序列。

    a. 对数变换

    对数变换主要是为了减小数据的振动幅度,使其线性规律更加明显(我是这么理解的时间序列模型大部分都是线性的,为了尽量降低非线性的因素,需要对其进行预处理,也许我理解的不对)。对数变换相当于增加了一个惩罚机制,数据越大其惩罚越大,数据越小惩罚越小。这里强调一下,变换的序列需要满足大于0,小于0的数据不存在对数变换。

    ts_log = np.log(ts)
    test_stationarity.draw_ts(ts_log)

        

    b. 平滑法

    根据平滑技术的不同,平滑法具体分为移动平均法和指数平均法。

    移动平均即利用一定时间间隔内的平均值作为某一期的估计值,而指数平均则是用变权的方法来计算均值

    test_stationarity.draw_trend(ts_log, 12)

        

    从上图可以发现窗口为12的移动平均能较好的剔除年周期性因素,而指数平均法是对周期内的数据进行了加权,能在一定程度上减小年周期因素,但并不能完全剔除,如要完全剔除可以进一步进行差分操作。

    c.  差分

    时间序列最常用来剔除周期性因素的方法当属差分了,它主要是对等周期间隔的数据进行线性求减。前面我们说过,ARIMA模型相对ARMA模型,仅多了差分操作,ARIMA模型几乎是所有时间序列软件都支持的,差分的实现与还原都非常方便。而statsmodel中,对差分的支持不是很好,它不支持高阶和多阶差分,为什么不支持,这里引用作者的说法:

          

    作者大概的意思是说预测方法中并没有解决高于2阶的差分,有没有感觉很牵强,不过没关系,我们有pandas。我们可以先用pandas将序列差分好,然后在对差分好的序列进行ARIMA拟合,只不过这样后面会多了一步人工还原的工作。

    diff_12 = ts_log.diff(12)
    diff_12.dropna(inplace=True)
    diff_12_1 = diff_12.diff(1)
    diff_12_1.dropna(inplace=True)
    test_stationarity.testStationarity(diff_12_1)
    

        

    从上面的统计检验结果可以看出,经过12阶差分和1阶差分后,该序列满足平稳性的要求了。

    d. 分解

    所谓分解就是将时序数据分离成不同的成分。statsmodels使用的X-11分解过程,它主要将时序数据分离成长期趋势、季节趋势和随机成分。与其它统计软件一样,statsmodels也支持两类分解模型,加法模型和乘法模型,这里我只实现加法,乘法只需将model的参数设置为"multiplicative"即可。

    from statsmodels.tsa.seasonal import seasonal_decompose
    decomposition = seasonal_decompose(ts_log, model="additive")
    
    trend = decomposition.trend
    seasonal = decomposition.seasonal
    residual = decomposition.resid
    

        

    得到不同的分解成分后,就可以使用时间序列模型对各个成分进行拟合,当然也可以选择其他预测方法。我曾经用过小波对时序数据进行过分解,然后分别采用时间序列拟合,效果还不错。由于我对小波的理解不是很好,只能简单的调用接口,如果有谁对小波、傅里叶、卡尔曼理解得比较透,可以将时序数据进行更加准确的分解,由于分解后的时序数据避免了他们在建模时的交叉影响,所以我相信它将有助于预测准确性的提高。

    4. 模型识别

    在前面的分析可知,该序列具有明显的年周期与长期成分。对于年周期成分我们使用窗口为12的移动平进行处理,对于长期趋势成分我们采用1阶差分来进行处理。

    rol_mean = ts_log.rolling(window=12).mean()
    rol_mean.dropna(inplace=True)
    ts_diff_1 = rol_mean.diff(1)
    ts_diff_1.dropna(inplace=True)
    test_stationarity.testStationarity(ts_diff_1)

         

    观察其统计量发现该序列在置信水平为95%的区间下并不显著,我们对其进行再次一阶差分。再次差分后的序列其自相关具有快速衰减的特点,t统计量在99%的置信水平下是显著的,这里我不再做详细说明。

    ts_diff_2 = ts_diff_1.diff(1)
    ts_diff_2.dropna(inplace=True)

          

    数据平稳后,需要对模型定阶,即确定p、q的阶数。观察上图,发现自相关和偏相系数都存在拖尾的特点,并且他们都具有明显的一阶相关性,所以我们设定p=1, q=1。下面就可以使用ARMA模型进行数据拟合了。这里我不使用ARIMA(ts_diff_1, order=(1, 1, 1))进行拟合,是因为含有差分操作时,预测结果还原老出问题,至今还没弄明白。 

    from statsmodels.tsa.arima_model import ARMA
    model = ARMA(ts_diff_2, order=(1, 1)) 
    result_arma = model.fit( disp=-1, method='css')

    5. 样本拟合

     模型拟合完后,我们就可以对其进行预测了。由于ARMA拟合的是经过相关预处理后的数据,故其预测值需要通过相关逆变换进行还原。

    predict_ts = result_arma.predict()
    # 一阶差分还原
    diff_shift_ts = ts_diff_1.shift(1)
    diff_recover_1 = predict_ts.add(diff_shift_ts)
    # 再次一阶差分还原
    rol_shift_ts = rol_mean.shift(1)
    diff_recover = diff_recover_1.add(rol_shift_ts)
    # 移动平均还原
    rol_sum = ts_log.rolling(window=11).sum()
    rol_recover = diff_recover*12 - rol_sum.shift(1)
    # 对数还原
    log_recover = np.exp(rol_recover)
    log_recover.dropna(inplace=True)

    我们使用均方根误差(RMSE)来评估模型样本内拟合的好坏。利用该准则进行判别时,需要剔除“非预测”数据的影响。

    ts = ts[log_recover.index]  # 过滤没有预测的记录
    plt.figure(facecolor='white')
    log_recover.plot(color='blue', label='Predict')
    ts.plot(color='red', label='Original')
    plt.legend(loc='best')
    plt.title('RMSE: %.4f'% np.sqrt(sum((log_recover-ts)**2)/ts.size))
    plt.show()

      

    观察上图的拟合效果,均方根误差为11.8828,感觉还过得去。

    6. 完善ARIMA模型

    前面提到statsmodels里面的ARIMA模块不支持高阶差分,我们的做法是将差分分离出来,但是这样会多了一步人工还原的操作。基于上述问题,我将差分过程进行了封装,使序列能按照指定的差分列表依次进行差分,并相应的构造了一个还原的方法,实现差分序列的自动还原。

    # 差分操作
    def diff_ts(ts, d):
        global shift_ts_list
        #  动态预测第二日的值时所需要的差分序列
        global last_data_shift_list
        shift_ts_list = []
        last_data_shift_list = []
        tmp_ts = ts
        for i in d:
            last_data_shift_list.append(tmp_ts[-i])
            print last_data_shift_list
            shift_ts = tmp_ts.shift(i)
            shift_ts_list.append(shift_ts)
            tmp_ts = tmp_ts - shift_ts
        tmp_ts.dropna(inplace=True)
        return tmp_ts
    
    # 还原操作
    def predict_diff_recover(predict_value, d):
        if isinstance(predict_value, float):
            tmp_data = predict_value
            for i in range(len(d)):
                tmp_data = tmp_data + last_data_shift_list[-i-1]
        elif isinstance(predict_value, np.ndarray):
            tmp_data = predict_value[0]
            for i in range(len(d)):
                tmp_data = tmp_data + last_data_shift_list[-i-1]
        else:
            tmp_data = predict_value
            for i in range(len(d)):
                try:
                    tmp_data = tmp_data.add(shift_ts_list[-i-1])
                except:
                    raise ValueError('What you input is not pd.Series type!')
            tmp_data.dropna(inplace=True)
        return tmp_data

    现在我们直接使用差分的方法进行数据处理,并以同样的过程进行数据预测与还原。

    diffed_ts = diff_ts(ts_log, d=[12, 1])
    model = arima_model(diffed_ts)
    model.certain_model(1, 1)
    predict_ts = model.properModel.predict()
    diff_recover_ts = predict_diff_recover(predict_ts, d=[12, 1])
    log_recover = np.exp(diff_recover_ts)

        

    是不是发现这里的预测结果和上一篇的使用12阶移动平均的预测结果一模一样。这是因为12阶移动平均加上一阶差分与直接12阶差分是等价的关系,后者是前者数值的12倍,这个应该不难推导。

    对于个数不多的时序数据,我们可以通过观察自相关图和偏相关图来进行模型识别,倘若我们要分析的时序数据量较多,例如要预测每只股票的走势,我们就不可能逐个去调参了。这时我们可以依据BIC准则识别模型的p, q值,通常认为BIC值越小的模型相对更优。这里我简单介绍一下BIC准则,它综合考虑了残差大小和自变量的个数,残差越小BIC值越小,自变量个数越多BIC值越大。个人觉得BIC准则就是对模型过拟合设定了一个标准(过拟合这东西应该以辩证的眼光看待)。

    def proper_model(data_ts, maxLag):
        init_bic = sys.maxint
        init_p = 0
        init_q = 0
        init_properModel = None
        for p in np.arange(maxLag):
            for q in np.arange(maxLag):
                model = ARMA(data_ts, order=(p, q))
                try:
                    results_ARMA = model.fit(disp=-1, method='css')
                except:
                    continue
                bic = results_ARMA.bic
                if bic < init_bic:
                    init_p = p
                    init_q = q
                    init_properModel = results_ARMA
                    init_bic = bic
        return init_bic, init_p, init_q, init_properModel

    相对最优参数识别结果:BIC: -1090.44209358 p: 0 q: 1 , RMSE:11.8817198331。我们发现模型自动识别的参数要比我手动选取的参数更优。

    7.滚动预测

    所谓滚动预测是指通过添加最新的数据预测第二天的值。对于一个稳定的预测模型,不需要每天都去拟合,我们可以给他设定一个阀值,例如每周拟合一次,该期间只需通过添加最新的数据实现滚动预测即可。基于此我编写了一个名为arima_model的类,主要包含模型自动识别方法,滚动预测的功能,详细代码可以查看附录。数据的动态添加:

    from dateutil.relativedelta import relativedelta
    def _add_new_data(ts, dat, type='day'):
    if type == 'day':
            new_index = ts.index[-1] + relativedelta(days=1)
        elif type == 'month':
            new_index = ts.index[-1] + relativedelta(months=1)
        ts[new_index] = dat
    
    def add_today_data(model, ts,  data, d, type='day'):
        _add_new_data(ts, data, type)  # 为原始序列添加数据
        # 为滞后序列添加新值
        d_ts = diff_ts(ts, d)
        model.add_today_data(d_ts[-1], type)
    
    def forecast_next_day_data(model, type='day'):
        if model == None:
            raise ValueError('No model fit before')
        fc = model.forecast_next_day_value(type)
        return predict_diff_recover(fc, [12, 1])

    现在我们就可以使用滚动预测的方法向外预测了,取1957年之前的数据作为训练数据,其后的数据作为测试,并设定模型每第七天就会重新拟合一次。这里的diffed_ts对象会随着add_today_data方法自动添加数据,这是由于它与add_today_data方法中的d_ts指向的同一对象,该对象会动态的添加数据。

    ts_train = ts_log[:'1956-12']
    ts_test = ts_log['1957-1':]
    
    diffed_ts = diff_ts(ts_train, [12, 1])
    forecast_list = []
    
    for i, dta in enumerate(ts_test):
        if i%7 == 0:
            model = arima_model(diffed_ts)
            model.certain_model(1, 1)
        forecast_data = forecast_next_day_data(model, type='month')
        forecast_list.append(forecast_data)
        add_today_data(model, ts_train, dta, [12, 1], type='month')
    
    predict_ts = pd.Series(data=forecast_list, index=ts['1957-1':].index)
    log_recover = np.exp(predict_ts)
    original_ts = ts['1957-1':]

        

    动态预测的均方根误差为:14.6479,与前面样本内拟合的均方根误差相差不大,说明模型并没有过拟合,并且整体预测效果都较好。

    8. 模型序列化

    在进行动态预测时,我们不希望将整个模型一直在内存中运行,而是希望有新的数据到来时才启动该模型。这时我们就应该把整个模型从内存导出到硬盘中,而序列化正好能满足该要求。序列化最常用的就是使用json模块了,但是它是时间对象支持得不是很好,有人对json模块进行了拓展以使得支持时间对象,这里我们不采用该方法,我们使用pickle模块,它和json的接口基本相同,有兴趣的可以去查看一下。我在实际应用中是采用的面向对象的编程,它的序列化主要是将类的属性序列化即可,而在面向过程的编程中,模型序列化需要将需要序列化的对象公有化,这样会使得对前面函数的参数改动较大,我不在详细阐述该过程。

    总结

    与其它统计语言相比,python在统计分析这块还显得不那么“专业”。随着numpy、pandas、scipy、sklearn、gensim、statsmodels等包的推动,我相信也祝愿python在数据分析这块越来越好。与SAS和R相比,python的时间序列模块还不是很成熟,我这里仅起到抛砖引玉的作用,希望各位能人志士能贡献自己的力量,使其更加完善。实际应用中我全是面向过程来编写的,为了阐述方便,我用面向过程重新罗列了一遍,实在感觉很不方便。原本打算分三篇来写的,还有一部分实际应用的部分,不打算再写了,还请大家原谅。实际应用主要是具体问题具体分析,这当中第一步就是要查询问题,这步花的时间往往会比较多,然后再是解决问题。以我前面项目遇到的问题为例,当时遇到了以下几个典型的问题:1.周期长度不恒定的周期成分,例如每月的1号具有周期性,但每月1号与1号之间的时间间隔是不相等的;2.含有缺失值以及含有记录为0的情况无法进行对数变换;3.节假日的影响等等。

     

    附录

     View Code

     修改的arima_model代码

    + View Code

      

    展开全文
  • 时间序列分析之协整检验

    万次阅读 多人点赞 2019-02-07 14:18:02
    平稳性是进行时间序列分析的一很重要的前提,很模型都是基于平稳下进行的,而现实中,很时间序列都是非平稳的,所以协整是从分析时间序列的非平稳性入手的。 协整的内容是: 设序列是 d 阶单整的,记为,...

    协整关系

    协整(Cointegration)理论是恩格尔(Engle)和格兰杰(Granger)在1978年提出的。平稳性是进行时间序列分析的一个很重要的前提,很多模型都是基于平稳下进行的,而现实中,很多时间序列都是非平稳的,所以协整是从分析时间序列的非平稳性入手的

    协整的内容是:

    设序列X_{t}是 d 阶单整的,记为X_{t}\sim I(d),如果存在一个非零向量 \beta 使得Y_{t} = \beta X_{t} \sim I(d-b),则称X_{t}具有 d, b 阶协整关系,记为X_{t}\sim CI(d, b),则 \beta 称为协整向量。

    特别当 X_{t} 和 Y_{t} 都是一阶单整时,一般而言,X_{t} 和 Y_{t} 的线性组合 Y_{t} - \beta X_{t} 仍然是一阶单整的,但是对于某些非零向量 \beta ,会使得 Y_{t} - \beta X_{t}\sim I(0),此时非零向量 \beta 称作协整向量,其中每一项  \beta_{t} 为 t 时刻的协整系数。通俗点说,如果两组序列都是非平稳的,但是经过一阶差分后是平稳的,且这两组序列经过某种线性组合也是平稳的,则它们之间就存在协整关系。

    协整理论的意义在于:

    • 首先,因为或许单个序列是非平稳的,但是通过协整我们可以建立起两个或者多个序列之间的平稳关系,进而充分应用平稳性的性质。
    • 其次,可以避免伪回归。如果一组非平稳的时间序列不存在协整关系,那么根据它们构造的回归模型就可能是伪回归。
    • 区别变量之间长期均衡关系和短期波动关系。

    非平稳序列很容易出现伪回归,而协整的意义就是检验它们的回归方程所描述的因果关系是否是伪回归的,所以常用的协整检验有两种:Engel-Granger 两步协整检验法和 Johansen 协整检验法,它们二者的区别在于 Engler-Granger 采用的是一元方程技术,而 Johansen 则是多元方程技术,所以Johansen 协整检验法受限更小。

    Engel-Granger 两步协整检验法

    EG检验的方法实际上就是对回归方程的残差进行单位根检验

    因为从协整的角度来看,因变量能被自变量的线性组合所解释,说明二者之间具有稳定的均衡关系;因变量不能被自变量解释的部分就构成了一个残差序列,这个残差序列不应该是序列相关的,也就是说残差应该是平稳的。所以EG检验一组变量是否具有协整关系也就是检验残差序列是否是平稳的。

    Engle-Granger提出的两步法的步骤如下:

    1、用 OLS 估计协整回归方程,从而得到协整系数:

    \large : \begin{center} Y_{t} = \beta X_{t} + \epsilon_{t}\end{center}

    2、检验 \large \epsilon_{t} 的平稳性,如果 \large \epsilon_{t} 平稳,则 X_{t} , Y_{t} 是协整的,否则不成立。对于\large \epsilon_{t} 平稳性的检验通常用 ADF 检验。

    Johansen Test 协整检验法

    当协整检验的VAR模型中如果含有多个滞后项时,如下:

    \large : \begin{center} Y_{t} = \beta_{1} X_{t} + \beta_{2} X_{t-1} + \beta_{3} X_{t-2} + ...+ \epsilon_{t}\end{center}

    采用EG检验就不能找出两个以上的协整向量了,此时可以用 Johansen Test 来进行协整检验,它的思想是采用极大似然估计来检验多变量之间的协整关系。

    具体步骤以后填

    -------------------------------------------------

    用 python 代码进行协整检验

    我们从 rb 期货中选择两个品种进行分析,具体的品种根据相关性选择,后期会另外补充。

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    
    a_price = pd.read_csv('./CloseA.csv')[:200]
    b_price = pd.read_csv('./CloseB.csv')[:200]
    
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.plot(range(len(a_price)), a_price)
    ax.plot(range(len(b_price)), b_price)
    ax.legend(['a','b'])
    plt.show()

     从图中看,两个品种具有很强的相关性,并且都是不稳定的。

    下面,我们通过ADF检验来看一下,两个序列是否是一阶单整的:

    from statsmodels.tsa.stattools import adfuller
    
    a_price = np.reshape(a_price.values, -1)
    a_price_diff = np.diff(a_price)
    
    b_price = np.reshape(b_price.values, -1)
    b_price_diff = np.diff(b_price)
    
    print(adfuller(a_price_diff))
    print(adfuller(b_price_diff))
    
    (-15.436034211511204, 2.90628134201655e-28, 0, 198, {'1%': -3.4638151713286316, '5%': -2.876250632135043, '10%': -2.574611347821651}, 1165.1556545612445)
    (-14.259156751414892, 1.4365811614283181e-26, 0, 198, {'1%': -3.4638151713286316, '5%': -2.876250632135043, '10%': -2.574611347821651}, 1152.4222884399824)

    从结果来看,两个序列都满足一阶单整,下面来判断两者是否存在协整关系。statsmodels 模块中有 coint 函数可以用来检测协整关系,它的内部实现就是基于 EG 协整检验的。

    coint 函数如下:

    def coint(y0, y1, trend='c', method='aeg', maxlag=None, autolag='aic',
              return_results=None):
        """Test for no-cointegration of a univariate equation
    
        The null hypothesis is no cointegration. Variables in y0 and y1 are
        assumed to be integrated of order 1, I(1).
    
        This uses the augmented Engle-Granger two-step cointegration test.
        Constant or trend is included in 1st stage regression, i.e. in
        cointegrating equation.
    
        **Warning:** The autolag default has changed compared to statsmodels 0.8.
        In 0.8 autolag was always None, no the keyword is used and defaults to
        'aic'. Use `autolag=None` to avoid the lag search.
    
        Parameters
        ----------
        y1 : array_like, 1d
            first element in cointegrating vector
        y2 : array_like
            remaining elements in cointegrating vector
        trend : str {'c', 'ct'}
            trend term included in regression for cointegrating equation
    
            * 'c' : constant
            * 'ct' : constant and linear trend
            * also available quadratic trend 'ctt', and no constant 'nc'
    
        method : string
            currently only 'aeg' for augmented Engle-Granger test is available.
            default might change.
        maxlag : None or int
            keyword for `adfuller`, largest or given number of lags
        autolag : string
            keyword for `adfuller`, lag selection criterion.
    
            * if None, then maxlag lags are used without lag search
            * if 'AIC' (default) or 'BIC', then the number of lags is chosen
              to minimize the corresponding information criterion
            * 't-stat' based choice of maxlag.  Starts with maxlag and drops a
              lag until the t-statistic on the last lag length is significant
              using a 5%-sized test
    
        return_results : bool
            for future compatibility, currently only tuple available.
            If True, then a results instance is returned. Otherwise, a tuple
            with the test outcome is returned.
            Set `return_results=False` to avoid future changes in return.
    
        Returns
        -------
        coint_t : float
            t-statistic of unit-root test on residuals
        pvalue : float
            MacKinnon's approximate, asymptotic p-value based on MacKinnon (1994)
        crit_value : dict
            Critical values for the test statistic at the 1 %, 5 %, and 10 %
            levels based on regression curve. This depends on the number of
            observations.
    
        Notes
        -----
    from statsmodels.tsa.stattools import coint
    
    print(coint(a_price, b_price))
    
    (-3.9532731584015215, 0.008362293067615467, array([-3.95232129, -3.36700631, -3.06583125]))
    

     从返回结果可以看出 t-statistic 值要小于1%的置信度,所以有99%的把握拒绝原假设,而且p-value的值也比较小,所以说存在协整关系。

     

    Ref :

    《统计套利:理论与实战》金志宏著

     

    展开全文
  • 小波分析时间序列的时间尺度分析 一问题引入 1.时间序列Time Series 时间序列是指将某种现象某一...频域分析如Fourier变换虽具有准确的频率定位功能但仅适合平稳时间序列分析 然而许多现象如河川径流地震波暴雨洪水等
  • 时间序列数据有很种定义,它们以不同的方式表示相同的含义。一简单的定义是,时间序列数据是包含序列时间戳的数据点。 时间序列数据的来源是周期性测量或观测。我们观察了许多行业的时间序列数据。举几例子: ...
  • 在这里需要强调一点的是,时间序列分析并不是关于时间的回归,它主要是研究自身的变化规律的(这里不考虑含外生变量的时间序列)。 为什么用python  用两字总结“情怀”,爱屋及乌,个人比较喜欢python,就用...
  • 尽管均值回归投资组合是在相关研究中基于单个标准得出的,但我们通过优化多个均值回归标准来导出均值回归投资组合。 我们期望基于多个指标的均值回归投资组合会导致更高的回报/风险。 我们在多资产市场中进行了实证...
  • 时间序列分析 时间序列分析是一种处理时间序列数据或趋势分析的统计技术。 时间序列数据表示数据处于一系列特定的时间段或间隔中。 数据分为三种类型: 时间序列数据: 关于变量在不同时间采用的值的一组观察值。 ...
  • 时间序列分析介绍

    2011-11-30 00:06:02
    这也是网上找到的一资源,但不是在CSDN上。时间序列已经被诸多研究所使用,但是很需要应用此研究方法的人士还是会对它的操作弄不清楚,希望这幻灯片能帮助到大家。
  • 通道时间序列进行自适应定向传递函数分析。函数使用自适应MVAR模型(MVAAR)对时间序列执行DTF分析。MVAAR模型为每个时间点生成一个更新的系数矩阵,然后用于DTF计算。输出形式为gamma2_集(a,b,c,d),其中a...
  • 为了预测论坛舆情及其动态演变趋势,基于多时间序列的关联分析,集中分析了论坛中3量的时间序列之间的关联规则:活跃者之间的关系强度的时间序列、坚定支持者人数的时间序列以及坚定支持者成员的变化频度的时间序列。...
  • 用于在 Matlab 中执行高度比较的时间序列分析的软件。 包含用于从给定时间序列中提取 7000 多个特征的代码,以及用于可视化和分析时间序列数据集结果的函数。
  • pyTSA 通常通过在不同参数配置下执行仿真合奏来分析许多动力学系统。... pyTSA是扩展,可让您处理多个时间序列。 该源代码当前托管在GitHub上,为 。 对于最新版本: git clone https://github.com/luca-dex/pyTSA
  • Arauto是一开源框架,旨在简化建模和实验时间序列分析和预测的过程。 Arauto提供了一直观的交互式界面,可以使用自回归模型(AR,ARMA,ARIMA,SARIMA,ARIMAX和SARIMAX)探索模型的不同参数。 越来越的估计器...
  • python数据分析:时间序列分析(Time series analysis)

    万次阅读 热门讨论 2018-12-06 14:01:20
    何为时间序列分析: 时间序列经常通过折线图绘制。时间序列用于统计,信号处理,模式识别,计量经济学,数学金融,天气预报,地震预测,脑电图,控制工程,天文学,通信工程,以及主要涉及时间测量的任何应用科学和...
  • 实现论文中介绍的程序Krafty、Rosen、Stoffer、Buysse 和 Hall(2017 年)“复制多个时间序列的条件光谱分析与夜间生理学的应用”美国统计协会杂志 当从多个受试者观察数据时,进行贝叶斯分析以量化静态标量结果与多...
  • 我们可以用时间序列分析解决一些预测模型,这种方法可以预测数据在未来的发展趋势。下面将会介绍时间序列分析的基础理论。 基础介绍 1.时间序列 时间戳(timestamp) 固定周期(period) 时间间隔(interval) 2.数据...
  • 将小波分辨分析与符号时间序列分析方法相结合,确定不同尺度上股指波动的主要模式与异常模式,为不同类型的投资者提供参考。通过离散小波分析得到波动序列不同尺度的细节,针对不同尺度上的细节,采用符号时间序列分析...
  • 这是一个时间序列分析项目,用于分析和预测卢科含水层的地下水深度。 在这里,我执行了单变量分析,但我将逐步介绍清理常规数据和子集变量的数据的步骤,我认为这些数据可能对下游变量分析有用。 数据由意大利的...
  • 第三,为了展示其功能性,我们将在同态加密上下文(DOING)中实现一组通用的时间序列分析工具。 此外,我们计划开发一种自举技术,为实时数据处理提供手段。 我们认为,专注于这些领域,其中围绕隐私的问题起着至...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,870
精华内容 748
关键字:

多个时间序列分析