时间序列模型
时间序列是研究数据随时间变化而变化的一种算法。是一种预测性分析算法。它的基本出发点就是事物发展都有连续性,按照它本身固有的规律进行。
时间序列的常用算法包括:

有这几个那如何选择模型呢
首先我们要知道时间序列就是按照时间顺序排列,随时间变化的随机过程,也就是说有对应的均值、方差、协方差等。
时间序列可以解决在只有时间(序列项)而没有其他可控变量下对未来数据的预测问题,常用于经济预测、股市预测、天气预测等。
如果随机过程随着时间变化,则此过程是非平稳的,相反,如果随机过程的特征不随时间变化,则此过程为平稳的
时间序列是按时间顺序排列的、随时间变化且相互关联的数据序列。分析时间序列的方法构成数据分析的一个重要领域,即时间序列分析。
时间序列根据研究的依据不同,可有不同的分类。
如果一个时间序列的概率分布与时间t无关,则称该序列为严格的(狭义)平稳时间序列。
如果序列的一、二阶矩存在,而且对任意时刻t满足:
(1)均值为常数
(2)协方差为时间间隔 T 的函数。则称为宽平稳(广义)时间序列。以后研究的时间序列主要是宽平稳时间序列。
一个时间序列可以分解为以下四部分:
(1)长期趋势变动。它指时间序列朝一定方向持续上升或下降,或停留在某一水平上,它反映了客观事物的主要变化趋势。
(2)季节变动。
(3)循环变动。通常指周期为一年以上,由非季节因素引起的波形相似的波动。
(4)不规则变动。通常为突然变动和随机变动。
通常用 T t T_t Tt 表示长期趋势项, S t S_t St 表示季节变动趋势项, C t C_t Ct 表示循环变动趋势项, R t R_t Rt 表示随机干扰项。常见的确定性时间序列模型有以下类型:
(1)加法模型
y t = T t + S t + C t + R t y_t = T_t + S_t + C_t + R_t yt=Tt+St+Ct+Rt
(2)乘法模型
y t = T t ∗ S t ∗ C t ∗ R t y_t = T_t * S_t * C_t * R_t yt=Tt∗St∗Ct∗Rt
(3)混合模型
y t = T t ∗ S t + R t y_t = T_t * S_t + R_t yt=Tt∗St+Rt
y t = S t + T t ∗ C t ∗ R t y_t = S_t + T_t * C_t * R_t yt=St+Tt∗Ct∗Rt
其中 y t y_t yt 是观测目标的观测记录, E ( R t ) = 0 E(R_t) = 0 E(Rt)=0, E ( R t 2 ) = σ 2 E(R^2_{t}) = σ^2 E(Rt2)=σ2。
线性回归算法中,每个经验点的权重是一致的,即很早以前的经验数据也可能对预测数据有较大的影响。很多实际场景中,未来一段时间的趋势可能和在最近一段时间的趋势关系更加紧密。比如小明去年数学考试成绩一直不及格,今年连续多次考试90多分,预测小明下一次数学考试的成绩,情理上90多分的可能性更高。采用传统的线性回归算法,预测结果可能是70多分。
指数平滑法原则认为,时间越靠过去的经验数据对趋势的影响越小。我们假定时间t的观测值为y(t),时间t的预测值为S(t),则时间t+1的预测值S(t+1)为
S
t
+
1
=
a
y
t
+
(
1
−
a
)
S
t
S_{t+1}=ay_t+(1-a)S_t
St+1=ayt+(1−a)St
a的取值范围在(0,1),a越大,最近时间点的观测值对预测值的影响越大
另外还有二次指数平滑、三次指数平滑,就不介绍,懒得写
首先来说ACF与PACF是用来确定模型AR(p,)、MA(q,)、ARMA(p,q)、ARIMA(p,l,q),中p、q。方法如下:

如何用PACF图和ACF图来确定p、q值
通常我们确定了模型后,看模型的数据的阶数和2倍标准差范围。
这里先解释一下 阶数就是历史观测项,比如当前时间t数据为 x t x_t xt阶数为7,表示 x t − 7 x_{t-7} xt−7。
🥳开始可以对照上面的表进行分析
acf、pacf图如下图

可以看到acf图中q到7阶段时,后续的值逐渐倾向于0的,是符合拖尾的,在pacf图中p到1阶段时,后续的值逐渐倾向于0的。所以模型为AR(1),
假设选择模型为ARMA
其acf、pacf图如下图

