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)

 移動平均線 (MA)

移動平均 (MA) 方法模型將序列中的下一步預測為先前時間步長中平均過程殘余誤差的線性函數。

需要注意的是,移動平均線模型不同于計算時間序列的移動平均線。

模型的符號涉及將模型 q 的順序指定為 MA 函數的參數,例如 MA(q)。例如,MA(1) 是一個一階移動平均模型。

該方法適用于沒有趨勢和季節分量的單變量時間序列。

我們可以使用 ARIMA 類來創建 MA 模型并設置零階 AR 模型。我們必須在 order 參數中指定 MA 模型的順序。

 Python 代碼

我們可以使用 ARIMA 類來創建 MA 模型并設置零階 AR 模型。我們必須在 order 參數中指定 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)

自回歸移動平均線 (ARMA)

自回歸移動平均 (ARMA) 方法模型基于過去觀測值和過去殘差的線性組合來預測序列中的下一步。

該方法結合了自回歸 (AR) 和移動平均 (MA) 模型。

為了表示模型,符號涉及將 AR(p) 和 MA(q) 模型的順序指定為 ARMA 函數的參數,例如 ARMA(p, q)。ARIMA 模型可用于開發 AR 或 MA 模型。

該方法適用于沒有趨勢和季節分量的單變量時間序列

?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)

 更多信息

自回歸綜合移動平均線 (ARIMA)

自回歸綜合移動平均 (ARIMA) 方法模型將序列中的下一步預測為先前時間步長的差分觀測值和殘差誤差的線性函數。

該方法集成了自回歸 (AR) 和移動平均 (MA) 模型的原理以及序列的差分預處理步驟,使序列靜止,稱為積分 (I)。

模型的符號涉及將 AR(p)、I(d) 和 MA(q) 模型的順序指定為 ARIMA 函數的參數,例如 ARIMA(p, d, q)。ARIMA 模型還可用于開發 AR、MA 和 ARMA 模型。

ARIMA 方法最適合表現出趨勢但缺乏季節性變化的單變量時間序列

?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)

 更多信息

季節性自回歸綜合移動平均線 (SARIMA)

季節性自回歸綜合移動平均 (SARIMA) 方法基于差異觀測值、誤差、差異季節性觀測值和先前時間步長的季節性誤差的線性混合,對序列中的下一步進行建模。

SARIMA 增強了 ARIMA 模型,使其能夠在季節性水平上執行相同的自回歸、差分和移動平均建模。

該模型的符號涉及指定 AR(p)、I(d) 和 MA(q) 模型的順序作為 ARIMA 函數的參數,以及季節性水平的 AR(P)、I(D)、MA(Q) 和 m 參數,例如 SARIMA(p, d, q)(P, D, Q)m,其中“m”是每個季節(季節周期)的時間步長數。SARIMA 模型可用于開發 AR、MA、ARMA 和 ARIMA 模型。

該方法適用于具有趨勢和/或季節性分量的單變量時間序列

?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)

 更多信息

具有外生回歸的季節性自回歸積分移動平均值 (SARIMAX)

具有外生回歸的季節性自回歸綜合移動平均值 (SARIMAX) 是 SARIMA 模型的擴展,其中還包括外生變量的建模。

外生變量也稱為協變量,可以將其視為具有與原始序列相同的時間步長的觀測值的并行輸入序列。初級序列可以稱為內源性數據,以將其與外源序列進行對比。外生變量的觀測值在每個時間步直接包含在模型中,并且以與主要內生序列相同的方式建模(例如,作為 AR、MA 等過程)。

SARIMAX 方法還可用于對具有外生變量(如 ARX、MAX、ARMAX 和 ARIMAX)的歸入模型進行建模。

該方法適用于具有趨勢和/或季節成分以及外生變量的單變量時間序列

?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)

 更多信息

向量自回歸 (VAR)

向量自回歸 (VAR) 方法使用 AR 模型方法對每個時間序列中的下一步進行建模。從本質上講,它擴展了 AR 模型以迎合多個并行時間序列,例如多變量時間序列。

模型的符號涉及將 AR(p) 模型的順序指定為 VAR 函數的參數,例如 VAR(p)。

該方法適用于沒有趨勢和季節分量的多變量時間序列

?Python 代碼

# VAR example
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)

 更多信息

向量自回歸移動平均 (VARMA)

向量自回歸移動平均 (VARMA) 方法利用 ARMA 模型方法對多個時間序列中即將到來的值進行建模。它是ARMA對多個并行時間序列的推廣,例如多變量時間序列。

