LSTM 網路引入記憶單元和門控機制,解決了傳統 RNN 無法有效處理長序列資料的瓶頸。透過遺忘門、輸入門和輸出門的協同作用,LSTM 能夠精確控制資訊的流動和更新,捕捉時間序列資料中的長期依賴關係。這使得 LSTM 在處理時間序列預測、語音識別和自然語言處理等任務中表現出色。然而,LSTM 的序列特性限制了其平行處理能力,影響了在大規模資料集上的訓練效率。DeepAR 模型則根據自迴歸遞迴網路,提供機率預測,而非單點預測值。這種機率預測方法能夠量化未來的不確定性,協助決策者更全面地評估風險。DeepAR 模型的核心優勢在於減少了特徵工程的工作量,即使缺乏歷史資料也能生成可靠的預測結果,並且能夠適應不同的分佈形式。DeepAR 模型利用深度神經網路學習時間序列的條件分佈,並透過蒙地卡羅取樣生成預測樣本軌跡。

時間序列的神經網路技術

長短期記憶(Long Short-Term Memory, LSTM)是一種特殊的迴圈神經網路(Recurrent Neural Network, RNN),專為解決長時間依賴性問題而設計。與傳統RNN相比,LSTM引入了更多的複雜性,這會影響其訓練速度。然而,LSTM在處理時間序列預測、語音識別及自然語言處理等領域中表現出色,並且已被廣泛應用於Apple的Siri和Google的AlphaGo等知名應用中。

LSTM 的技術概觀

LSTM的核心概念是引入了「記憶單元」,這些單元能夠在順序資料中儲存和傳遞資訊。這些記憶單元由三個「門」(gate)控制:遺忘門(Forget Gate)、輸入門(Input Gate)和輸出門(Output Gate)。這些門決定了哪些資訊應該被保留、更新或丟棄。

記憶單元的工作原理

以下是LSTM記憶單元的架構圖:

  graph TD;
    A[當前輸入 x(t)] --> B[遺忘門];
    A --> C[輸入門];
    A --> D[輸出門];
    E[上一隱藏狀態 h(t-1)] --> B;
    E --> C;
    E --> D;
    F[上一短期記憶 c(t-1)] --> B;
    F --> C;
    G[新記憶單元狀態 c(t)] --> D;

遺忘門

遺忘門決定哪些資訊應該被保留或丟棄。它接收當前輸入和上一隱藏狀態,並透過Sigmoid函式進行計算,其輸出範圍在0到1之間。如果輸出接近0,則表示該資訊應該被丟棄;如果接近1,則表示該資訊應該被保留。

輸入門

輸入門負責決定哪些新資訊應該被加入記憶單元。它接收當前輸入和上一隱藏狀態,並透過Sigmoid函式進行計算。同時,它還會計算新資訊的候選值,並透過Tanh函式將其壓縮到-1到1之間。最終,新資訊與遺忘門的結果相結合,形成新的記憶單元狀態。

輸出門

輸出門決定哪些資訊應該被輸出為隱藏狀態。它接收當前記憶單元狀態並透過Sigmoid函式進行計算。同時,它還會計算記憶單元狀態的Tanh值,並將兩者相乘以獲得最終的隱藏狀態。

LSTM 的實務應用

以下是使用LSTM進行時間序列預測的實務案例,具體為空載客運量預測。

首先,我們需要匯入必要的函式庫和載入資料集:

import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error, r2_score
import matplotlib.pyplot as plt
from neuralforecast import NeuralForecast
from neuralforecast.models import LSTM
from neuralforecast.tsdataset import TimeSeriesDataset
from neuralforecast.losses.pytorch import GMM, MQLoss, DistributionLoss
from neuralforecast.utils import AirPassengersDF as Y_df
from ray import tune

載入資料集並分割為訓練集和測試集:

Y_train_df = Y_df[Y_df.ds <= '1959-12-31']  # 訓練集
Y_test_df = Y_df[Y_df.ds > '1959-12-31']   # 測試集

