使用 TiDE 進(jìn)行時(shí)間序列預(yù)測
今天云朵君和大家一起學(xué)習(xí)一種新穎的時(shí)間序列預(yù)測模型 - TiDE(Time-series Dense Encoder)。
時(shí)間序列預(yù)測一直是數(shù)據(jù)科學(xué)領(lǐng)域的一個(gè)熱門研究課題,廣泛應(yīng)用于能源、金融、交通等諸多行業(yè)。傳統(tǒng)的統(tǒng)計(jì)模型如ARIMA、GARCH等因其簡單高效而被廣泛使用。而近年來,隨著深度學(xué)習(xí)的興起,基于神經(jīng)網(wǎng)絡(luò)的預(yù)測模型也備受關(guān)注,表現(xiàn)出了強(qiáng)大的預(yù)測能力。
其中,Transformer模型因其出色的捕捉長期依賴關(guān)系的能力,一度被認(rèn)為是解決時(shí)間序列預(yù)測問題的利器。但最新研究發(fā)現(xiàn),這些基于Transformer的模型在長期預(yù)測任務(wù)中,性能并不如人意,反而被一些簡單的線性模型超越。
有鑒于此,谷歌的研究團(tuán)隊(duì)在2023年提出了TiDE模型。該模型摒棄了Transformer的復(fù)雜結(jié)構(gòu),轉(zhuǎn)而采用了多層感知器(MLP)的編碼器-解碼器架構(gòu)。雖然設(shè)計(jì)簡潔,但TiDE能有效捕捉時(shí)間序列的非線性依賴關(guān)系,并能很好地處理動(dòng)態(tài)協(xié)變量和靜態(tài)屬性數(shù)據(jù),展現(xiàn)出令人驚艷的預(yù)測性能。
在多個(gè)公開基準(zhǔn)數(shù)據(jù)集的實(shí)驗(yàn)中,TiDE不僅精度超越了當(dāng)前最優(yōu)模型,而且在推理速度和訓(xùn)練效率上也領(lǐng)先于Transformer模型5-10倍以上。這種簡單高效的特點(diǎn)使TiDE非常適合應(yīng)用于工業(yè)級(jí)的大規(guī)模部署場景。
如果您對(duì)TiDE模型的原理和細(xì)節(jié)有進(jìn)一步的了解興趣,我們強(qiáng)烈推薦大家閱讀原論文(https://arxiv.org/pdf/2304.08424.pdf)。希望TiDE這一創(chuàng)新預(yù)測模型能為時(shí)間序列分析領(lǐng)域注入新的活力,為解決實(shí)際問題提供更多的可能性。
探索 TiDE
TiDE 這個(gè)名字看似生澀,其實(shí)就是" Time-series Dense Encoder "的英文縮寫。它的設(shè)計(jì)思路非常巧妙,摒棄了目前流行的轉(zhuǎn)換器(Transformer)結(jié)構(gòu),而是采用了編碼器-解碼器的框架,使用簡單的多層感知器(MLP)網(wǎng)絡(luò)來完成編碼和解碼的工作。
那它是如何工作的呢?首先,編碼器會(huì)將歷史的時(shí)間序列數(shù)據(jù)和相關(guān)的協(xié)變量(如節(jié)假日、促銷活動(dòng)等)輸入進(jìn)去,學(xué)習(xí)一個(gè)緊湊的表示向量,捕捉數(shù)據(jù)的內(nèi)在模式。接下來,解碼器會(huì)根據(jù)這個(gè)向量,結(jié)合已知的未來時(shí)間步的協(xié)變量,生成相應(yīng)的預(yù)測值。
TiDE的巧妙之處在于,它利用MLP的非線性映射能力來提取復(fù)雜特征,同時(shí)避免了轉(zhuǎn)換器的注意力計(jì)算,大幅提高了模型的訓(xùn)練和預(yù)測速度。事實(shí)上,在多個(gè)公開數(shù)據(jù)集的測試中,TiDE不僅精度超過了現(xiàn)有最佳模型,其運(yùn)算效率甚至比基于轉(zhuǎn)換器的模型快了5-10倍之多!
這種高效而精準(zhǔn)的特性,使得TiDE十分適合工業(yè)級(jí)的大規(guī)模部署場景。如果你對(duì)時(shí)間序列預(yù)測有研究興趣,不防一探 TiDE 模型的奧秘。
TiDE 的結(jié)構(gòu)
TiDE 的架構(gòu)如下圖所示。
TiDE 的結(jié)構(gòu)
從上圖我們可以看出,該模型將每個(gè)序列視為一個(gè)獨(dú)立通道,即每次只傳遞一個(gè)序列及其協(xié)變量。
我們還可以看到,該模型有三個(gè)主要組成部分:編碼器、解碼器和時(shí)序解碼器,它們都依賴于殘差塊結(jié)構(gòu)。
這張圖包含了很多信息,讓我們來更詳細(xì)地探討每個(gè)組件。
探索殘差塊
如前所述,殘差塊是 TiDE 架構(gòu)的基礎(chǔ)層。
殘差塊的組成
從上圖中,我們可以看到這是一個(gè)具有一個(gè)隱藏層和 ReLU 激活的 MLP。然后是一個(gè)剔除層、一個(gè)跳轉(zhuǎn)連接和最后的層歸一化步驟。
然后,這個(gè)組件會(huì)在整個(gè)網(wǎng)絡(luò)中重復(fù)使用,以進(jìn)行編碼、解碼和預(yù)測。
了解編碼器
在這一步中,模型會(huì)將時(shí)間序列的過去和協(xié)變因素映射到一個(gè)密集的表示中。
第一步是進(jìn)行特征投影。這就是利用殘差塊將動(dòng)態(tài)協(xié)變量(隨時(shí)間變化的外生變量)映射到低維投影中。
請(qǐng)記住,在進(jìn)行多元預(yù)測時(shí),我們需要特征的未來值。因此,模型必須處理回望窗口和水平序列。
這些序列可能會(huì)很長,因此,通過向低維空間投影,我們可以保持長度可控,并允許模型處理更長的序列,包括歷史窗口和預(yù)測范圍。
第二步是將序列的過去與其屬性以及過去和未來協(xié)變量的投影連接起來。然后將其發(fā)送給編碼器,編碼器就是一疊殘差塊。
因此,編碼器負(fù)責(zé)學(xué)習(xí)輸入的表示。這可以看作是一種學(xué)習(xí)嵌入。
完成后,嵌入將被發(fā)送到解碼器。
了解解碼器
在這里,解碼器負(fù)責(zé)接收編碼器的學(xué)習(xí)表示并生成預(yù)測。
第一步是密集解碼器,它也是由一疊殘差塊組成。它獲取編碼信息并輸出一個(gè)矩陣,然后輸入時(shí)序解碼器。
解碼輸出與預(yù)測特征堆疊,以捕捉未來協(xié)變量的直接影響。例如,節(jié)假日是準(zhǔn)時(shí)事件,會(huì)對(duì)某些時(shí)間序列產(chǎn)生重要影響。有了這種殘差聯(lián)系,模型就能捕捉并利用這些信息。
第二步是時(shí)空解碼器,在此生成預(yù)測結(jié)果。在這里,它只是一個(gè)輸出大小為 1 的殘差塊,這樣我們就能得到給定時(shí)間序列的預(yù)測結(jié)果。
現(xiàn)在,我們已經(jīng)了解了 TiDE 的每個(gè)關(guān)鍵組成部分,讓我們用 Python 將其應(yīng)用到一個(gè)小型預(yù)測項(xiàng)目中。
使用 TiDE 進(jìn)行預(yù)測
現(xiàn)在,讓我們?cè)谝粋€(gè)小型預(yù)測項(xiàng)目中應(yīng)用 TiDE,并將其性能與 TSMixer 進(jìn)行比較。
有趣的是,TSMixer 也是谷歌研究人員開發(fā)的基于 MLP 的多元預(yù)測架構(gòu),但它比 TiDE 早一個(gè)月發(fā)布。因此,我認(rèn)為在一個(gè)小實(shí)驗(yàn)中比較這兩種模型是很有趣的。
Etth1 數(shù)據(jù)集: https://github.com/zhouhaoyi/ETDataset。
這是文獻(xiàn)中廣泛使用的時(shí)間序列預(yù)測基準(zhǔn)。它與其他協(xié)變量一起跟蹤電力變壓器的每小時(shí)油溫,是進(jìn)行多元預(yù)測的絕佳場景。
導(dǎo)入庫并讀取數(shù)據(jù)
第一步自然是導(dǎo)入項(xiàng)目所需的庫并讀取數(shù)據(jù)。
雖然 TiDE 原始論文的源代碼在 上公開,但我還是選擇使用 Darts 中的實(shí)現(xiàn)。
GitHub: https://github.com/google-research/google-research/tree/master/tide)
它將為我們提供更大的靈活性,而且它還帶有超參數(shù)優(yōu)化功能,而這些功能在原始代碼庫中是沒有的。
導(dǎo)入 darts 以及其他標(biāo)準(zhǔn)軟件包。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from darts import TimeSeries
from darts.datasets import ETTh1Dataset
然后,我們就可以讀取數(shù)據(jù)了。Darts 提供了學(xué)術(shù)界常用的標(biāo)準(zhǔn)數(shù)據(jù)集,比如 Etth1 數(shù)據(jù)集。
series = ETTh1Dataset().load()
拆分?jǐn)?shù)據(jù),將最后 96 個(gè)時(shí)間步驟保留給測試集。
train, test = series[:-96], series[-96:]
訓(xùn)練 TiDE
要訪問 TiDE,只需從 darts 庫中導(dǎo)入它。在訓(xùn)練之前,還需要手動(dòng)縮放數(shù)據(jù)。這樣可以確保訓(xùn)練過程更快、更穩(wěn)定。
from darts.models.forecasting.tide_model import TiDEModel
from darts.dataprocessing.transformers import Scaler
train_scaler = Scaler()
scaled_train = train_scaler.fit_transform(train)
然后,初始化模型并指定其參數(shù)。在這里,我使用的優(yōu)化參數(shù)與論文中針對(duì)該特定數(shù)據(jù)集介紹的參數(shù)相同。
tide = TiDEModel(
input_chunk_length=720,
output_chunk_length=96,
num_encoder_layers=2,
num_decoder_layers=2,
decoder_output_dim=32,
hidden_size=512,
temporal_decoder_hidden=16,
use_layer_norm=True,
dropout=0.5,
random_state=42)
然后,就可以簡單地訓(xùn)練30 個(gè)epochs擬合模型了。
tide.fit(
scaled_train,
epochs=30
)
一旦模型完成訓(xùn)練,我們就可以訪問其預(yù)測結(jié)果。請(qǐng)注意,由于我們對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行了縮放,因此模型也會(huì)輸出縮放的預(yù)測結(jié)果。因此,我們必須反向轉(zhuǎn)換。
scaled_pred_tide = tide.predict(n=96)
pred_tide = train_scaler.inverse_transform(scaled_pred_tide)
完美!然后,我們就可以評(píng)估 TiDE 的性能了。
評(píng)估性能
為了評(píng)估模型的性能,我們將預(yù)測值和實(shí)際值存儲(chǔ)在一個(gè) DataFrame 中。
preds_df = pred_tide.pd_dataframe()
test_df = test.pd_dataframe()
我們還可以選擇將預(yù)測結(jié)果可視化。為了簡單起見,我只繪制了四列。
cols_to_plot = ['OT', 'HULL', 'MUFL', 'MULL']
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12,8))
for i, ax in enumerate(axes.flatten()):
col = cols_to_plot[i]
ax.plot(test_df[col], label='Actual', ls='-', color='blue')
ax.plot(preds_df[col], label='TiDE', ls='--', color='green')
ax.legend(loc='best')
ax.set_xlabel('Date')
ax.set_title(col)
plt.tight_layout()
fig.autofmt_xdate()
可視化 TiDE 預(yù)測
從上圖中我們可以看出,TiDE 對(duì)每個(gè)序列的預(yù)測都相當(dāng)出色。
當(dāng)然,評(píng)估性能的最佳方法是計(jì)算誤差指標(biāo),因此我們來計(jì)算一下平均絕對(duì)誤差(MAE)和平均平方誤差(MSE)。
from darts.metrics import mae, mse
tide_mae = mae(test, pred_tide)
tide_mse = mse(test, pred_tide)
print(tide_mae, tide_mse)
由此得出 MAE 為 1.19,MSE 為 3.58。
目前,還沒有現(xiàn)成的實(shí)現(xiàn)方法,因此我們必須手動(dòng)完成許多步驟。
現(xiàn)在,我們只報(bào)告 TSMixer 在 Etth1 數(shù)據(jù)集上對(duì) 96 個(gè)時(shí)間步長進(jìn)行多元預(yù)測的性能。
圖片
TiDE 和 TSMixer 對(duì) Etth1 數(shù)據(jù)集在 96 個(gè)時(shí)間步長范圍內(nèi)進(jìn)行多元預(yù)測的性能指標(biāo)。我們可以看到,TiDE 的性能最好。
我們使用了一個(gè)名為Etth1的標(biāo)準(zhǔn)數(shù)據(jù)集,在96個(gè)時(shí)間步長的范圍內(nèi)進(jìn)行評(píng)估。結(jié)果顯示,在這個(gè)數(shù)據(jù)集上,TiDE模型的平均絕對(duì)誤差(MAE)和均方誤差(MSE)都比TSMixer更低,這意味著TiDE在預(yù)測精度上表現(xiàn)更優(yōu)秀。
當(dāng)然,這只是一個(gè)有限的實(shí)驗(yàn)案例,并不能完全說明TiDE在任何情況下都會(huì)勝過TSMixer。事實(shí)上,TiDE可能是對(duì)TSMixer的一種漸進(jìn)式改進(jìn)。因此,對(duì)于每個(gè)具體的應(yīng)用場景,我們都應(yīng)當(dāng)分別評(píng)估并選擇最適合的模型。
總的來說,時(shí)間序列預(yù)測是一個(gè)錯(cuò)綜復(fù)雜的領(lǐng)域,沒有放之四海而皆準(zhǔn)的萬能模型。選擇合適的模型需要結(jié)合具體數(shù)據(jù)和應(yīng)用場景,并進(jìn)行反復(fù)試驗(yàn)和調(diào)優(yōu)。我們應(yīng)該保持開放和客觀的態(tài)度,虛心學(xué)習(xí)不同模型的優(yōu)缺點(diǎn),努力尋找最佳實(shí)踐。
寫在最后
TiDE(Time-series Dense Encoder)是一種用于時(shí)間序列預(yù)測的機(jī)器學(xué)習(xí)模型。它的全稱是時(shí)間序列密集編碼器,是一種基于多層感知機(jī)(MLP)結(jié)構(gòu)的模型,專門設(shè)計(jì)用于處理多變量、長期的時(shí)間序列預(yù)測問題。
TiDE模型的工作原理是,首先利用殘差模塊對(duì)協(xié)變量(影響預(yù)測目標(biāo)的其他相關(guān)變量)和歷史數(shù)據(jù)進(jìn)行編碼,將它們映射到一個(gè)內(nèi)部表示空間中。然后,模型會(huì)對(duì)這個(gè)學(xué)習(xí)到的內(nèi)部表示進(jìn)行解碼,從而生成對(duì)未來時(shí)間步的預(yù)測值。
由于TiDE模型結(jié)構(gòu)僅包含全連接層,因此相比循環(huán)神經(jīng)網(wǎng)絡(luò)等復(fù)雜模型,它的訓(xùn)練時(shí)間更短。但即便如此,在長期多步預(yù)測任務(wù)中,TiDE仍能取得很高的預(yù)測性能。
不過,針對(duì)不同的預(yù)測問題,模型的表現(xiàn)也會(huì)有所差異。因此,在實(shí)際應(yīng)用中,建議對(duì)TiDE以及其他潛在的模型方案進(jìn)行評(píng)估和測試,選擇最佳的方案。