ACF和PACF都呈现衰减趋于零,在1阶位置就开始基本落在2倍标准差范围,所以是ARMA(1,1)模型
AR是线性时间序列分析模型,通过自身当前数据与历史之前的数据之间的相关关系(自相关)来建立回归方程,
在时间序列中,当前观测值可以通过历史的观测值,结合相关性获得,公式如下:
Y t = c + Φ 1 Y t − 1 + Φ 2 Y t − 2 + . . . . . . + Φ p Y t − p + ξ t Y_t=c+\Phi_{1}Y_{t-1}+\Phi_{2}Y_{t-2}+......+\Phi_{p}Y_{t-p}+\xi_{t} Yt=c+Φ1Yt−1+Φ2Yt−2+......+ΦpYt−p+ξt
公式中 ξ t \xi_{t} ξt为噪声, Y t − 1 Y_{t-1} Yt−1, Y t − 2 Y_{t-2} Yt−2是历史观测项, p p p是历史观测值
过将一段时间序列中白噪声序列进行加权和,可以得到移动平均方程。
在时间序列中,当前观测值是由历史的误差的线性组合成的,这些误差互相独立分布且服从正态分布。公式如下:
Y
t
=
c
+
ξ
t
+
θ
1
ξ
t
−
1
+
θ
2
ξ
t
−
2
+
.
.
.
.
.
.
+
θ
q
ξ
t
−
q
Y_t=c+\xi_{t}+\theta_{1}\xi_{t-1}+\theta_{2}\xi_{t-2}+......+\theta_{q}\xi_{t-q}
Yt=c+ξt+θ1ξt−1+θ2ξt−2+......+θqξt−q
自回归移动平均模型是与自回归和移动平均模型两部分组成。
ARMA(p,q)模型全称为自回归移动平均模型,公式如下:
Y
t
=
c
+
Φ
1
Y
t
−
1
+
Φ
2
Y
t
−
2
+
.
.
.
.
.
.
+
Φ
p
Y
t
−
p
+
ξ
t
+
θ
1
ξ
t
−
1
+
θ
2
ξ
t
−
2
+
.
.
.
.
.
.
+
θ
q
ξ
t
−
q
Y_t=c+\Phi_{1}Y_{t-1}+\Phi_{2}Y_{t-2}+......+\Phi_{p}Y_{t-p}+\xi_{t}+\theta_{1}\xi_{t-1}+\theta_{2}\xi_{t-2}+......+\theta_{q}\xi_{t-q}
Yt=c+Φ1Yt−1+Φ2Yt−2+......+ΦpYt−p+ξt+θ1ξt−1+θ2ξt−2+......+θqξt−q
ARIMA(p,d,q)模型全称为差分自回归移动平均模型
(Autoregressive Integrated Moving Average Model,简记ARIMA).
自回归(AR),差分(I),移动平均(MA)
趋势参数:
ARIMA与ARMA模型公式都是一样的,区别在于,ARIMA公式中的Y变成差分算子(即Y是经过原始Y值差分计算了一次的新值),保证了数据 的稳定性。
差分(difference)又名差分函数或差分运算,差分的结果反映了离散量之间的一种变化,是研究离散数学的一种工具。它将原函数f(x) 映射到f(x+a)-f(x+b) 。差分运算,相应于微分运算,是微积分中重要的一个概念。总而言之,差分对应离散,微分对应连续。差分又分为前向差分、向后差分及中心差分三种。
通常情况下我们用到的是前向差分公式如下:
x
k
=
x
0
+
k
h
,
(
k
=
0
,
1
,
.
.
.
,
n
)
x_k=x_0+kh,(k=0,1,...,n)
xk=x0+kh,(k=0,1,...,n)
△
f
(
x
k
)
=
f
(
x
k
+
1
)
−
f
(
x
k
)
\triangle f(x_k)=f(x_{k+1})-f(x_k)
△f(xk)=f(xk+1)−f(xk)
差分的阶
称为阶的差分,即前向阶差分 ,如果数学运用根据数学归纳法,有其中,为二项式系数。特别的,有前向差分有时候也称作数列的二项式变换
😍以物理学中来理解,一个汽车位移与时间的问题。
一阶导数表示速度,二阶差分表示速度的导数加速度。同样的,在时间序列模型中,一阶差分表示相邻时间的数据的变化情况,二阶差分就表示这种变化的变化强弱。
🥰这里的数据集AirPassengers.csv,百度都搜到得
import numpy as np
import pandas as pd
from datetime import datetime
import matplotlib.pylab as plt
data=pd.read_csv('AirPassengers.csv',encoding='utf-8')
data.head(5)