初始化並訓練LSTM模型:

horizon = 12  # 預測時域

fcst = NeuralForecast(
    models=[
        LSTM(
            h=horizon,
            input_size=-1,
            loss=DistributionLoss(distribution='Normal', level=[80, 90]),
            scaler_type='robust',
            encoder_n_layers=2,
            encoder_hidden_size=128,
            context_size=10,
            decoder_hidden_size=128,
            decoder_layers=2,
            max_steps=200,
        )
    ],
    freq='M'
)

fcst.fit(df=Y_train_df)

進行預測:

y_hat = fcst.predict()
y_hat.set_index('ds', inplace=True)
y_hat.head()

評估模型準確性:

calculate_error_metrics(Y_test_df[['y']], y_hat[['LSTM']])

顯示結果:

MSE : 2924.734375
RMSE : 54.080814361572266
MAPE : 0.10070467740297318
r2 : 0.47201929308164103
adjusted_r2 : 0.4192212223898052

視覺化預測結果:

plt.figure(figsize=(20, 3))
y_past = Y_train_df["y"]
y_pred = y_hat[['LSTM']]
y_test = Y_test_df["y"]

plt.plot(y_past, label="歷史時間序列值")
plt.plot(y_pred, label="預測值")
plt.plot(y_test, label="實際時間序列值")

plt.title('空載客運量預測', fontsize=10)
plt.ylabel('每月乘客數', fontsize=10)
plt.xlabel('時間戳 [t]', fontsize=10)
plt.legend()

此圖示顯示了模型預測的空載客運量與實際資料之間的對比情況,我們可以看到模型預測結果與實際情況相當接近。

LSTM 的限制與未來發展

雖然LSTM在處理長時間依賴性方面表現出色,但它仍然有一些限制。例如,LSTM不支援平行處理,這使得其在大規模資料集上的訓練效率不高。未來可能會有一些新的架構,如Transformer模型,能夠克服這些限制並進一步提升時間序列預測的效能。

透過這個案例可以看到LSTM在實務應用中的強大能力及其潛力。隨著技術的不斷進步及資料科學社群的不斷探索創新方案,我們相信未來將有更多更好地解決方案來處理複雜地時間序列問題。

時序資料的深度自迴歸神經網路

在這一部分,玄貓將探討根據自迴歸(AR)的神經網路。我們將重點介紹根據自迴歸遞迴網路的 DeepAR 預測方法。自迴歸模型在時序資料預測中透過依賴過去的觀察值來預測未來的值。這些模型根據一個基本假設,即同一變數的過去和未來值是相互依賴的,它們使用過去觀察值的線性組合來進行時序資料預測。模型的「階數」僅僅是指用於計算未來值的過去值的數量。

我們之前討論過的技術提供了一個單一的預測預測值。然而,我們將在這一部分介紹的是機率預測技術。機率預測技術具有獨特的特點。這些技術不僅僅預測單一值,而是提供一個稱為機率分佈的值範圍。

2.6.1 機率預測的關鍵特性

a) 不確定性量化:提供具有機率的值範圍,而不是單一預測值。這有助於量化與未來相關聯的不確定性。

b) 考慮風險的更好決策:內在不確定性支援對於考慮風險的戰略決策至關重要。

c) 分位數表示:預測可以用分位數表示並使用箱線圖和狀態圖表示不同的置信水平。

傳統預測方法最初是為了單個時序資料進行時序預測而開發的。範圍後來擴充套件到小群組時序資料進行預測。在早期傳統方法中,每個給定時序組內部模型引數是從歷史觀察中獨立估計出來的。然後手動選擇模型以適應趨勢、季節性、週期和自相關等各種引數。然後根據模型動態選擇最佳模型進行時序預測。

DeepAR 對處理具有季節性、趨勢和其他不規則性的複雜時序資料非常有效。