模型的符號涉及將 AR(p) 和 MA(q) 模型的順序指定為 VARMA 函數的參數,例如 VARMA(p, q)。VARMA 模型還可用于開發 VAR 或 VMA 模型。

該方法適用于沒有趨勢和季節分量的多變量時間序列

 Python 代碼

 更多信息

具有外生回歸的向量自回歸移動平均值 (VARMAX)

具有外生回歸的向量自回歸移動平均值 (VARMAX) 擴展了 VARMA 模型的功能,其中還包括外生變量的建模。它是 ARMAX 方法的多變量版本。

外生變量,也稱為協變量,可以認為是與原始序列的時間步長對齊的并行輸入序列。主要系列被稱為內源性數據,以將其與外源序列進行對比。外生變量的觀測值在每個時間步直接包含在模型中,并且以與主要內生序列相同的方式建模(例如,作為 AR、MA 等過程)。

VARMAX 方法還可用于對具有外生變量(如 VARX 和 VMAX)的歸和模型進行建模。

該方法適用于無趨勢的多變量時間序列和具有外生變量的季節分量。

?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)

 更多信息

簡單指數平滑 (SES)

簡單指數平滑 (SES) 方法將下一個時間步長建模為先前時間步長觀測值的指數加權線性函數。

該方法適用于沒有趨勢和季節分量的單變量時間序列

?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)

 更多信息

Holt Winter 指數平滑 (HWES)

Holt Winter’s Exponential Smoothing (HWES) 也稱為三重指數平滑方法,將下一個時間步長建模為先前時間步長觀測值的指數加權線性函數,同時考慮趨勢和季節性。

該方法適用于具有趨勢和/或季節性分量的單變量時間序列

?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)


二、時間序列方法對比及實踐

在這里,我們將看看時間序列預測的例子,以及如何建立ARMA、ARIMA和SARIMA模型,對比特幣(BTC)的未來價格進行時間序列預測。

讀取和顯示 BTC 時間序列數據

我們將首先使用 Pandas 數據讀取器讀取 BTC 的歷史價格。讓我們在終端中使用一個簡單的 pip 命令來安裝它:

pip install pandas-datareader

讓我們打開一個 Python 腳本,并從 Pandas 庫中導入數據讀取器:

import pandas_datareader.data as web
import datetime

我們還導入 Pandas 庫本身,并放寬對列和行的顯示限制:

import pandas as pd 
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)

現在,我們可以導入日期時間庫,這將允許我們定義數據提取的開始和結束日期:

import datetime

import datetime現在我們已經掌握了提取比特幣價格時間序列數據所需的一切,讓我們收集數據。

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())

我們看到我們的數據框包含許多列。讓我們來看看這些列中的每一個的含義。

  1. 日期:這是我們時間序列中的索引,用于指定與價格關聯的日期。
  2. 收盤價:當天購買BTC的最后價格。
  3. 開盤價:當天購買BTC的第一個價格。
  4. 最高價:當天購買BTC的最高價格。
  5. 最低價:當天購買BTC的最低價格。
  6. 交易量:當天的總交易次數。
  7. 調整收盤價:根據股息和股票分割調整后的收盤價。

我們將使用收盤價作為預測模型。具體來說,我們將使用歷史收盤價 BTC 來預測未來的 BTC 價格。讓我們將收盤價 BTC 數據寫入 csv 文件。這樣,我們就可以避免使用 Pandas 數據讀取器重復提取數據。

btc.to_csv("btc.csv")

現在,讓我們閱讀 csv 文件并顯示前五行:

btc = pd.read_csv("btc.csv")
print(btc.head())

為了使用統計庫提供的模型,我們需要將日期列設置為數據框索引。我們還應該使用 to_datetime 方法格式化該日期:

btc.index = pd.to_datetime(btc['Date'], format='%Y-%m-%d')

讓我們顯示我們的數據框:

del btc['Date']

讓我們繪制我們的時間序列數據。為此,讓我們導入數據可視化庫 Seaborn 和 Matplotlib:

import matplotlib.pyplot as plt
import seaborn as sns

讓我們使用 Seaborn 格式化可視化:

sns.set()

并使用 Matplotlib 標記 y 軸和 x 軸。我們還將在 x 軸上旋轉日期,以便它們更易于閱讀:

plt.ylabel('BTC Price')
plt.xlabel('Date')
plt.xticks(rotation=45)

最后,使用 Matplotlib 生成我們的圖:

plt.plot(btc.index, btc['BTC-USD'], )

現在我們可以繼續構建我們的第一個時間序列模型,即自回歸移動平均線。?

拆分數據進行訓練和測試

