超完整!11 種經(jīng)典時(shí)間序列預(yù)測(cè)方法!
本文我們深入探討如何使用機(jī)器學(xué)習(xí)方法對(duì) Python 的時(shí)間序列問題進(jìn)行分類和預(yù)測(cè)。我們將深入研究一套經(jīng)典的時(shí)間序列預(yù)測(cè)方法,您可以在探索機(jī)器學(xué)習(xí)方法之前測(cè)試這些方法。
雖然傳統(tǒng)方法強(qiáng)調(diào)線性關(guān)系,但它們?cè)谠S多情況下都是熟練且有效的。只要數(shù)據(jù)準(zhǔn)備充分,技術(shù)設(shè)置好就會(huì)很好。
一、 概述
本文演示了 11 種不同的經(jīng)典時(shí)間序列預(yù)測(cè)方法,以及時(shí)間序列方法的對(duì)比及實(shí)踐教程。
- 自回歸 (AR)
- 移動(dòng)平均線 (MA)
- 自回歸移動(dòng)平均線 (ARMA)
- 自回歸綜合移動(dòng)平均線 (ARIMA)
- 季節(jié)性自回歸綜合移動(dòng)平均線 (SARIMA)
- 具有外生回歸的季節(jié)性自回歸積分移動(dòng)平均值 (SARIMAX)
- 向量自回歸 (VAR)
- 向量自回歸移動(dòng)平均 (VARMA)
- 具有外生回歸的向量自回歸移動(dòng)平均值 (VARMAX)
- 簡(jiǎn)單指數(shù)平滑 (SES)
- Holt Winter 指數(shù)平滑 (HWES)
每種方法都以一致的方式呈現(xiàn),包括:
- 描述。對(duì)該技術(shù)的簡(jiǎn)短而精確的描述。
- Python 代碼。一個(gè)簡(jiǎn)短的工作示例,用于在 Python 中擬合模型并進(jìn)行預(yù)測(cè)。
- 更多信息。API 和算法的參考。
對(duì)于提供的每個(gè)代碼示例,我們使用一個(gè)基本的說明性數(shù)據(jù)集。我們理解它可能并不總是適合重點(diǎn)方法,因此我們建議您用您的數(shù)據(jù)替換人為的數(shù)據(jù)集,以測(cè)試該方法。
請(qǐng)記?。憾ㄖ泼糠N方法都需要針對(duì)您的具體問題進(jìn)行調(diào)整。在許多情況下,我已經(jīng)在博客上提供了如何配置甚至網(wǎng)格搜索參數(shù)的示例,請(qǐng)嘗試搜索功能。
如果本指南被證明是有益的,請(qǐng)?jiān)谙旅娴脑u(píng)論部分分享您的想法。
自回歸 (AR)
自回歸 (AR) 方法使用先前觀測(cè)值的線性組合來預(yù)測(cè)序列中的后續(xù)值。
模型的符號(hào)涉及將模型 p 的順序指定為 AR 函數(shù)的參數(shù),例如 AR(p)。例如,AR(1) 是一個(gè)一階自回歸模型。
該方法最適合缺乏趨勢(shì)和季節(jié)性分量的單變量時(shí)間序列。
Python 代碼
# AR example
from statsmodels.tsa.ar_model import AutoReg
from random import random
# contrived dataset
data = [x + random() for x in range(1, 100)]
# fit model
model = AutoReg(data, lags=1)
model_fit = model.fit()
# make prediction
yhat = model_fit.predict(len(data), len(data))
print(yhat)
移動(dòng)平均線 (MA)
移動(dòng)平均 (MA) 方法模型將序列中的下一步預(yù)測(cè)為先前時(shí)間步長(zhǎng)中平均過程殘余誤差的線性函數(shù)。
需要注意的是,移動(dòng)平均線模型不同于計(jì)算時(shí)間序列的移動(dòng)平均線。
模型的符號(hào)涉及將模型 q 的順序指定為 MA 函數(shù)的參數(shù),例如 MA(q)。例如,MA(1) 是一個(gè)一階移動(dòng)平均模型。
該方法適用于沒有趨勢(shì)和季節(jié)分量的單變量時(shí)間序列。
我們可以使用 ARIMA 類來創(chuàng)建 MA 模型并設(shè)置零階 AR 模型。我們必須在 order 參數(shù)中指定 MA 模型的順序。
Python 代碼
我們可以使用 ARIMA 類來創(chuàng)建 MA 模型并設(shè)置零階 AR 模型。我們必須在 order 參數(shù)中指定 MA 模型的順序。
# MA example
from statsmodels.tsa.arima.model import ARIMA
from random import random
# contrived dataset
data = [x + random() for x in range(1, 100)]
# fit model
model = ARIMA(data, order=(0, 0, 1))
model_fit = model.fit()
# make prediction
yhat = model_fit.predict(len(data), len(data))
print(yhat)
自回歸移動(dòng)平均線 (ARMA)
自回歸移動(dòng)平均 (ARMA) 方法模型基于過去觀測(cè)值和過去殘差的線性組合來預(yù)測(cè)序列中的下一步。
該方法結(jié)合了自回歸 (AR) 和移動(dòng)平均 (MA) 模型。
為了表示模型,符號(hào)涉及將 AR(p) 和 MA(q) 模型的順序指定為 ARMA 函數(shù)的參數(shù),例如 ARMA(p, q)。ARIMA 模型可用于開發(fā) AR 或 MA 模型。
該方法適用于沒有趨勢(shì)和季節(jié)分量的單變量時(shí)間序列。
Python 代碼
# ARMA example
from statsmodels.tsa.arima.model import ARIMA
from random import random
# contrived dataset
data = [random() for x in range(1, 100)]
# fit model
model = ARIMA(data, order=(2, 0, 1))
model_fit = model.fit()
# make prediction
yhat = model_fit.predict(len(data), len(data))
print(yhat)
更多信息
- 維基百科上的自回歸-移動(dòng)平均模型
自回歸綜合移動(dòng)平均線 (ARIMA)
自回歸綜合移動(dòng)平均 (ARIMA) 方法模型將序列中的下一步預(yù)測(cè)為先前時(shí)間步長(zhǎng)的差分觀測(cè)值和殘差誤差的線性函數(shù)。
該方法集成了自回歸 (AR) 和移動(dòng)平均 (MA) 模型的原理以及序列的差分預(yù)處理步驟,使序列靜止,稱為積分 (I)。
模型的符號(hào)涉及將 AR(p)、I(d) 和 MA(q) 模型的順序指定為 ARIMA 函數(shù)的參數(shù),例如 ARIMA(p, d, q)。ARIMA 模型還可用于開發(fā) AR、MA 和 ARMA 模型。
ARIMA 方法最適合表現(xiàn)出趨勢(shì)但缺乏季節(jié)性變化的單變量時(shí)間序列。
Python 代碼
# ARIMA example
from statsmodels.tsa.arima.model import ARIMA
from random import random
# contrived dataset
data = [x + random() for x in range(1, 100)]
# fit model
model = ARIMA(data, order=(1, 1, 1))
model_fit = model.fit()
# make prediction
yhat = model_fit.predict(len(data), len(data), typ='levels')
print(yhat)
更多信息
- 維基百科上的自回歸綜合移動(dòng)平均線
季節(jié)性自回歸綜合移動(dòng)平均線 (SARIMA)
季節(jié)性自回歸綜合移動(dòng)平均 (SARIMA) 方法基于差異觀測(cè)值、誤差、差異季節(jié)性觀測(cè)值和先前時(shí)間步長(zhǎng)的季節(jié)性誤差的線性混合,對(duì)序列中的下一步進(jìn)行建模。
SARIMA 增強(qiáng)了 ARIMA 模型,使其能夠在季節(jié)性水平上執(zhí)行相同的自回歸、差分和移動(dòng)平均建模。
該模型的符號(hào)涉及指定 AR(p)、I(d) 和 MA(q) 模型的順序作為 ARIMA 函數(shù)的參數(shù),以及季節(jié)性水平的 AR(P)、I(D)、MA(Q) 和 m 參數(shù),例如 SARIMA(p, d, q)(P, D, Q)m,其中“m”是每個(gè)季節(jié)(季節(jié)周期)的時(shí)間步長(zhǎng)數(shù)。SARIMA 模型可用于開發(fā) AR、MA、ARMA 和 ARIMA 模型。
該方法適用于具有趨勢(shì)和/或季節(jié)性分量的單變量時(shí)間序列。
Python 代碼
# SARIMA example
from statsmodels.tsa.statespace.sarimax import SARIMAX
from random import random
# contrived dataset
data = [x + random() for x in range(1, 100)]
# fit model
model = SARIMAX(data, order=(1, 1, 1), seasonal_order=(0, 0, 0, 0))
model_fit = model.fit(disp=False)
# make prediction
yhat = model_fit.predict(len(data), len(data))
print(yhat)
更多信息
- statsmodels.tsa.statespace.sarimax.SARIMAX API 接口
- statsmodels.tsa.statespace.sarimax.SARIMAXResults API
- 維基百科上的自回歸綜合移動(dòng)平均線
具有外生回歸的季節(jié)性自回歸積分移動(dòng)平均值 (SARIMAX)
具有外生回歸的季節(jié)性自回歸綜合移動(dòng)平均值 (SARIMAX) 是 SARIMA 模型的擴(kuò)展,其中還包括外生變量的建模。
外生變量也稱為協(xié)變量,可以將其視為具有與原始序列相同的時(shí)間步長(zhǎng)的觀測(cè)值的并行輸入序列。初級(jí)序列可以稱為內(nèi)源性數(shù)據(jù),以將其與外源序列進(jìn)行對(duì)比。外生變量的觀測(cè)值在每個(gè)時(shí)間步直接包含在模型中,并且以與主要內(nèi)生序列相同的方式建模(例如,作為 AR、MA 等過程)。
SARIMAX 方法還可用于對(duì)具有外生變量(如 ARX、MAX、ARMAX 和 ARIMAX)的歸入模型進(jìn)行建模。
該方法適用于具有趨勢(shì)和/或季節(jié)成分以及外生變量的單變量時(shí)間序列。
Python 代碼
# SARIMAX example
from statsmodels.tsa.statespace.sarimax import SARIMAX
from random import random
# contrived dataset
data1 = [x + random() for x in range(1, 100)]
data2 = [x + random() for x in range(101, 200)]
# fit model
model = SARIMAX(data1, exog=data2, order=(1, 1, 1), seasonal_order=(0, 0, 0, 0))
model_fit = model.fit(disp=False)
# make prediction
exog2 = [200 + random()]
yhat = model_fit.predict(len(data1), len(data1), exog=[exog2])
print(yhat)
更多信息
- statsmodels.tsa.statespace.sarimax.SARIMAX API 接口
- statsmodels.tsa.statespace.sarimax.SARIMAXResults API
- 維基百科上的自回歸綜合移動(dòng)平均線
向量自回歸 (VAR)
向量自回歸 (VAR) 方法使用 AR 模型方法對(duì)每個(gè)時(shí)間序列中的下一步進(jìn)行建模。從本質(zhì)上講,它擴(kuò)展了 AR 模型以迎合多個(gè)并行時(shí)間序列,例如多變量時(shí)間序列。
模型的符號(hào)涉及將 AR(p) 模型的順序指定為 VAR 函數(shù)的參數(shù),例如 VAR(p)。
該方法適用于沒有趨勢(shì)和季節(jié)分量的多變量時(shí)間序列。
Python 代碼
from statsmodels.tsa.vector_ar.var_model import VAR
from random import random
# contrived dataset with dependency
data = list()
for i in range(100):
v1 = i + random()
v2 = v1 + random()
row = [v1, v2]
data.append(row)
# fit model
model = VAR(data)
model_fit = model.fit()
# make prediction
yhat = model_fit.forecast(model_fit.y, steps=1)
print(yhat)
更多信息
- statsmodels.tsa.vector_ar.var_model。VAR API
- statsmodels.tsa.vector_ar.var_model。VARResults API
- 維基百科上的向量自回歸
向量自回歸移動(dòng)平均 (VARMA)
向量自回歸移動(dòng)平均 (VARMA) 方法利用 ARMA 模型方法對(duì)多個(gè)時(shí)間序列中即將到來的值進(jìn)行建模。它是ARMA對(duì)多個(gè)并行時(shí)間序列的推廣,例如多變量時(shí)間序列。
模型的符號(hào)涉及將 AR(p) 和 MA(q) 模型的順序指定為 VARMA 函數(shù)的參數(shù),例如 VARMA(p, q)。VARMA 模型還可用于開發(fā) VAR 或 VMA 模型。
該方法適用于沒有趨勢(shì)和季節(jié)分量的多變量時(shí)間序列。
Python 代碼
更多信息
- statsmodels.tsa.statespace.varmax.VARMAX 接口
- statsmodels.tsa.statespace.varmax.VARMAXResults
- 維基百科上的向量自回歸
具有外生回歸的向量自回歸移動(dòng)平均值 (VARMAX)
具有外生回歸的向量自回歸移動(dòng)平均值 (VARMAX) 擴(kuò)展了 VARMA 模型的功能,其中還包括外生變量的建模。它是 ARMAX 方法的多變量版本。
外生變量,也稱為協(xié)變量,可以認(rèn)為是與原始序列的時(shí)間步長(zhǎng)對(duì)齊的并行輸入序列。主要系列被稱為內(nèi)源性數(shù)據(jù),以將其與外源序列進(jìn)行對(duì)比。外生變量的觀測(cè)值在每個(gè)時(shí)間步直接包含在模型中,并且以與主要內(nèi)生序列相同的方式建模(例如,作為 AR、MA 等過程)。
VARMAX 方法還可用于對(duì)具有外生變量(如 VARX 和 VMAX)的歸和模型進(jìn)行建模。
該方法適用于無趨勢(shì)的多變量時(shí)間序列和具有外生變量的季節(jié)分量。
Python 代碼
# VARMAX example
from statsmodels.tsa.statespace.varmax import VARMAX
from random import random
# contrived dataset with dependency
data = list()
for i in range(100):
v1 = random()
v2 = v1 + random()
row = [v1, v2]
data.append(row)
data_exog = [x + random() for x in range(100)]
# fit model
model = VARMAX(data, exog=data_exog, order=(1, 1))
model_fit = model.fit(disp=False)
# make prediction
data_exog2 = [[100]]
yhat = model_fit.forecast(exog=data_exog2)
print(yhat)
更多信息
- statsmodels.tsa.statespace.varmax.VARMAX 接口
- statsmodels.tsa.statespace.varmax.VARMAXResults
- 維基百科上的向量自回歸
簡(jiǎn)單指數(shù)平滑 (SES)
簡(jiǎn)單指數(shù)平滑 (SES) 方法將下一個(gè)時(shí)間步長(zhǎng)建模為先前時(shí)間步長(zhǎng)觀測(cè)值的指數(shù)加權(quán)線性函數(shù)。
該方法適用于沒有趨勢(shì)和季節(jié)分量的單變量時(shí)間序列。
Python 代碼
# SES example
from statsmodels.tsa.holtwinters import SimpleExpSmoothing
from random import random
# contrived dataset
data = [x + random() for x in range(1, 100)]
# fit model
model = SimpleExpSmoothing(data)
model_fit = model.fit()
# make prediction
yhat = model_fit.predict(len(data), len(data))
print(yhat)
更多信息
- statsmodels.tsa.holtwinters.SimpleExpSmoothing API 接口
- statsmodels.tsa.holtwinters.HoltWinters結(jié)果 API
- 維基百科上的指數(shù)平滑
Holt Winter 指數(shù)平滑 (HWES)
Holt Winter's Exponential Smoothing (HWES) 也稱為三重指數(shù)平滑方法,將下一個(gè)時(shí)間步長(zhǎng)建模為先前時(shí)間步長(zhǎng)觀測(cè)值的指數(shù)加權(quán)線性函數(shù),同時(shí)考慮趨勢(shì)和季節(jié)性。
該方法適用于具有趨勢(shì)和/或季節(jié)性分量的單變量時(shí)間序列。
Python 代碼
# HWES example
from statsmodels.tsa.holtwinters import ExponentialSmoothing
from random import random
# contrived dataset
data = [x + random() for x in range(1, 100)]
# fit model
model = ExponentialSmoothing(data)
model_fit = model.fit()
# make prediction
yhat = model_fit.predict(len(data), len(data))
print(yhat)
二、時(shí)間序列方法對(duì)比及實(shí)踐
在這里,我們將看看時(shí)間序列預(yù)測(cè)的例子,以及如何建立ARMA、ARIMA和SARIMA模型,對(duì)比特幣(BTC)的未來價(jià)格進(jìn)行時(shí)間序列預(yù)測(cè)。
讀取和顯示 BTC 時(shí)間序列數(shù)據(jù)
我們將首先使用 Pandas 數(shù)據(jù)讀取器讀取 BTC 的歷史價(jià)格。讓我們?cè)诮K端中使用一個(gè)簡(jiǎn)單的 pip 命令來安裝它:
pip install pandas-datareader
讓我們打開一個(gè) Python 腳本,并從 Pandas 庫中導(dǎo)入數(shù)據(jù)讀取器:
import pandas_datareader.data as web
import datetime
我們還導(dǎo)入 Pandas 庫本身,并放寬對(duì)列和行的顯示限制:
import pandas as pd
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
現(xiàn)在,我們可以導(dǎo)入日期時(shí)間庫,這將允許我們定義數(shù)據(jù)提取的開始和結(jié)束日期:
import datetime
現(xiàn)在我們已經(jīng)掌握了提取比特幣價(jià)格時(shí)間序列數(shù)據(jù)所需的一切,讓我們收集數(shù)據(jù)。
import pandas_datareader as web
btc = web.get_data_yahoo(['BTC-USD'], start=datetime.datetime(2018, 1, 1), end=datetime.datetime(2020, 12, 2))['Close']
print(btc.head())
我們看到我們的數(shù)據(jù)框包含許多列。讓我們來看看這些列中的每一個(gè)的含義。
- 日期:這是我們時(shí)間序列中的索引,用于指定與價(jià)格關(guān)聯(lián)的日期。
- 收盤價(jià):當(dāng)天購(gòu)買BTC的最后價(jià)格。
- 開盤價(jià):當(dāng)天購(gòu)買BTC的第一個(gè)價(jià)格。
- 最高價(jià):當(dāng)天購(gòu)買BTC的最高價(jià)格。
- 最低價(jià):當(dāng)天購(gòu)買BTC的最低價(jià)格。
- 交易量:當(dāng)天的總交易次數(shù)。
- 調(diào)整收盤價(jià):根據(jù)股息和股票分割調(diào)整后的收盤價(jià)。
我們將使用收盤價(jià)作為預(yù)測(cè)模型。具體來說,我們將使用歷史收盤價(jià) BTC 來預(yù)測(cè)未來的 BTC 價(jià)格。
讓我們將收盤價(jià) BTC 數(shù)據(jù)寫入 csv 文件。這樣,我們就可以避免使用 Pandas 數(shù)據(jù)讀取器重復(fù)提取數(shù)據(jù)。
btc.to_csv("btc.csv")
現(xiàn)在,讓我們閱讀 csv 文件并顯示前五行:
btc = pd.read_csv("btc.csv")
print(btc.head())
為了使用統(tǒng)計(jì)庫提供的模型,我們需要將日期列設(shè)置為數(shù)據(jù)框索引。我們還應(yīng)該使用 to_datetime 方法格式化該日期:
btc.index = pd.to_datetime(btc['Date'], format='%Y-%m-%d')
讓我們顯示我們的數(shù)據(jù)框:
del btc['Date']
讓我們繪制我們的時(shí)間序列數(shù)據(jù)。為此,讓我們導(dǎo)入數(shù)據(jù)可視化庫 Seaborn 和 Matplotlib:
import matplotlib.pyplot as plt
import seaborn as sns
讓我們使用 Seaborn 格式化可視化:
sns.set()
并使用 Matplotlib 標(biāo)記 y 軸和 x 軸。我們還將在 x 軸上旋轉(zhuǎn)日期,以便它們更易于閱讀:
plt.ylabel('BTC Price')
plt.xlabel('Date')
plt.xticks(rotatinotallow=45)
最后,使用 Matplotlib 生成我們的圖:
plt.plot(btc.index, btc['BTC-USD'], )
現(xiàn)在我們可以繼續(xù)構(gòu)建我們的第一個(gè)時(shí)間序列模型,即自回歸移動(dòng)平均線。
拆分?jǐn)?shù)據(jù)進(jìn)行訓(xùn)練和測(cè)試
模型構(gòu)建的一個(gè)重要部分是拆分我們的數(shù)據(jù)以進(jìn)行訓(xùn)練和測(cè)試,這可確保構(gòu)建一個(gè)可以在訓(xùn)練數(shù)據(jù)之外泛化的模型,并且性能和輸出具有統(tǒng)計(jì)意義。
我們將拆分?jǐn)?shù)據(jù),使 2020 年 11 月之前的所有內(nèi)容都作為訓(xùn)練數(shù)據(jù),而 2020 年之后的所有內(nèi)容都將成為測(cè)試數(shù)據(jù):
train = btc[btc.index < pd.to_datetime("2020-11-01", format='%Y-%m-%d')]
test = btc[btc.index > pd.to_datetime("2020-11-01", format='%Y-%m-%d')]
plt.plot(train, color = "black")
plt.plot(test, color = "red")
plt.ylabel('BTC Price')
plt.xlabel('Date')
plt.xticks(rotatinotallow=45)
plt.title("Train/Test split for BTC Data")
plt.show()
自回歸移動(dòng)平均線 (ARMA)
ARMA 中的術(shù)語“自回歸”意味著模型使用過去的值來預(yù)測(cè)未來的值。具體而言,預(yù)測(cè)值是過去值的加權(quán)線性組合。這種類型的回歸方法類似于線性回歸,不同之處在于此處的特征輸入是歷史值。
移動(dòng)平均是指由白噪聲項(xiàng)的加權(quán)線性組合表示的預(yù)測(cè),其中白噪聲是隨機(jī)信號(hào)。這里的想法是,ARMA使用過去值和白噪聲的組合來預(yù)測(cè)未來的值。自回歸對(duì)市場(chǎng)參與者的行為進(jìn)行建模,例如買賣BTC。白噪聲模型震撼了戰(zhàn)爭(zhēng)、經(jīng)濟(jì)衰退和政治事件等事件。
我們可以使用 SARIMAX 軟件包定義 ARMA 模型:
from statsmodels.tsa.statespace.sarimax import SARIMAX
讓我們定義我們的輸入:
y = train['BTC-USD']
然后讓我們定義我們的模型。為了定義一個(gè)帶有 SARIMAX 類的 ARMA 模型,我們傳入了 (1, 0 ,1) 的階數(shù)參數(shù)。Alpha 對(duì)應(yīng)于我們預(yù)測(cè)的顯著性水平。通常,我們選擇 alpha = 0.05。在這里,ARIMA 算法計(jì)算預(yù)測(cè)周圍的上限和下限,因此實(shí)際值有 5% 的可能性超出上限和下限。這意味著有 95% 的置信度認(rèn)為實(shí)際值將介于我們預(yù)測(cè)的上限和下限之間。
ARMAmodel = SARIMAX(y, order = (1, 0, 1))
然后,我們可以擬合我們的模型:
ARMAmodel = ARMAmodel.fit()
生成我們的預(yù)測(cè):
y_pred = ARMAmodel.get_forecast(len(test.index))
y_pred_df = y_pred.conf_int(alpha = 0.05)
y_pred_df["Predictions"] = ARMAmodel.predict(start = y_pred_df.index[0], end = y_pred_df.index[-1])
y_pred_df.index = test.index
y_pred_out = y_pred_df["Predictions"]
并繪制結(jié)果:
plt.plot(y_pred_out, color='green', label = 'Predictions')
plt.legend()
我們還可以使用均方根誤差來評(píng)估性能:
import numpy as np
from sklearn.metrics import mean_squared_error
arma_rmse = np.sqrt(mean_squared_error(test["BTC-USD"].values, y_pred_df["Predictions"]))
print("RMSE: ",arma_rmse)
RMSE相當(dāng)高,我們可以在檢查地塊時(shí)猜到這一點(diǎn)。不幸的是,當(dāng)價(jià)格實(shí)際上漲時(shí),該模型預(yù)測(cè)價(jià)格會(huì)下降。同樣,ARMA 的局限性在于它無法用于非平穩(wěn)時(shí)間序列,并且無法捕獲季節(jié)性。讓我們看看我們是否可以使用 ARIMA 模型提高性能。
自回歸綜合移動(dòng)平均線 (ARIMA)
讓我們從統(tǒng)計(jì)庫導(dǎo)入 ARIMA 包:
from statsmodels.tsa.arima.model import ARIMA
ARIMA 任務(wù)有三個(gè)參數(shù)。第一個(gè)參數(shù)對(duì)應(yīng)于滯后(過去的值),第二個(gè)參數(shù)對(duì)應(yīng)于差分(這就是使非平穩(wěn)數(shù)據(jù)平穩(wěn)的原因),最后一個(gè)參數(shù)對(duì)應(yīng)于白噪聲(用于模擬沖擊事件)。
讓我們定義一個(gè)帶有階參數(shù) (2,2,2) 的 ARIMA 模型:
ARIMAmodel = ARIMA(y, order = (2, 2, 2))
ARIMAmodel = ARIMAmodel.fit()
y_pred = ARIMAmodel.get_forecast(len(test.index))
y_pred_df = y_pred.conf_int(alpha = 0.05)
y_pred_df["Predictions"] = ARIMAmodel.predict(start = y_pred_df.index[0], end = y_pred_df.index[-1])
y_pred_df.index = test.index
y_pred_out = y_pred_df["Predictions"]
plt.plot(y_pred_out, color='Yellow', label = 'ARIMA Predictions')
plt.legend()
import numpy as np
from sklearn.metrics import mean_squared_error
arma_rmse = np.sqrt(mean_squared_error(test["BTC-USD"].values, y_pred_df["Predictions"]))
print("RMSE: ",arma_rmse)
我們看到 ARIMA 預(yù)測(cè)(黃色)位于 ARMA 預(yù)測(cè)之上。讓我們嘗試將差異參數(shù)增加到 ARIMA (2,3,2):
我們看到這有助于捕捉價(jià)格上漲的方向。讓我們嘗試使用 ARIMA(5,4,2) 進(jìn)一步使用參數(shù):
我們的 RMSE 為 793,比 ARMA 好。另一種方法是根據(jù)時(shí)間特征(如周、月和年)訓(xùn)練線性回歸模型。這種方法是有限的,因?yàn)樗荒芟?ARIMA 方法那樣捕獲自回歸和移動(dòng)平均特征。此外,ARIMA 根據(jù)去趨勢(shì)滯后目標(biāo)值訓(xùn)練回歸器,而不是線性回歸等自變量。話雖如此,ARIMA的表現(xiàn)可能會(huì)優(yōu)于在獨(dú)立時(shí)間變量上訓(xùn)練的線性回歸模型。
最后,讓我們看看包含季節(jié)性的SARIMA是否會(huì)進(jìn)一步提高性能。
季節(jié)性 ARIMA (SARIMA)
季節(jié)性 ARIMA 捕捉歷史價(jià)值、沖擊事件和季節(jié)性。我們可以使用 SARIMAX 類定義一個(gè) SARIMA 模型:
SARIMAXmodel = SARIMAX(y, order = (5, 4, 2), seasonal_order=(2,2,2,12))
SARIMAXmodel = SARIMAXmodel.fit()
y_pred = SARIMAXmodel.get_forecast(len(test.index))
y_pred_df = y_pred.conf_int(alpha = 0.05)
y_pred_df["Predictions"] = SARIMAXmodel.predict(start = y_pred_df.index[0], end = y_pred_df.index[-1])
y_pred_df.index = test.index
y_pred_out = y_pred_df["Predictions"]
plt.plot(y_pred_out, color='Blue', label = 'SARIMA Predictions')
plt.legend()
在這里,我們的 RMSE 為 966,比 ARIMA 略差。這可能是由于缺乏超參數(shù)優(yōu)化。如果我們對(duì) SARIMA 模型的參數(shù)進(jìn)行調(diào)整,我們應(yīng)該能夠進(jìn)一步提高性能。
我鼓勵(lì)您嘗試使用超參數(shù),看看是否可以構(gòu)建一個(gè)性能優(yōu)于 ARIMA 的 SARIMA 模型。此外,您可以采用網(wǎng)格搜索等方法通過算法找到每個(gè)模型的最佳參數(shù)。
總結(jié)
在這篇文章中,你發(fā)現(xiàn)了一套經(jīng)典的時(shí)間序列預(yù)測(cè)方法,你可以在時(shí)間序列數(shù)據(jù)集上測(cè)試和調(diào)整這些方法。這些方法專為各種時(shí)序數(shù)據(jù)集而設(shè)計(jì),可用于在各種方案和行業(yè)中實(shí)現(xiàn)它們。無論您是在處理股票市場(chǎng)趨勢(shì)、天氣預(yù)報(bào)還是銷售預(yù)測(cè),這些方法都可以提供有價(jià)值的預(yù)測(cè)。