在過去十年中,我們見證了資料可用性的爆炸式增長。處理大資料的新工具和技術變得流行起來。隨著需要對數百萬相關時序資料進行預測的使用案例出現,新期望和相關開發應運而生。讓我們透過參照一些使用案例來欣賞這種情況。對大型公寓樓群能源需求進行預測、對伺服器農場能耗進行預測以及感恩節期間對單個產品需求進行預測是一些例子。

在這些情況下,你可能已經注意到大量歷史資料可用性是共同點。這些資料可以是同類別或類別似事件。可以利用類別似事件的時序資料進行個別時序資料預測。從類別似事件中學習有兩個主要優勢:(a) 有效地擬合更複雜模型; (b) 減少特徵工程和模型選擇步驟中的工作量。DeepAR 的時序預測模型有效地從歷史資料中學習,利用這兩個優勢。

DeepAR 模型使用遞迴神經網路(RNN)來學習資料中的時間依賴性和模式。該模型接受變數過去值並生成未來值機率分佈。該分佈可用於估計最可能未來值或生成預測置信區間。

儘管如前所述,從多個時序資料中學習有許多優點,但仍存在一些實際問題。在真實世界中的資料集中,時序資料幅度變化很大,而且幅度分配強烈偏斜。例如,圖 2-17 解釋了領先線上零售商銷售速度(百萬單位)專案分配情況。

此圖示

  histogram
    title Sales Velocity (in millions)
    x-log Log Number of Sales
    y-log Number of Items
    series "Sales Velocity"

2.6.2 Deep Autoregressive 的技術概述

DeepAR 模型相比傳統方法有一些關鍵優勢:

(a) 特徵工程所需努力和時間較少:由於模型能夠學習給定共變數跨時間序列中的季節性和依賴性,因此無需花費大量時間和精力進行特徵工程以捕捉複雜且群組依賴行為。 (b) 無歷史資料產品也能夠產生可靠預報:因為它從類別似事件歷史資料學習。 (c) 能夠適應不同分佈形式:因為它內建了多種機率函式可以選擇。

DeepAR 模型具有一些屬性,能夠透過學習所有時間序列集合的歷史行為來產生更好的預報: (a) 擁有多種機率函式:允許時間序列建模團隊根據資料統計屬性選擇合適函式。 (b) 透過蒙地卡羅樣本生成機率預報:可用於計算屬於預報視野子範圍分位估計。

內容解密:

程式邏輯: DeepAR 模型根據 RNN 的框架設計,主要目的是解決具備週期性、趨勢以及其他不規則特徵之複雜時系列問題。其核心設計概念為透過從多重時系列資料中進行學習來提升準確度與穩定性。

設計考量

  1. 自迴歸設計:根據自迴歸概念設計模型,其能夠利用之前觀察到之資料作為未來資料之依賴參考。
  2. 遞迴神經網路(RNN):利用 RNN 作為基礎結構以便能夠捕捉與存取時間資料之間之依賴特徵與轉換。
  3. 廣泛機率函式支援:為了適應不同情境及目標而設計不同之機率函式供使用者選擇。
  4. 蒙地卡羅樣本:透過蒙地卡羅樣本生成機率分佈形式之機率結果以便更精準地反映不確定性與風險影響。

技術原理

  1. 時間依賴與週期性捕捉: 透過 RNN 構架捕捉與存取之前及當前時間點之間之依賴關係與週期變化。
  2. 跨群組學習: 透過跨多重群組資料學習來提升結果穩定度及準確度。
  3. 機率分佈輸出: 提供完整機率分佈結果以反映可能情境與風險。

潛在改進點

  1. 參考更多類別似事件資料: 執行更多次實驗以收集更多類別似事件資料以增強變異形態學習能力。
  2. 進階特徵處理: 提升現有特徵處理流程以便更全面捕捉複雜情境及訊息。
  3. 加強對極端偏差情境之處理: 改善現有演算法針對極端偏差情境下之較弱表現能力。
  4. 使用次世代 RNN 架構: 採用更新版本 RNN 架構如 LSTM 或 GRU 以提升表現與能力。

