本文主要是介绍【时间序列】时间序列的线性、趋势和动量预测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Introduction
对于某些时间序列预测工具来说趋势是相关的,并且是预测公式的一部分。在这项工作中,我们将展示预测时间序列数据,并同时利用数据中的关系和趋势。
此章节的前半部分展示了通过使用线性回归拟合时间序列数据来进行预测。对于后半部分我们证明通过使用移动平均线等时间序列数据的趋势,我们可以使用动量预测来预测趋势的可能未来方向。
Linear Regression (LR) Forecasting
线性回归预测用于预测时间序列 y y y,并假设它与另一个时间序列 x x x具有线性关系。我们先从最简单的一元线性回归模型入手,其公式表述形式为:
y = α + β x y=\alpha+\beta x y=α+βx
其中 β \beta β是线性拟合的斜率 α \alpha α是拟合误差的截距。通常在预测的过程中 y y y被替换为 y ^ \hat y y^表示预测值。如果我们能求出 α \alpha α和 β \beta β的值,根据 x x x的值我们能求出 y y y的预测值: y ^ i = α + β x i \hat y_i=\alpha+\beta x_i y^i=α+βxi。
那么在给定数据集 D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x n , y n ) } D=\{(x_1,y_1),(x_2,y_2),\dots,(x_n,y_n)\} D={(x1,y1),(x2,y2),…,(xn,yn)}的情况下如何确定 α \alpha α和 β \beta β的值呢?根据最小二乘法:
R S S = ∑ i = 1 n ( y i − y ^ i ) 2 = ∑ i = 1 n [ y i − ( α + β x i ) ] 2 (1) RSS=\sum_{i=1} ^n(y_i-\hat y_i)^2=\sum_{i=1}^n[y_i-(\alpha+\beta x_i)]^2 \tag{1} RSS=i=1∑n(yi−y^i)2=i=1∑n[yi−(α+βxi)]2(1)
对公式(1)求偏导得:
∂ R S S ∂ α = − 2 ∑ i = 1 n ( y i − α − β x i ) ∂ R S S ∂ β = − 2 ∑ i = 1 n ( y i − α − β x i ) x i (2) \begin{aligned} \frac{\partial RSS}{\partial \alpha}&=-2\sum_{i=1}^n(y_i-\alpha-\beta x_i) \\ \frac{\partial RSS}{\partial \beta}&=-2\sum_{i=1}^n(y_i-\alpha-\beta x_i)x_i\tag{2} \end{aligned} ∂α∂RSS∂β∂RSS=−2i=1∑n(yi−α−βxi)=−2i=1∑n(yi−α−βxi)xi(2)
令 ∂ R S S ∂ α = 0 \frac{\partial RSS}{\partial \alpha}=0 ∂α∂RSS=0得到:
a = 1 n ∑ i = 1 n ( y i − β x i ) = y ˉ − β x ˉ (3) a=\frac{1}{n}\sum_{i=1}^n(y_i-\beta x_i)=\bar y-\beta \bar x\tag{3} a=n1i=1∑n(yi−βxi)=yˉ−βxˉ(3)
令 ∂ R S S ∂ β = 0 \frac{\partial RSS}{\partial \beta}=0 ∂β∂RSS=0得到:
∑ β x i 2 = ∑ x i y i − ∑ a x i = ∑ x i y i − ∑ ( y ˉ − β x ˉ ) x i ∑ β ( x i 2 − x ˉ ⋅ x i ) = ∑ ( x i y i − y ˉ ⋅ x i ) (4) \begin{aligned} \sum \beta x_i^2&=\sum x_iy_i-\sum ax_i\\ &=\sum x_iy_i-\sum(\bar y-\beta \bar x)x_i\\ \sum \beta(x_i^2-\bar x\cdot x_i)&=\sum(x_iy_i-\bar y\cdot x_i)\tag{4} \end{aligned} ∑βxi2∑β(xi2−xˉ⋅xi)=∑xiyi−∑axi=∑xiyi−∑(yˉ−βxˉ)xi=∑(xiyi−yˉ⋅xi)(4)
根据公式(4)可以求得:
β = ∑ ( x i y i − y ˉ ⋅ x i ) ∑ ( x i 2 − x ˉ ⋅ x i ) (5) \beta=\frac{\sum(x_iy_i-\bar y\cdot x_i)}{\sum(x_i^2-\bar x\cdot x_i)}\tag{5} β=∑(xi2−xˉ⋅xi)∑(xiyi−yˉ⋅xi)(5)
对公式(5)进行进一步处理分子中的第二项可做如下转换:
∑ y ˉ ⋅ x i = y ˉ ∑ i = 1 n x i = n y ˉ x ˉ = x ˉ ∑ i = 1 n y i = ∑ i = 1 n x ˉ y i (6) \sum \bar y\cdot x_i=\bar y\sum_{i=1}^nx_i=n\bar y\bar x=\bar x\sum_{i=1}^ny_i=\sum_{i=1}^n\bar xy_i\tag{6} ∑yˉ⋅xi=yˉi=1∑nxi=nyˉxˉ=xˉi=1∑nyi=i=1∑nxˉyi(6)
其中 x ˉ \bar x xˉ和 y ˉ \bar y yˉ是常数,则 n y ˉ x ˉ = ∑ i = 1 n x ˉ y ˉ (7) n\bar y\bar x=\sum_{i=1}^n\bar x\bar y \tag {7} nyˉxˉ=i=1∑nxˉyˉ(7).
基于公式(6)和公式(7)对公式(5)进行变换得到:
β = ∑ i = 1 n ( x i y i − x i y ˉ − x ˉ y i + x ˉ y ˉ ) ∑ i = 1 n ( x i 2 − x ˉ x i − x ˉ x i + x ˉ 2 ) (8) \beta=\frac{\sum_{i=1}^n (x_iy_i-x_i\bar y-\bar xy_i+\bar x\bar y)}{\sum_{i=1}^n(x_i^2-\bar xx_i-\bar xx_i+\bar x^2)}\tag{8} β=∑i=1n(xi2−xˉxi−xˉxi+xˉ2)∑i=1n(xiyi−xiyˉ−xˉyi+xˉyˉ)(8)
由公式(6)可以看出公式(8)分子的第三项和第四项相等,分母的第三项和第四项就是将分子的第三项和第四项中的 y y y变为了 x x x。所以分母的第三项和第四项也是相等的。
进一步地,将公式(8)合并为:
β = ∑ i = 1 n ( x i ( y i − y ˉ ) − x ˉ ( y i − y ˉ ) ) ∑ i = 1 n ( x i 2 − 2 x ˉ x i + x ˉ 2 ) (9) \beta = \frac{\sum_{i=1}^n(x_i(y_i-\bar y)-\bar x(y_i-\bar y))}{\sum_{i=1}^n(x_i^2-2\bar xx_i+\bar x^2)}\tag{9} β=∑i=1n(xi2−2xˉxi+xˉ2)∑i=1n(xi(yi−yˉ)−xˉ(yi−yˉ))(9)
即:
β = ∑ i = 1 n ( x i − x ˉ ) ( y i − y ˉ ) ∑ i = 1 n ( x i − x ˉ ) 2 (10) \beta=\frac{\sum_{i=1}^n(x_i-\bar x)(y_i-\bar y)}{\sum_{i=1}^n(x_i-\bar x)^2}\tag{10} β=∑i=1n(xi−xˉ)2∑i=1n(xi−xˉ)(yi−yˉ)(10)
以上就是一元线性回归的参数推导过程,多元线性回归的方程推导参见以下参考链接:
1 多元线性回归超详细详解(一步一步手推公式)
2 统计自学5:多元线性回归(概念及OLS估计值推导)
3 一元线性回归的详细推导过程
Gauss Markov Assumptions
使用最小二乘法(OLS)估计线性回归模型的参数方法,其无偏性假定需要满足以下条件:
- 线性模型:此假设要求参数 β \beta β是线性的,模型中自变量与因变量是线性关系。
- 自变量和因变量 ( x , y ) (x,y) (x,y)是随机抽样的,这将导致异常值或残差项的自相关为零。
- 对于多元线性回归方法,多个自变量之间不应该存在共线性。
- 零条件均值(Zero Conditional Mean):给定自变量时,误差项的平均值应该为零。这意味着,自变量不能是误差的一个函数,即自变量和误差项之间不能存在相关性。
- 同方差性(Homoskedasticity):误差项的方差应该在所有自变量的取值范围内都相等。这意味着,误差项的方差应该是恒定的。
- 正态分布:误差项应该是正态分布的。
Ridge Regression
之前我们依据最小二乘法求解出来的多元线性回归的参数是 β = ( X T X ) − 1 X T y \beta=(X^TX)^{-1}X^Ty β=(XTX)−1XTy,而这样的求解,在有的时候会出现问题,当自变量间存在多重线性关系或者矩阵不可求逆时,这种求法就会出错或者是参数 β \beta β会很大。
于是,就在线性回归模型的目标函数上引入 L 2 L2 L2正则项(也叫惩罚项),最终目标函数为: J ( β ) = ∑ ( y − X β ) 2 + ∑ λ β 2 J(\beta)=\sum(y-X\beta)^2+\sum\lambda\beta^2 J(β)=∑(y−Xβ)2+∑λβ2, β \beta β为回归系数, λ \lambda λ为正则项平方的系数为非负数。
对目标函数求导得到 β = ( X T X + λ ) − 1 X T y \beta=(X^TX+\lambda)^{-1}X^Ty β=(XTX+λ)−1XTy,当 λ = 0 \lambda=0 λ=0,该目标函数和普通线性回归模型的参数一样;当 λ → + ∞ \lambda\rightarrow+\infty λ→+∞,参数就会趋近于零。
Lasso Regression
虽然岭回归通过添加 L 2 L2 L2正则项来所见模型系数的大小秉进一步较少多重共线性的影响,提高模型的稳定性和鲁棒性。但不管怎么缩减,始终会保留建模时的所有变量。一但变量较多的时候,模型就会变得很复杂造成过拟合。
Lasso回归模型的目标函数为: J ( β ) = ∑ ( y − X β ) 2 + ∑ λ ∣ β ∣ J(\beta)=\sum(y-X\beta)^2+\sum\lambda|\beta| J(β)=∑(y−Xβ)2+∑λ∣β∣
由于目标函数的惩罚项时有关回归系数 β \beta β的绝对值之和,因此惩罚项在零点处是不可导的,所以也不能用最小二乘法,梯度下降法,用的是坐标下降法。这个坐标下降法,就是控制其他p-1个参数不变的情况下,对 β j \beta_j βj求偏导,逐个求导,最后让导函数等于0,求出最小的 β \beta β。
ElasticNet Regression
ElasticNet是Lasso和Ridge回归技术的混合体。它使用L1来训练并且L2优先作为正则化矩阵。当有多个相关的特征时,ElasticNet是很有用的。Lasso 会随机挑选他们其中的一个,而ElasticNet则会选择两个。
β ^ = arg m i n β ( ∥ y − X β ∥ 2 + λ 2 ∥ β ∥ 2 + λ 1 ∥ β ∥ ) \hat \beta =\arg \mathop{min}\limits_{\beta}(\lVert y-X\beta\rVert^2+\lambda_2\lVert \beta \rVert^2+\lambda_1\lVert\beta\rVert ) β^=argβmin(∥y−Xβ∥2+λ2∥β∥2+λ1∥β∥)
Example 1:Univariate LR in Stock Price of Netflix
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from pandas.plotting import autocorrelation_plot
from statsmodels.graphics import tsaplots
from sklearn.metrics import r2_score
from sklearn import metrics%matplotlib inline
price = pd.read_csv('E:/kaggle竞赛学习/Netflix/NFLX.csv',usecols=['Date','Close'],parse_dates=['Date'])
price.set_index("Date",inplace=True)plt.rcParams["figure.figsize"] = (15,2)
ax=price.plot()
plt.ylabel("price")
ax.set_title('Daily Close Price')
# plt.show()
Testing for Stationarity
进行时间序列预测时要做的第一步是检查数据的平稳性,尤其是在存在突出趋势时。在本笔记本中,我们将使用使用最广泛的统计检验,叫做增强的****Augmented Dickey-Fuller单元根检验。请注意,单位根检验确定趋势定义时间序列的强度。该测试使用自回归模型,并跨不同的滞后值优化信息标准。回想一下:
原假设(H0):
- 时间序列具有单位根,并且是非平稳的。它是具有时间依赖性。
备择假设(H1): - 时间序列没有单位根并且是平稳的。它不具有时间依赖性。
最后,可以使用 ADF 统计量解释检验结果,即 ADF 统计量应小于将数据视为平稳的临界值。
在某些参考文献中,它们使用检验中的 p 值。p 值低于阈值(例如 5% 或 1%)表示时间序列平稳,否则数据是非平稳的。
- p − v a l u e < = 0.05 p-value<=0.05 p−value<=0.05:时间序列是平稳的。
- p − v a l u e > 0.05 p-value>0.05 p−value>0.05:时间序列是非平稳的。
在其他参考中,他们只是将 ADF 统计量与临界值进行比较,这样,如果它大于临界值,则称时间序列为非平稳的。
from statsmodels.tsa.stattools import adfuller
series = pd.read_csv("E:/kaggle竞赛学习/Netflix/NFLX.csv",usecols=['Close'])
X = series.values
result = adfuller(X)
print('ADF Statistic: %f' % result[0])
print('p-value: %f' % result[1])
print('Critical Values: ')
for key,value in result[4].items():print('\t%s: %.3f' % (key,value))
ADF Statistic: -1.812591
p-value: 0.374229
Critical Values: 1%: -3.4375%: -2.86410%: -2.568
Testing for Autocorrelation
自相关系数检验的是时序数据和他本身的滞后的相关性强度。第一个系数测量的是 y t y_t yt到 y t − 1 y_{t-1} yt−1,而第二个系数测量的是 y t y_t yt到 y t − 2 y_{t-2} yt−2之间的关系,依此类推。
# testing autocorrelation using pandas tools.
plt.rcParams["figure.figsize"] = (6,4)
tsaplots.plot_acf(price)
plt.show()
下面显示了使用熊猫工具可视化滞后自相关化的另一种方法。
plt.rcParams["figure.figsize"] = (6,4)
autocorrelation_plot(price)
如果我们将滞后数据作为原始数据的移动版本并查看重叠(在本例中为它们的自相关),则可以更好地想象滞后自相关的概念。如果原始趋势在滞后数据的移动时同时上升或下降,则相关性为正,否则为负。
回到自相关图与滞后的关系,该图显示,随着滞后的增加趋势减小。数据与前100个之后的强关系表明,这并非高斯-马尔可夫假设中所述的纯粹随机。在大约等于 120 天的滞后时,自相关为零并开始为负。这是因为滞后数据的趋势与数据的正趋势相反变为负值。
在这儿,在大约 y t − 320 y_{t-320} yt−320之后,自相关为零。这主要是因为滞后数据和原始数据的重叠最小,因为重叠的数据越来越少。
现在我们假设NFLX股票价格时序数据满足高斯马尔科夫假设条件4-6,并对NFLX的价格应用线性回归,以预测下个月的价格。
# 让我们创建另一个变量来操作而不是使用原始数据
window = 30
price2 = price[['Close']]
plt.rcParams["figure.figsize"] = (15,2)
price2.plot()
# With the goal of predicting the future prices daily for a month (30days), we create a variable to contain the size
# it will be placed at the end of a variable 'Prediction' in the dataframe that is shifted by 30 days
plt.rcParams["figure.figsize"] = (6,4)
price2['Prediction'] = price2[['Close']].shift(-window)
print(len(price2['Prediction']))
price2.plot(subplots=True)
plt.show()
# 现在我们将价格的原始数据用作 X,预测数据为 y,并使用 80% 的数据作为训练集
# 同时将 20% 的数据作为测试集并使用 sklearn 函数来训练和测试数据。
# 对于这两个变量,最后 30 个值被删除。
X = np.array(price2[['Close']])
X = X[:-window]
print(len(X))y = np.array(price2['Prediction'])
y = y[:-window]
x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2020)
lr = LinearRegression()
fit = lr.fit(x_train, y_train)
## coefficients of linear fit are:
b = fit.intercept_
m = fit.coef_print("the equation of the linear fit is: ")
print('y= ', m, 'x + ', b)# checking R^2
R_sqd = lr.score(x_test, y_test)
print("lr confidence: ", R_sqd)
the equation of the linear fit is:
y= [0.89744979] x + 49.94427826384913
lr confidence: 0.755657845996569
# To show the relationship of the training set and the predicted prices.. we plot the following.
plt.rcParams["figure.figsize"] = (6,4)
plt.plot(x_train, y_train, 'o')
plt.xlabel('x_train')
plt.ylabel('y_train')
plt.plot(x_train.flatten(), lr.predict(x_train), label='regression line')
plt.legend()
# 这里试图证明训练集和预测值之间的差异几乎是高斯的
plt.rcParams["figure.figsize"] = (6,4)
plt.hist(lr.predict(x_train)-y_train, bins=np.arange(-125, 126, 25))
plt.show()
# Setting the last 30 rows of the original Close price as test data
# to predict the next values.
x_forecast = np.array(price2.drop(['Prediction'],1))[-window:]
print(len(x_forecast))# # we predict the closing prices...
lr_prediction = lr.predict(x_forecast)
print(len(lr_prediction))
plt.rcParams["figure.figsize"] = (6,4)
plt.plot(x_test, y_test, 'o')
plt.xlabel('x_test')
plt.ylabel('y_test')
plt.plot(x_test.flatten(), lr.predict(x_test))
plt.figure(figsize=[15, 2])
price2.loc[~price2.Prediction.isnull()].Close.plot(label='y_train')
price2.loc[price2.Prediction.isnull()].Close.plot(label='y_test')
pd.Series(lr.predict(price2.loc[price2.Prediction.isnull()][['Close']].values), index=price2.loc[price2.Prediction.isnull()].index, name='Pred_LR').plot(label='y_pred from regression')
plt.legend(loc=2)
这篇关于【时间序列】时间序列的线性、趋势和动量预测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!