美文网首页
时序预测的七种方法(python)

时序预测的七种方法(python)

作者: 途中的蜗牛 | 来源:发表于2020-04-17 09:10 被阅读0次

    原文:
    1、7 methods to perform Time Series forecasting (with Python codes)https://www.analyticsvidhya.com/blog/2018/02/time-series-forecasting-methods/
    2、(Python)时序预测的七种方法https://blog.csdn.net/yunqiinsight/article/details/79741483

    很多人都会投资加密货币,如比特币,但是安全吗?如何确保能够产生一定的利润,我们可以使用“时间序列建模”根据以前的价格得出一个近似值,从而为投资提供一定的参考。


    比特币价格分布

    除了加密货币,还有许多重要的领域使用时间序列预测,如销售,呼叫中心的呼叫量,太阳活动,海潮,股票价格等等。
    假设一家酒店的经理希望预测明年他预计会有多少客人相应地调整酒店的库存,并对酒店的收入做出合理的猜测。根据前几年/月/日的数据,他可以使用时间序列预测,得到访客的近似值。预测客人将有助于酒店资源管理和做好相应的计划。

    在本文中,我们将学习多种预测技术,并通过在数据集上实现对它们进行比较。我们将通过不同的技巧,看看如何使用这些方法来提高结果。

    目录

    1、理解问题描述和数据集
    2、安装库
    3、方法 1 –以简单的方式开始
    4、方法2 – 简单平均数
    5、方法3 – 移动平均数
    6、方法 4 –指数平滑法
    7、方法5 – Holt线性趋势法
    8、方法6 – Holt冬季季节法
    9、方法7 –综合自回归移动平均法(ARIMA)

    1、理解问题描述和数据集

    在本文中,我们将学习多种预测技术,并通过使用股票数据实现对它们进行比较。

    import pandas as pd 
    import numpy as np 
    import matplotlib.pyplot as plt 
    import tushare as ts
    
    #Importing data
    df = ts.get_hist_data('000001')
    df.sort_index(inplace=True)
    df = df.reset_index(level=0)
    df.index = pd.to_datetime(df['date']) 
    df = df[['close']]
    
    df.head()
    
    00001股票价格

    构建训练集和测试集

    t=.8   # 训练集和测试集按照 0.8 进行切分
    t = int(t*len(df))
    
    train = df[:t] 
    test = df[t:]
    

    把数据(用于训练的和测试的)可视化,以了解在一段时间内是如何变化的。

    00001股票价格

    2、安装库

    安装所必须的statsmodels、arima等模块,一般是使用pip install即可。

    3、方法 1 –以Naive开始(Start with a Naive Approach)

    考虑下面给出的图表。假设y轴表示硬币的价格,x轴表示时间(天)。

    硬币价格
    从图中我们可以看出,从一开始,硬币的价格是稳定的。大多时候我们都有一个在整个时间段都比较稳定的数据集。如果想预测第二天的价格,可以简单地用前一天的价格数据,估计第二天的价格。这种假定下一个期望点等于最后一个观测点的预测技术称为 朴素方法(Naive Method)
    Naive Method
    现在我们采用Naive 方法来预测股票中的测试数据的价格。
    dd= np.asarray(train.close)
    y_hat = test.copy()
    y_hat['naive'] = dd[len(dd)-1]
    plt.figure(figsize=(12,8))
    plt.plot(train.index, train['close'], label='Train')
    plt.plot(test.index,test['close'], label='Test')
    plt.plot(y_hat.index,y_hat['naive'], label='Naive Forecast')
    plt.legend(loc='best')
    plt.title("Naive Forecast")
    plt.show()
    
    使用Naive Method的股票价格预测

    现在我们将计算均方根误差(RMSE)以检查测试数据集上模型的精度。

    from sklearn.metrics import mean_squared_error
    from math import sqrt
    rms = sqrt(mean_squared_error(test.close, y_hat.naive))
    print(rms)
    # 1.9912027833925308
    

    可以从RMSE值和上面的图推断,Naive方法不适合变化频繁的数据集,它最适合稳定的数据集。

    方法2 简单均值法(Simple Average)

    考虑下面给出的图表。假设y轴表示硬币的价格,x轴表示时间(天)。


    某硬币价格

    可以从图中推断,硬币的价格是以微小的幅度随机上升和下降的,平均值不变。很多时候,我们得到了一个数据集,虽然它在整个时间段内有一个较小的变化,但是每个时间段的平均值保持不变。在这种情况下,我们可以预测第二天的价格与之前每天的平均值相近。
    这种预测期望值等于所有观测点平均值的预测技术称为简单均值法。


    Simple Average
    我们取之前已知的所有值,计算平均值并将其作为下一个值。当然不是很精确,但有点接近。作为一种预测方法,实际上有些情况下这种技术的效果最好(但是显然并不适用于股票预测)。
    y_hat_avg = test.copy()
    y_hat_avg['avg_forecast'] = train['close'].mean()
    plt.figure(figsize=(12,8))
    plt.plot(train['close'], label='Train')
    plt.plot(test['close'], label='Test')
    plt.plot(y_hat_avg['avg_forecast'], label='Average Forecast')
    plt.legend(loc='best')
    plt.show()
    
    使用Simple Average进行股票预测

    现在将计算均方根误差检查模型的准确性

    rms = sqrt(mean_squared_error(test.close, y_hat_avg.avg_forecast))
    print(rms)
    #3.633413210936537
    

    方法3 移动均值法(Moving Average)

    考虑下面给出的图表。假设y轴表示硬币的价格,x轴表示时间(天)。


    某硬币价格

    从图中可以推断,硬币的价格在一段时间以前大幅度地提高了,但现在是稳定的。很多时候,我们得到了一个数据集,其中一段时间以前对象的价格/销售量急剧增加/急剧下降。使用初期的价格会对下一个时间段的预测产生很大影响。所以相对于简单均值法的改进,只计算最后几个时间段的平均价格。显然,只有最近的值才是重要的。这种利用时间窗计算平均值的预测技术称为移动均值法。
    利用一个简单的移动平均模型,对于所有i>p,我们根据前一个值的一个固定的有限个“p”的平均值来预测时间序列中的下一个值。


    Moving Average
    y_hat_avg = test.copy()
    y_hat_avg['moving_avg_forecast'] = train['close'].rolling(60).mean().iloc[-1]
    plt.figure(figsize=(16,8))
    plt.plot(train['close'], label='Train')
    plt.plot(test['close'], label='Test')
    plt.plot(y_hat_avg['moving_avg_forecast'], label='Moving Average Forecast')
    plt.legend(loc='best')
    plt.show()
    
    使用Moving Average进行股票预测

    我们只选择了过去2个月的数据。现在将计算均方根误差来检查模型的准确性。

    rms = sqrt(mean_squared_error(test.close, y_hat_avg.moving_avg_forecast))
    print(rms)
    # 1.4956947306289905
    

    移动均值法的改进方法——加权移动均值法(Weighted moving average)。在上述移动均值法中,我们同样权衡过去的N个观测值。但我们可能遇到的情况是,过去的每一次观察都以不同的方式影响预测。这种以不同的方式权衡过去观测值的技术称为加权移动均值技术。

    加权移动均值是一个移动平均值,在滑动窗口的值中赋予不同的权重,通常是为了使最近的点更重要。


    Weighted moving average

    选择窗口的大小,需要一个权重列表(应该加起来为1)。例如,如果选择[ 0.40,0.25,0.20,0.15 ]作为权重,我们将分别给最后4个点40%,25%,20%和15%的权重。

    方法4 简单指数平滑法(Simple Exponential Smoothing)

    在理解了上述方法之后,可以注意到,简单均值法和加权移动均值法是完全相反的。我们需要在这两个方法之间采取某种方法,这种方法考虑到所有数据,同时对数据点进行不同的加权。例如,最近的观测点有更大的权重,而更远的数据权重更低,这样好像会更合理,这种技术称为简单指数平滑法。预测是使用加权平均值计算的,在加权平均值中,当观测值来自过去更远的地方时,权重呈指数递减,最小的权重与最老的观测值相关联。

    Simple Exponential Smoothing
    这里0≤ α ≤1是平滑参数(smoothing parameter)

    预测时间T + 1是一个序列中的所有观测值的加权平均值Y1,…,YT。权重下降的速率由参数α决定。

    如果观察足够长的时间,你会看到,期望ŷx是α⋅YT和(1−α)⋅ŶT-1的和。

    也可以写成 :

    Simple Exponential Smoothing
    所以基本上我们已经有了一个1−α和α的加权移动平均值。
    可以看到,1−α乘以之前预期的表达递归的值ŷx−1。这就是为什么这种方法被称为Exponential。在时间t + 1的预测等于最近观察值yt 和最近预测值 ŷ t|t−1之间的加权平均值。
    from statsmodels.tsa.api import ExponentialSmoothing, SimpleExpSmoothing, Holt
    y_hat_avg = test.copy()
    fit2 = SimpleExpSmoothing(np.asarray(train['close'])).fit(smoothing_level=0.6,optimized=False)
    y_hat_avg['SES'] = fit2.forecast(len(test))
    plt.figure(figsize=(16,8))
    plt.plot(train['close'], label='Train')
    plt.plot(test['close'], label='Test')
    plt.plot(y_hat_avg['SES'], label='SES')
    plt.legend(loc='best')
    plt.show()
    
    简单指数平滑法的股票预测

    现在将计算均方根误差检查模型的准确性。

    rms = sqrt(mean_squared_error(test.close, y_hat_avg.SES))
    print(rms)
    #2.051521877556213
    

    方法 5 霍尔特线性趋势法(Holt’s Linear Trend method)

    我们现在已经学会了几种预测方法,但可以看到,这些模型在变化较大数据上不是太好。

    1.png

    趋势是在一段时间内观察到的价格的一般模式。如Naive方法会假定最后两点之间的趋势将保持不变,或者可以在所有点之间的平均斜率得到一个平均趋势,使用移动趋势均值或指数平滑法。

    但我们需要一种方法,能准确无误地绘制趋势图。考虑数据集趋势的这种方法称为霍尔特线性趋势法。每个时间序列的数据集可以被分解为不同趋势的组成部分,季节性和剩余。任何跟随趋势的数据集都可以使用Holt线性趋势法进行预测。

    import statsmodels.api as sm
    sm.tsa.seasonal_decompose(train.close, freq=7).plot()  # 以7为周期的季节性特性,可能不太准确
    result = sm.tsa.stattools.adfuller(train.close)
    plt.show()
    
    Holt’s Linear Trend method

    从图表可以看出,该数据集呈增长趋势。因此,可以用Holt的线性趋势来预测未来的价格。

    霍尔特扩展简单指数平滑方法,允许有趋势的数据预测。它只适用于两个等级(多个序列的平均值)和趋势的指数平滑方法。用数学符号表示,现在需要三个等式:一个用于等级,一个用于趋势,一个结合等级与得到预测值Ŷ的趋势


    Holt’s Linear Trend method

    我们在上述算法中预测的值称为等级。在上面的三个等式中,可以注意到我们增加了等级和趋势来生成预测等式。

    作为简单指数平滑法,这里的等级等式表明它是一个观察数的加权平均值和样本内前步预测。趋势等式表明,这是一个基于ℓ(t)−ℓ(t−1)和和b(t−1)的时间t的预测趋势的加权平均值。

    我们将添加这些等式来生成预测等式。也可以通过乘以趋势和等级而不是增加,来生成乘法预测等式。当趋势呈线性上升或下降时,则采用加法等式,而当趋势呈指数下降时,则采用乘法等式。实践表明乘法是一种更稳定的预测,但加性方法更容易理解。


    1.png
    y_hat_avg = test.copy()
    
    fit1 = Holt(np.asarray(train['close'])).fit(smoothing_level = 0.3,smoothing_slope = 0.1)
    y_hat_avg['Holt_linear'] = fit1.forecast(len(test))
    
    plt.figure(figsize=(16,8))
    plt.plot(train['close'], label='Train')
    plt.plot(test['close'], label='Test')
    plt.plot(y_hat_avg['Holt_linear'], label='Holt_linear')
    plt.legend(loc='best')
    plt.show()
    
    Holt’s Linear Trend method

    现在将计算均方根误差检查模型的准确性,但是实际的结果并不好,误差更大呀。

    rms = sqrt(mean_squared_error(test.close, y_hat_avg.Holt_linear))
    print(rms)
    #10.831374815508934
    

    方法6 Holt-Winters方法(Holt-Winters Method)

    考虑一个位于山上的旅馆。在夏季期间有很高的访问量,而今年余下时间的游客相对较少。因此,业主的利润在夏季比其他季节都要好得多。而且每年都一样,是季节性的。数据集在一段固定的时间间隔内显示出相似性。

    1.jpg

    由于季节性因素,使用霍尔特冬季方法将是其它模型中最好的选择。霍尔特-温特斯季节性方法包括预测等式和三个平滑等式-一个似乎等级ℓt,一个是趋势bt,一个是季节组成部分 st,平滑参数α,β和γ。


    Holt-Winters Method

    其中S是季节性周期的长度,0≤α≤1, 0≤β≤1和0≤γ≤1。

    y_hat_avg = test.copy()
    fit1 = ExponentialSmoothing(np.asarray(train['close']) ,seasonal_periods=7 ,trend='add', seasonal='add',).fit()
    y_hat_avg['Holt_Winter'] = fit1.forecast(len(test))
    plt.figure(figsize=(16,8))
    plt.plot( train['close'], label='Train')
    plt.plot(test['close'], label='Test')
    plt.plot(y_hat_avg['Holt_Winter'], label='Holt_Winter')
    plt.legend(loc='best')
    plt.show()
    
    Holt-Winters Method

    现在将计算均方根误差检查模型的准确性

    rms = sqrt(mean_squared_error(test.close, y_hat_avg.Holt_Winter))
    print(rms)
    # 6.780348146636006
    

    从图中可以看出,Holt-Winters Method更适合预测那种周期非常明确的活动,对于股票预测来说,准确率很难保证。

    方法7 ARIMA

    另一个在数据科学家中非常流行的时间序列模型是ARIMA。它代表自回归积分移动平均(Autoregressive Integrated Moving average)。指数平滑模型是基于对趋势和季节性数据的描述,ARIMA模型的目的是描述数据之间的相关性。ARIMA的改进考虑到数据集的季节性,就像Holt-Winters方法一样。

    y_hat_avg = test.copy()
    fit1 = sm.tsa.statespace.SARIMAX(train.close, order=(2, 1, 4),seasonal_order=(0,1,1,7)).fit()
    y_hat_avg['SARIMA'] = fit1.predict(start="2017-10-18", end="2018-10-18", dynamic=True)
    plt.figure(figsize=(16,8))
    plt.plot( train['close'], label='Train')
    plt.plot(test['close'], label='Test')
    plt.plot(y_hat_avg['SARIMA'], label='SARIMA')
    plt.legend(loc='best')
    plt.show()
    
    arima

    总体来说,这些算法都不适合用于股票预测。

    相关文章

      网友评论

          本文标题:时序预测的七种方法(python)

          本文链接:https://www.haomeiwen.com/subject/fzzrvhtx.html