下一節將介紹 DeepAR 的具體應用及案例分析

時序資料的深度學習模型

在時序資料預測中,深度學習模型如DeepAR(Deep AutoRegressive Model)已經展現出了強大的能力。DeepAR結合了時間序列的歷史資料及其特徵,透過深度神經網路來進行預測。玄貓將從DeepAR的基本概念開始,詳細說明其工作原理、程式碼實作及應用。

DeepAR 的基本概念

DeepAR 是一種根據深度學習的時間序列預測模型,旨在模擬時間序列資料的條件分佈。它的輸入包括三個主要引數:共變數(covariates)、前一時間步的目標值以及前一網路輸出值。這些輸入資料被用來電腦率分佈引數,從而訓練模型引數。預測過程中,模型會根據歷史資料生成多個樣本軌跡,這些軌跡代表了聯合預測分佈。

此圖示

  graph TD
    A[共變數 xi, t] --> B[前一時間步目標值 zi, t - 1]
    C[前一網路輸出值 hi, t - 1] --> B
    B --> D[DeepAR 網路]
    D --> E[輸出 hi, t]
    E --> F[電腦率分佈引數]
    F --> G[訓練模型引數]
    G --> H[生成預測樣本軌跡]

此圖示展示了DeepAR 模型的基本結構和工作流程。

DeepAR 的工作原理

DeepAR 的核心理念是透過深度神經網路來建模時間序列的條件分佈。具體來說,模型會利用過去的觀測資料來預測未來的數值。以下是DeepAR 的主要步驟:

  1. 輸入處理:將共變數、前一時間步的目標值和前一網路輸出值作為模型的輸入。
  2. 網路計算:利用深度神經網路(如LSTM或GRU)進行特徵提取和時序建模。
  3. 機率分佈引數計算:根據網路輸出電腦率分佈引數。
  4. 訓練模型:使用最大似然估計法來訓練模型引數。
  5. 預測生成:在預測階段,利用歷史資料生成多個樣本軌跡。

DeepAR 的程式碼實作

以下是玄貓使用 neuralforecast 函式庫實作DeepAR 模型的完整程式碼範例。這段程式碼展示瞭如何載入資料、初始化和訓練DeepAR 模型,並進行預測和評估。

import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error, mean_absolute_percentage_error, r2_score
import matplotlib.pyplot as plt
from neuralforecast import NeuralForecast
from neuralforecast.losses.pytorch import DistributionLoss, HuberMQLoss
from neuralforecast.models import DeepAR
from neuralforecast.utils import AirPassengers, AirPassengersPanel, AirPassengersStatic

# 轉換至DataFrame格式並檢視部分資料
air_passengers_panel = AirPassengersPanel.head()
print(air_passengers_panel)

# 分割資料集為訓練集和測試集
Y_train_df = AirPassengersPanel[AirPassengersPanel.ds < AirPassengersPanel['ds'].values[-12]]
Y_test_df = AirPassengersPanel[AirPassengersPanel.ds >= AirPassengersPanel['ds'].values[-12]].reset_index(drop=True)

# 初始化並訓練DeepAR模型
nf = NeuralForecast(
    models=[DeepAR(
        h=12,
        input_size=48,
        lstm_n_layers=3,
        trajectory_samples=100,
        loss=DistributionLoss(distribution='Normal', level=[80, 90], return_params=False),
        learning_rate=0.005,
        stat_exog_list=['airline1'],
        futr_exog_list=['trend'],
        max_steps=100,
        val_check_steps=10,
        early_stop_patience_steps=-1,
        scaler_type='standard',
        enable_progress_bar=True)],
    freq='M'
)
nf.fit(df=Y_train_df, static_df=AirPassengersStatic, val_size=12)

# 預測下一個時間範圍內的值
Y_hat_df = nf.predict(futr_df=Y_test_df)
print(Y_hat_df.head())