def draw_ts(timeSeries):
f = plt.figure(facecolor='white')
timeSeries.plot(color='blue')
plt.legend()
plt.show()
draw_ts(data)

🐻从图中看,序列是非平稳时间序列。
一阶差分
data['diff_1']=data.diff()
draw_ts(data['diff_1'])

二阶差分,我们通常最多就做到二阶差分就行
data['diff_2']=data['diff_1'].diff()
draw_ts(data['diff_2'])

🐻大致可以看图,差分为平稳时间序列
单位根检验背后的直觉是它确定趋势定义时间序列的强度。
有许多单位根测试,Augmented Dickey-Fuller可能是更广泛使用的之一。它使用自回归模型并优化跨多个不同滞后值的信息标准。
测试的零假设是时间序列可以用单位根表示,它不是静止的(具有一些时间依赖的结构)。替代假设(拒绝零假设)是时间序列是静止的。
我们使用测试中的p值来解释这个结果。在下面的代码反馈结果也会出现p。低于阈值的p值(例如5%或1%)表明我们拒绝零假设(静止),否则高于阈值的p值表明我们未能拒绝零假设(非静止)。
我们先用原数据进行检验看看。
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
testStationarity(data)

上图我们只需关注p值,其余的参数解释如下:
下面我们用1阶差分来检验
diff_1=data.diff()
diff_1 = diff_1.dropna()
testStationarity(diff_1)

🐯从结果来看还无法拒绝原假设(原假设为是平稳时间序列),这时候我们通常对原数据先进行对数处理,再进行一次差分。
del data['diff_1']
del data['diff_2']
ts_log = np.log(data)
draw_ts(ts_log)

logdiff_1=ts_log.diff(12)
logdiff_1 = logdiff_1.dropna()
logdiff_2=logdiff_1.diff(1)
logdiff_2=logdiff_2.dropna()
testStationarity(logdiff_2)

🙊p值小于0.05,拒绝原假设(原假设为是平稳时间序列),故数据为平稳时间序列
检验当前时刻t到滞后时刻k(Lags Used),
y
t
y_t
yt与y_{t-k}的相关性。
由上小节得到的滞后值为12.
from statsmodels.stats.diagnostic import acorr_ljungbox
acorr=acorr_ljungbox(logdiff_2,lags=12)
acorr

🏀这里acorr[0]为这12个时刻的统计值,acorr[1],为t时刻的统计值与滞后的12时刻的相关性。
从结果可以看出,p值较小,拒绝原假设(没有相关性),故数据有序列相关性
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
pacf = plot_pacf(logdiff_2, lags=20)
plt.title('PACF')
pacf.show()
acf = plot_acf(logdiff_2, lags=20)
plt.title('ACF')
acf.show()


🏉从图可得 p=1,q=1
import statsmodels.tsa.stattools as st
model = st.arma_order_select_ic(logdiff_2, max_ar=5, max_ma=5, ic=['aic', 'bic', 'hqic'])
model.bic_min_order
返回(2,3)
使用差分后的数据
from statsmodels.tsa.arima_model import ARMA
model_arma = ARMA(logdiff_2, order = model.bic_min_order)
result_arma = model_arma.fit(disp = -1, method = 'css')
使用原始数据
from statsmodels.tsa.arima_model import ARIMA
model = ARIMA(data, order=(1,1,1))
result = model.fit()
残差检验,对已经训练好的模型,对模型的残差,进行可视化,
对残差进行可视化,判断残差是否符合正态分布
resid = result.resid
from statsmodels.graphics.api import qqplot
qqplot(resid, line='q', fit=True)
plt.show()

pred = result.predict(start=1, end =len(data) + 10 ) # 从训练集第0个开始预测(start=1表示从第0个开始),预测完整个训练集后,还需要向后预测10个
print(len(pred))
print(pred[-10:]) # 有负数,表明是一阶差分之后的
# 此时可以画出预测的曲线和data_diff进行比较

result_fina = np.array(pred[0:-10]) + (np.array(data.shift(1)))
result_fina
# 如果还取了对数,进行如下操作
# result_log_rev = np.exp(result_fina)
# result_log_rev.dropna(inplace=True)
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:
对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs
我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查
我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案
ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序