精华内容
下载资源
问答
  • 分享Matlab在时间序列分析中的应用,附带完整的目录,扫描版,与君共勉~
  • MATLAB 在时间序列分析中的应用PDF版本,由张善文,雷英杰等编写
  • MATLAB在时间序列分析中的应用_张善文等2007
  • 本书简明扼要地介绍了时间序列及其相关领域基本概念和基本理论,对ARMA序列预测、时间序列统计分析、时间序列时频分析和时间序列小波变换等给出了有关...,介绍了MATLAB时间序列分析有关函数功能和用法...
  • 31 1.5 时间序列分析的相关特征量 1.5.3 时间序列发展速度与增长速度 环比发展速度报告期水平与前一时期水平之比 1 ? ? i i i Y Y R n i , , 2 , 1 ? ? 定基发展速度 0 Y Y R i i ? n i , , 2 , 1 ? ? 两种关系 0 ...
  • MATLAB 金融时间序列分析及建模中的应用 间序列建模,解次预测问题~
  • 时间序列分析在第二次世界大战前应用于经济预测。二次大战中和战后,军事科学、空间科学、气象预报和工业自动化等部门的应用更加广泛。时间序列分析(Time series analysis)是一种动态数据处理的统计方法。该方法...
  • 所谓年降水量时间序列的多时间尺度是指:年降水量演化过程,并不存在真正意义上变化周期,而是其变化周期随着研究尺度不同而发生相应变化,这种变化一般表现为小时间尺度变化周期往往嵌套大尺度变化...
  • Financial ToolboxMatlab自带金融工具箱具有下列功能日期数据处理资产均值方差分析时间序列分析固定收益计算有价证卷收益和价格统计分析定价和灵敏度分析年金和现金流计算抵押支持债卷 2. Financial Derivatives ...
  • 时间序列分析实验报告 基于matlab时间序列分析在实际问题中的应用 时间序列分析(Time series analysis)是一种动态数据处理的统计方法。该方法基于随机过程理论和数理统计学方法,研究随机数据序列所遵从的统计规律...

    时间序列分析实验报告

    基于matlab的时间序列分析在实际问题中的应用 时间序列分析(Time series analysis)是一种动态数据处理的统计方法。该方法基于随机过程理论和数理统计学方法,研究随机数据序列所遵从的统计规律,以用于解决实际问题。时间序列分析不仅可以从数量上揭示某一现象的发展变化规律或从动态的角度刻画某一现象和其他现象之间的内在的数量关系及其变化规律性,而且运用时间序列模型可以预测和控制现象的未来行为,以达到修正或重新设计系统使其达到最优状态。 时间序列是指观察或记录到的一组按时间顺序排列的数据。如某段时间内。某类产品产量的统计数据,某企业产品销售量,利润,成本的历史统计数据;某地区人均收入的历史统计数据等实际数据的时间序列。展示了研究对象在一定时期内的发展变化过程。可以从中分析寻找出其变化特征,趋势和发展规律的预测信息。时间序列预测方法的用途广泛,它的基本思路是,分析时间序列的变化特征,选择适当的模型形式和模型参数以建立预测模型,利用模型进行趋势外推预测,最后对模型预测值进行评价和修正从而得到预测结果。目前最常用的拟合平稳序列模型是ARMA模型,其中AR和MA模型可以看成它的特例。 一.时间序列的分析及建模步骤 (1) 判断序列平稳性, 若平稳转到(3),否则转到(2)。 平稳性检验是动态数据处理的必要前提,因为时间序列算法的处理对象是平稳性的数据序列,若数据序列为非平稳,则计算结果将会出错。在实际应用中,如某地区的GDP,某公司的销售额等时间序列可能是非平稳的,它们在整体上随着时间的推移而增长,其均值随时间变化而变化。通常将GDP等非平稳序列作差分或预处理。所以获得一个时间序列之后,要对其进行分析预测,首先要保证该时间序列是平稳化的。平稳性检验的方法有数据图、逆序检验、游程检验、自相关偏相关系数、特征根、参数检验等。本实验中采用数据图法,数据图法比较直观。 (2) 对序列进行差分运算。 一般而言,若某序列具有线性趋势,则可以通过对其进行一次差分而将线性趋势剔除掉。差分的实质是自回归。对线性趋势的序列,一阶差分即可提取确定性信息若序列具有二次趋势,则两次差分后可变换为平稳序列,若序列具有d次多项式趋势,则通过d次差分后可变为平稳序列。 (3) 计算序列的自相关系数和偏相关系数,判断截尾性,对序列模型进行识别。 若序列自相关系数在q步截尾(即kq时,显著的等于零)并且偏相关系数被负指数函数收敛到零,则可判断为MA(q)序列。 若序列偏相关系数在p步截尾,并且序列自相关系数被负指数函数控制收敛到零,则可判断凡为AR(p)序列。 若序列和序列皆不截尾,且自相关系数和偏相关系数都被负指数函数控制收敛到零 则序列为ARMA序列。以上都不满足,则序列是非平稳的。 (4)对模型阶数进行估计 模型定阶的方法有残差方差图法,自相关函数和偏自相关函数法,F检验法,最佳准则函数法等。本实验采用自相关函数和偏自相关函数法和AIC准则。 (5)估计模型参数。 不论是那种时间序列模型,要建立完整的估计方程就需要知道其中的参数。可以用矩估计、最小二乘估计、极大似然估计等方法得到模型中的参数。本实验采用最小二乘估计。 (6)模型适应性检验及优化,计算残差方差是否最小,若是最小转到(7),否则转到(4)。 模型的适应性检验实质上是对at的独立性检验,如果得到的模型已经是适应性模型,那么at一定是完全或基本上接近独立的,这时若再增加模型的阶数,新增加的参数可能接近等于0,剩余平方和也不会因增加模型的阶数而显著减小。常用的适应性检验方法有:散点图法,估计参数法,F检验法等。估计参数法比较粗略。 (7)根据参数建立方程,预测序列未来走势等。 将各个模型的参数估计出来之后,结合估计出来的模型的阶数,可以根据各个模型的估计方程建立具体的估计方程,代入已知的时间序列的项从而对时间序列中的未来的项进行预测。其中模型方程中的白噪声序列可以通过时间序列本身经过相关处理生成。 二.实验内容 对我国 1978—2005 年的 GDP 进行建模分析并对2006-2011年的GDP进行预测,并与实际值比较,估计预测质量。实验利用MATLAB软件进行建模仿真及预测。我国 1978—2005 年的 GDP值列于下表1 表1为我国1978-2005年的GDP (亿元) 1978年 1979年 1980年 1981年 1982年 1983年 1984年 3645.2 4062.6 4545.6 4891.6 5323.4 5962.7 7208.1 1985年 1986年 1987年 1988年 1989年 1990年 1991年 9016 19275.2 12058.6 15042.8 16992.3 18667.8 21781.5 1992年 1993年 1994年 1995年 1996年 1997年 1998年 26923.5 35333.9 48197.9 60793.7 71176.6 78973 84402.3 1999年 2000年 2001年 2002年 2003年 2004年 2005年 89677.1 99214.6 109655.2 120332.7 135822.8 159878.3 183084.8 (1)对序列做预处理,判断平稳性 设原序列数据表示为共28个数据,由序列图明显看出序列不平稳,做一阶差分运算后数据平稳。再对数据进行标准化处理,对差分后的数据序列求均值: 标准差 标准化处理公式为 数据预处理前后的对比图和标准化处理后的图如下: 图1 一次差分前后序列图对比 图2 数据标准化后的图 (2)计算自相关和偏相关系数,对序列的模型和阶数进行判断 判断依据是:AR模型自相关系数拖尾,偏相关系数截尾。 MA自相关系数截尾,偏相关系数拖尾。ARMA自相关和偏相关系数都拖尾。自相关系数拖尾可根据点图来判断,只要愈变愈小(k增大时)。对于,常采用的方法是:当k>p时,平均20个中至多有一个使﹥,则认为截尾在k=p处,因为当N很大时,样本偏相关函数(k>p)近似服从正态分布。自相关系数和偏相关系数如图3和4所示。 从图中可以看出自相关系数具有拖尾性,不是MA模型,偏相关系数在1之后≤=0.378,渐进趋于零。所以可以判定序列模型是AR模型,初步判定为1阶。也可认为模型的阶数为2,考虑到2阶计算量也不是很大,所以定为2阶。 处理后序列自相关系数 示于表一。 样本的偏相关函数,…. 示于表二。 表一 自相关系数表 0.6325 0.4502 0.3012 0.2076 0.1254 0.0823 0.1054 0.2177 0.2010 0.1640 0.0483 -0.1.81 -0.2348 -0.2642 -0.2617 -0.2550 -0.2599 -0.2001 -0.0929 -0.2172 表二 偏相关系数表 0.6325 0.

    展开全文
  • 原文链接:http://tecdat.cn/?p=17622​tecdat.cn最近,我们继续对时间序列建模进行探索,研究时间序列模型自回归和条件异方差族。我们想了解自回归移动平均值(ARIMA...这些时间序列分析模型是什么?拟合ARIMA和G...

    原文链接:

    http://tecdat.cn/?p=17622tecdat.cn

    最近,我们继续对时间序列建模进行探索,研究时间序列模型的自回归和条件异方差族。我们想了解自回归移动平均值(ARIMA)和广义自回归条件异方差(GARCH)模型。它们在量化金融文献中经常被引用。

    接下来是我对这些模型的理解,基于拟合模型的预测的一般拟合程序和简单交易策略的摘要。

    这些时间序列分析模型是什么?

    拟合ARIMA和GARCH模型是一种发现时间序列中的观测值,噪声和方差影响时间序列的方式。适当地拟合的这种模型将具有一定的预测效用,当然前提是该模型在将来的一段时间内仍非常适合基础过程。

    ARMA

    ARMA模型是自回归(AR)模型和移动平均(MA)模型的线性组合。AR模型其预测变量是该序列的先前值。MA模型在结构上类似于AR模型,除了预测变量是噪声项。p,q阶的自回归移动平均模型– ARMA(p,q)–是两者的线性组合,可以定义为:

    7c1a48e8e96ca6815f4e16f1f3658815.png

    其中 w是白噪声,而a和 b是模型的系数。

    ARIMA(p,d,q)模型是ARMA(p,q)模型,它们的差值是d倍-或积分(I)-以产生平稳序列。

    GARCH

    最后,GARCH模型还试图说明时间序列的异方差行为(即,波动性聚类的特征)以及该序列先前值的序列影响(由AR解释)和噪声项(由MA解释)。GARCH模型使用方差本身的自回归过程,也就是说,它使用方差的历史值来说明方差随时间的变化。

    那么我们如何应用这些模型?

    有了这种背景,我接下来将ARIMA / GARCH模型拟合到EUR / USD汇率,并将其用作交易系统的基础。使用拟合程序估算每天的模型参数,然后使用该模型预测第二天的收益,并相应保持一个交易日。

    在每个交易日结束时,会使用滚动返回窗口来拟合最佳ARIMA / GARCH模型。拟合过程基于对参数的搜索,以最小化Aikake信息准则,但是也可以使用其他方法。例如,我们可以选择最小化贝叶斯信息准则的参数,这可以通过惩罚复杂模型(即具有大量参数的模型)来减少过度拟合。

    我选择使用1000天的滚动窗口来拟合模型,但这是优化的参数。有一种情况是在滚动窗口中使用尽可能多的数据,但这可能无法足够快地捕获不断变化的模型参数以适应不断变化的市场。

    这是代码:


    1. ### ARIMA / GARCH交易模型

    2. #获取数据并初始化对象以保存预测

    3. EURUSD <- read.csv('EURUSD.csv', header = T)

    4. returns <- diff(log(EURUSD$C)) ## ROC也可以使用:默认情况下计算对数

    5. #遍历每个交易日,从滚动窗口中估计最佳模型参数

    6. #并预测第二天的收益

    7. for (i in 0:forecasts.length) {

    8. roll.returns <- returns[(1+i):(window.length + i)] #创建滚动窗口

    9. # 估计最佳ARIMA模型

    10. for (p in 0:5) for (q in 0:5) { #将可能的阶限制为p,q <= 5

    11. if (p == 0 && q == 0) next #将可能的阶限制为p,q <= 5

    12. current.aic <- AIC(arimaFit)

    13. if (current.aic < final.aic) { #如果AIC降低则保留阶数

    14. final.aic <- current.aic

    15. final.order <- c(p,0,q)

    16. final.arima <- arima(roll.returns, order = final.order)

    17. }

    18. }

    19. else next

    20. }

    21. # 指定并拟合GARCH模型

    22. spec = ugarchspec(

    23. # 指定并拟合GARCH模型

    24. # 模型并不总是收敛-在这种情况下,将0值分配给预测值和p.val

    25. if (is(fit, "warning")) {

    26. forecasts[i+1] <- 0

    27. directions[i+1] <- ifelse(x[1] > 0, 1, -1) #仅定向预测

    28. forecasts[i+1] <- x[1] # 预测的实际值

    29. print(forecasts[i])

    30. # 残差分析

    31. resid <- as.numeric(residuals(fit, standardize = TRUE))

    32. }

    33. forecasts.ts <- xts(forecasts, dates[(window.length):length(returns)])

    34. # 创建滞后的序列预测

    35. ag.direction <- ifelse(ag.forecasts > 0, 1, ifelse(ag.forecasts < 0, -1, 0))

    36. # 创建滞后的序列预测

    37. ag.direction.returns <- ag.direction * returns[(window.length):length(returns)]

    38. ag.direction.returns[1] <- 0 # remove NA

    39. # 创建ARIMA / GARCH买入持有的回测

    40. ag.curve <- cumsum( ag.direction.returns)

    41. # 绘制两条曲线:策略收益和累积收益

    42. plot(x = both.curves[,"Strategy returns"], xl


    首先,仅是方向性预测:在预测正收益时购买,在预测负收益时出售。这种方法的结果如下所示(不包含交易费用): 在上面的模型拟合过程中,我保留了实际的预测收益值以及预测收益的方向。我想研究预测返回值的大小的预测能力。具体来说,当预测回报的幅度低于某个阈值时进行过滤交易会改善策略的性能吗?下面的代码以较小的返回阈值执行此分析。为简单起见,我将预测对数收益率转换为简单收益率,以便能够控制预测的信号并易于实现。

    0da0a789ca54155dc387a97c0d0d3297.png

    1. # 仅在预测超过阈值幅度时测试进入交易

    2. simp.forecasts <- exp(ag.forecasts) - 1

    3. ag.threshold.returns[1] <- 0 # 删除缺失

    4. ag.threshold.curve <- cumsum(ag.threshold.returns))

    5. # 绘制两条曲线:策略收益和累积收益

    6. plot(x = both.curves[,"Strategy returns"], xlab = "Time", y

    结果覆盖了原始策略: 在我看来,我们拟合某段时间的ARIMA / GARCH模型可能比其他时间更好或更糟地表示了基础过程。当我们对模型缺乏信心时,过滤交易可能会改善性能。这种方法要求评估每天模型拟合的统计显着性,并且仅在显着性超过特定阈值时才输入交易。有许多方法可以实现这一点。首先,我们可以检查模型残差的相关图,并在此基础上判断拟合优度。理想情况下,残差的相关图类似于白噪声过程,没有序列相关性。残差的相关图可以在R中构造如下:

    a285b53154d517771f1a78396057ef3b.png

    1. acf(fit@fit$residuals, main = 'ACF of Model Residuals')

    77ea27c7561d731c8b28b8e66809d0f7.png


    尽管此相关图表明模型拟合良好,但显然它不是一种很好的方法,因为它依赖于主观判断,更不用说人类有能力审查每天的模型。更好的方法是检查Ljung-Box统计量是否适合模型拟合。Ljung-Box是用于评估拟合模型残差的自相关是否与零显着不同的假设检验。在该检验中,零假设是残差的自相关为零;另一种是我们的时间序列分析具有序列相关性。否定空值并确认替代值将意味着该模型不是很好的拟合,因为残差中存在无法解释的结构。Ljung-Box统计量在R中的计算方式如下:


    1. Box-Ljung test

    2. data: resid

    3. X-squared = 23.099, df = 20, p-value = 0.284

    在这种情况下,p值可以证明残差是独立的,并且该特定模型非常合适。作为解释,为了增加残差的自相关,Ljung-Box测试统计量(在上面的代码输出中为X平方)变得更大。p值是在原假设下获得大于或大于检验统计量的值的概率。因此,在这种情况下,高p值是残差独立性的证据。

    将Ljung-Box检验应用于每天的模型拟合可发现很少几天独立残差的零假设被拒绝,因此将策略扩展为过滤模型拟合不太可能增加太多价值:

    abf85355ed4361279036b2f0be8be296.png

    时间序列分析结论和未来工作

    在回溯测试期间,ARIMA / GARCH策略的表现优于欧元/美元汇率的买入和持有策略,但是,该表现并不出色。似乎可以通过过滤诸如预测幅度和模型拟合优度之类的特征来提高策略的性能,尽管后者在此特定示例中并没有增加太多价值。另一个过滤选项是为每天的预测计算95%的置信区间,并且仅在每个信号相同时才输入交易,尽管这会大大减少实际进行的交易数量。

    GARCH模型还有许多其他种类,例如指数,积分,二次,阈值和转换等。与本示例中使用的简单GARCH(1,1)模型相比,这些方法可能会或可能不会更好地表示基础过程。

    我最近发现非常有趣的一个研究领域是通过不同模型的智能组合对时间序列进行预测。例如,通过取几个模型的单个预测的平均值,或对预测的信号进行多数表决。要借用一些机器学习的术语,这种“集合”模型通常会比任何组合模型产生更准确的预测。也许有用的方法是使用经过适当训练的人工神经网络或其他统计学习方法来对此处提出的ARIMA / GARCH模型进行预测。也许我们可以期望ARIMA / GARCH模型能够捕获时间序列的任何线性特征,而神经网络可能非常适合非线性特征。

    如果您有任何想法可以改善时间序列分析模型的预测准确性,欢迎在下方评论或联系我们。


    99a98265910b1e01a765c96d35323438.png

    最受欢迎的见解

    1.HAR-RV-J与递归神经网络(RNN)混合模型预测和交易大型股票指数的高频波动率

    2.R语言中基于混合数据抽样(MIDAS)回归的HAR-RV模型预测GDP增长

    3.波动率的实现:ARCH模型与HAR-RV模型

    4.R语言ARMA-EGARCH模型、集成预测算法对SPX实际波动率进行预测

    5.GARCH(1,1),MA以及历史模拟法的VaR比较

    6.R语言多元COPULA GARCH 模型时间序列预测

    7.R语言基于ARMA-GARCH过程的VAR拟合和预测

    8.matlab预测ARMA-GARCH 条件均值和方差模型

    9.R语言对S&P500股票指数进行ARIMA + GARCH交易策略

    展开全文
  • python时间序列分析

    2020-09-01 16:05:32
    这里需要强调一点是,时间序列分析并不是关于时间回归,它主要是研究自身变化规律(这里不考虑含外生变量时间序列)。 为什么用python  用两个字总结“情怀”,爱屋及乌,个人比较喜欢python,就用...

    什么是时间序列

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

    为什么用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

      

    展开全文
  • 前面之前分享了3月底发表的的《水稻微生物组时间序列分析文章,大家对其中图绘制过程比较感兴趣。一上午收到了超30条留言,累计收到41个小伙伴留言求精讲。我们将花时间把此文原始代码整理并精讲,祝有...

    写在前面

    之前分享了3月底发表的的《水稻微生物组时间序列分析》的文章,大家对其中图绘制过程比较感兴趣。一上午收到了超30条留言,累计收到41个小伙伴的留言求精讲。

    我们将花时间把此文的原始代码整理并精讲,祝有需要的小伙伴能有收获。

    本系列按原文4幅组图,共分为4节。本文是第4节,随机森林回归。

    之前我们用了三篇文章,对随机森林的应用、分类、回归进行讲解和实战如下:

    • 一文读懂随机森林在微生态中的应用

    • 随机森林randomForest 分类Classification

    • 随机森林randomForest 回归Regression

    今天以图3中的一个子图,来实践一下冲击图的绘制。

    前情提要

    • 水稻微生物组时间序列分析

    • 1模式图与PCoA

    • 2a-相关分析

    • 2b-散点图拟合

    • 3-冲击图

    先回顾一下图4的内容。

    哪些菌可以作为生育时间的biomarkers?

    80bf9e3a80a9bd1c85e41587f966b621.png

    图4. 水稻生育期相关的微生物标记物(biomarkers)。

    A. 采用随机森林方法在两地点的两品种样本中鉴定了23个纲与生育时间相关。其中按贡献度由大到小排序。其中的子图为交叉验证评估的结果。

    B. 热图展示23个年龄相关的biomarkers相对丰度。

    方法简介:本图A采用R语言的RandomForest包进行分析,结果采用ggplot2的柱状图进行可视化,biomarkers按贡献度由大到小排序,并进行交叉验证模型的准确度和biomarkers数量的选择依据。图B采用pheatmap展示每个时间点biomarkers的相对丰度均值,其中biomarkers按出现最高丰度的时间排序。

    回归分析

    统计分析,主要基于两个表:OTU表和实验设计表,对于想进一步讨论分类级,别需要OTUs的物种注释文件。

    这样基于这3个文件,可以制作出千变万化的统计分析图片,来作为论据支持你的文章(Story)。

    时间序列做回归,主要是想建模来预测其它样品的生育时间。主要分为两部分,训练集建模,测试集验证。

    我们主要有两个品种,种植在两个地点。这里先以A50建模,IR24验证的方案来演示。本实验较复杂 ,具体的方法会有多种组合。

    读取文件

    # 读取实验设计、和物种分类文件
    tc_map =read.table("../data/design.txt
    展开全文
  • 时间序列分析中的AR模型是利用历史数据来预测未来数据的一种模型,也叫做自回归模型auto-regressive。滤波器中也有应用,原理跟FIR滤波一样,如果是用matlab的话使用相同AR系数预测的序列和FIR滤波器函数得到的...
  • 100篇时间序列论文

    2010-06-06 00:10:38
    Matlab在时间序列分析中的应用 磁悬浮列车系统的随机最优控制 非平稳时间序列自适应线性神经网络在线预测 关于不确定非线性时变系统的观测器设计问题 混沌时间序列的双线性自适应预测 。。。。。。。 有一百之多,下...
  • Matlab关于人工神经网络预测中的应用的论文二-人工神经网络模型研究生招生数量预测中的应用.pdf 四、灰色人工神经网络人口总量预测模型及应用 摘要:针对单一指标进行人口总量预测精度不高的问题,基于灰色...
  • 时间序列教程

    2018-02-13 11:42:12
    MATLAB在时间序列建模预测及程序代码+MATLAB在金融时间序列分析及建模中的应用+时间序列分析
  • Matlab关于人工神经网络预测中的应用的论文二-基于RBF人工神经网络模型预测棉花耗水量.pdf 四、灰色人工神经网络人口总量预测模型及应用 摘要:针对单一指标进行人口总量预测精度不高的问题,基于灰色系统...
  • 实际应用中,通常将所观测与处理信号限制一定的时间间隔内,即时域对信号进行“ 截断操作” ,或称作加时间窗(用时间窗函数乘以信号)。由卷积定理可知:时域相乘等于频域卷积,例如矩形窗R5(n)(形式...
  • VC使用MATLAB C/C++函数库 MATLAB广泛应用于线性代数、自动控制理论、数理统计、数字信号处理、时间序列分析、动态系统仿真等领域。因此如果VCMATLAB进行调用将大大减少编程工作量、保证程序准确性,...
  • VC使用MATLAB C/C++函数库

    千次阅读 2005-09-01 15:27:00
    $$$$$$$$$$$$VC使用MATLAB C/C++函数库$$$$$$$$$$$$$$MATLAB广泛应用于线性代数、自动控制理论、数理统计、数字信号处理、时间序列分析、动态系统仿真等领域。因此如果VCMATLAB进行调用将大大减少编程...
  • 第21章 自组织竞争网络模式分类中的应用—患者癌症发病预测 第22章 SOM神经网络的数据分类--柴油机故障诊断 第23章 Elman神经网络的数据预测----电力负荷预测模型研究 第24章 概率神经网络的分类预测--基于PNN的...
  • 为提升轴承故障诊断的准确度及信号的处理能力,针对小波分析轴承局部损伤诊断中的紧支性特点,研究了正交紧支撑函数的构建方法,以小波多分辨分析法和多元时间序列分析为基础,构建出小波神经网络,并对模型中的...
  • EZ熵是一种用于生理时间序列分析的软件应用程序 EZ Entropy是在MATLAB:registered:环境开发。 它以面向对象风格进行编程,并使用图形用户界面进行构建。 EZ Entropy通过其紧凑图形界面易于操作,从而使...
  • 第21章 自组织竞争网络模式分类中的应用—患者癌症发病预测 第22章 SOM神经网络的数据分类--柴油机故障诊断 第23章 Elman神经网络的数据预测----电力负荷预测模型研究 第24章 概率神经网络的分类预测--基于PNN的...
  • matlab神经网络30个案例分析

    热门讨论 2011-06-01 20:06:07
    第16章 自组织竞争网络模式分类中的应用——患者癌症发病预测153 本案例中给出了一个含有60个个体基因表达水平的样本。每个样本中测量了114个基因特征,其中前20个样本是癌症病人的基因表达水平的样本(其中还可能...
  • 摘 要 信号处理许多具体的应用是以线性卷积为基础的当序列点数较少时可以直接 计算线性卷积然而当序列长度很长时直接计算卷积的运算量非常庞大快速卷积是实 现卷积的一种快速算法减少了运算量节约了时间给我们...
  • 第14章 SVM的回归预测分析——上证指数开盘指数预测, 第15章 SVM的信息粒化时序回归预测——上证指数开盘指数变化趋势和变化空间预测, 第16章 自组织竞争网络模式分类中的应用——患者癌症发病预测, 第17章SOM...

空空如也

空空如也

1 2 3 4
收藏数 68
精华内容 27
关键字:

matlab在时间序列分析中的应用

matlab 订阅