內容解密:

  • import 陳述式:載入所需的Python函式庫,包括資料處理、評估指標和視覺化等功能。
  • AirPassengersPanel.head():檢視部分資料,確認資料格式正確。
  • Y_train_dfY_test_df:將資料集分割為訓練集和測試集,其中最後一年資料作為測試集。
  • NeuralForecast 初始化:設定DeepAR模型引數,包括預測範圍、自迴歸輸入大小、LSTM層數等。
  • nf.fit:使用訓練資料訓練DeepAR模型。
  • nf.predict:使用訓練好的模型進行預測。

評估與視覺化

完成模型訓練和預測後,玄貓會使用評估指標(如均方誤差MSE、均方根誤差RMSE、平均絕對百分比誤差MAPE等)來評估模型效能。以下是計算評估指標並視覺化結果的程式碼範例:

# 計算評估指標
def calculate_error_metrics(y_true, y_pred):
    mse = mean_squared_error(y_true, y_pred)
    rmse = np.sqrt(mse)
    mape = mean_absolute_percentage_error(y_true, y_pred)
    r2 = r2_score(y_true, y_pred)
    adjusted_r2 = 1 - (1 - r2) * (len(y_true) - 1) / (len(y_true) - len(y_pred.columns) - 1)
    return mse, rmse, mape, r2, adjusted_r2

mse, rmse, mape, r2, adjusted_r2 = calculate_error_metrics(Y_test_df[['y']], Y_hat_df[['DeepAR']])
print(f'MSE: {mse}')
print(f'RMSE: {rmse}')
print(f'MAPE: {mape}')
print(f'R2: {r2}')
print(f'Adjusted R2: {adjusted_r2}')

# 視覺化結果
Y_hat_df = Y_hat_df.reset_index(drop=False).drop(columns=['unique_id', 'ds'])
plot_df = pd.concat([Y_test_df.reset_index(drop=False), Y_hat_df], axis=1)
plot_df = pd.concat([Y_train_df.reset_index(drop=False), plot_df])
plt.figure(figsize=(20, 3))
plot_df = plot_df[plot_df.unique_id == 'Airline1'].drop('unique_id', axis=1)

plt.plot(plot_df['ds'], plot_df['y'], c='black', label='True')
plt.plot(plot_df['ds'], plot_df['DeepAR-median'], c='blue', label='Median')
plt.fill_between(x=plot_df['ds'][-12:],
                 y1=plot_df['DeepAR-lo-90'][-12:].values,
                 y2=plot_df['DeepAR-hi-90'][-12:].values,
                 alpha=0.4, label='90% confidence interval')
plt.title('Air Passengers Forecast')
plt.ylabel('Monthly Passengers')
plt.xlabel('Timestamp [t]')
plt.legend()
plt.grid()
plt.show()

內容解密:

  • calculate_error_metrics 函式:定義評估指標計算函式,傳回均方誤差、均方根誤差、平均絕對百分比誤差、R平方值及調整後R平方值。
  • mse, rmse, mape, r2, adjusted_r2:計算並列印各項評估指標。
  • 視覺化部分:將真實值及預測結果進行視覺化對比,並顯示90%信賴區間。

DeepAR 的應用與挑戰

DeepAR 在多種時序資料預測任務中表現出色,特別是在具有非線性特徵及複雜依賴關係的場景中。然而,實際應用中仍面臨一些挑戰:

  1. 資料品質:高品質且完整的歷史資料是成功應用DeepAR 的關鍵。缺失值或噪音可能會影響模型效能。
  2. 超引數調整:LSTM層數、學習率等超引數需要仔細調整以達到最佳效果。
  3. 計算資源:深度學習模型通常需要大量計算資源進行訓練和推斷。

總結來說,DeepAR 是一種強大且靈活的時序資料預測工具。透過深度學習技術,它能夠有效地捕捉時間序列中的複雜模式和依賴關係。玄貓建議在實際應用中結合領域知識進行超引數調整,並確保資料品質以提升模型效能。