模型構建的一個重要部分是拆分我們的數據以進行訓練和測試,這可確保構建一個可以在訓練數據之外泛化的模型,并且性能和輸出具有統計意義。我們將拆分數據,使 2020 年 11 月之前的所有內容都作為訓練數據,而 2020 年之后的所有內容都將成為測試數據:

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(rotation=45)
plt.title("Train/Test split for BTC Data")
plt.show()

自回歸移動平均線 (ARMA)

ARMA 中的術語“自回歸”意味著模型使用過去的值來預測未來的值。具體而言,預測值是過去值的加權線性組合。這種類型的回歸方法類似于線性回歸,不同之處在于此處的特征輸入是歷史值。移動平均是指由白噪聲項的加權線性組合表示的預測,其中白噪聲是隨機信號。這里的想法是,ARMA使用過去值和白噪聲的組合來預測未來的值。自回歸對市場參與者的行為進行建模,例如買賣BTC。白噪聲模型震撼了戰爭、經濟衰退和政治事件等事件。我們可以使用 SARIMAX 軟件包定義 ARMA 模型:

from statsmodels.tsa.statespace.sarimax import SARIMAX

?讓我們定義我們的輸入:

y = train['BTC-USD']

y = train['BTC-USD']然后讓我們定義我們的模型。為了定義一個帶有 SARIMAX 類的 ARMA 模型,我們傳入了 (1, 0 ,1) 的階數參數。Alpha 對應于我們預測的顯著性水平。通常,我們選擇 alpha = 0.05。在這里,ARIMA 算法計算預測周圍的上限和下限,因此實際值有 5% 的可能性超出上限和下限。這意味著有 95% 的置信度認為實際值將介于我們預測的上限和下限之間。

ARMAmodel = SARIMAX(y, order = (1, 0, 1))

然后,我們可以擬合我們的模型:

ARMAmodel = ARMAmodel.fit()

生成我們的預測:

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"]

并繪制結果:

plt.plot(y_pred_out, color='green', label = '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)

RMSE相當高,我們可以在檢查地塊時猜到這一點。不幸的是,當價格實際上漲時,該模型預測價格會下降。同樣,ARMA 的局限性在于它無法用于非平穩時間序列,并且無法捕獲季節性。讓我們看看我們是否可以使用 ARIMA 模型提高性能。?

自回歸綜合移動平均線 (ARIMA)

讓我們從統計庫導入 ARIMA 包:

from statsmodels.tsa.arima.model import ARIMA

ARIMA 任務有三個參數。第一個參數對應于滯后(過去的值),第二個參數對應于差分(這就是使非平穩數據平穩的原因),最后一個參數對應于白噪聲(用于模擬沖擊事件)。讓我們定義一個帶有階參數 (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 預測(黃色)位于 ARMA 預測之上。讓我們嘗試將差異參數增加到 ARIMA (2,3,2):

我們看到這有助于捕捉價格上漲的方向。讓我們嘗試使用 ARIMA(5,4,2) 進一步使用參數:

我們的 RMSE 為 793,比 ARMA 好。另一種方法是根據時間特征(如周、月和年)訓練線性回歸模型。這種方法是有限的,因為它不能像 ARIMA 方法那樣捕獲自回歸和移動平均特征。此外,ARIMA 根據去趨勢滯后目標值訓練回歸器,而不是線性回歸等自變量。話雖如此,ARIMA的表現可能會優于在獨立時間變量上訓練的線性回歸模型。最后,讓我們看看包含季節性的SARIMA是否會進一步提高性能。 

 季節性 ARIMA (SARIMA)

季節性 ARIMA 捕捉歷史價值、沖擊事件和季節性。我們可以使用 SARIMAX 類定義一個 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 略差。這可能是由于缺乏超參數優化。如果我們對 SARIMA 模型的參數進行調整,我們應該能夠進一步提高性能。我鼓勵您嘗試使用超參數,看看是否可以構建一個性能優于 ARIMA 的 SARIMA 模型。此外,您可以采用網格搜索等方法通過算法找到每個模型的最佳參數。

 總結

在這篇文章中,你發現了一套經典的時間序列預測方法,你可以在時間序列數據集上測試和調整這些方法。這些方法專為各種時序數據集而設計,可用于在各種方案和行業中實現它們。無論您是在處理股票市場趨勢、天氣預報還是銷售預測,這些方法都可以提供有價值的預測。

文章轉自微信公眾號@算法進階

上一篇:

人工智能需要怎樣的計算范式和理論?

下一篇:

簡單有效!差分Transformer竟能消除注意力噪聲
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費