SOFTS: 時間序列預測的最新模型以及Python使用示例
近年來,深度學習一直在時間序列預測中追趕著提升樹模型,其中新的架構已經逐漸為最先進的性能設定了新的標準。
這一切都始于2020年的N-BEATS,然后是2022年的NHITS。2023年,PatchTST和TSMixer被提出,最近的iTransformer進一步提高了深度學習預測模型的性能。
這是2024年4月《SOFTS: Efficient Multivariate Time Series Forecasting with Series-Core Fusion》中提出的新模型,采用集中策略來學習不同序列之間的交互,從而在多變量預測任務中獲得最先進的性能。
在本文中,我們詳細探討了SOFTS的體系結構,并介紹新的STar聚合調度(STAD)模塊,該模塊負責學習時間序列之間的交互。然后,我們測試將該模型應用于單變量和多變量預測場景,并與其他模型作為對比。
SOFTS介紹
SOFTS是 Series-cOre Fused Time Series的縮寫,背后的動機來自于長期多元預測對決策至關重要的認識:
首先我們一直研究Transformer的模型,它們試圖通過使用補丁嵌入和通道獨立等技術(如PatchTST)來降低Transformer的復雜性。但是由于通道獨立性,消除了每個序列之間的相互作用,因此可能會忽略預測信息。
iTransformer 通過嵌入整個序列部分地解決了這個問題,并通過注意機制處理它們。但是基于transformer的模型在計算上是復雜的,并且需要更多的時間來訓練非常大的數據集。
另一方面有一些基于mlp的模型。這些模型通常很快,并產生非常強的結果,但當存在許多序列時,它們的性能往往會下降。
所以出現了SOFTS:研究人員建議使用基于mlp的STAD模塊。由于是基于MLP的,所以訓練速度很快。并且STAD模塊,它允許學習每個序列之間的關系,就像注意力機制一樣,但計算效率更高。
SOFTS架構

在上圖中可以看到每個序列都是單獨嵌入的,就像在iTransformer 中一樣。
然后將嵌入發送到STAD模塊。每個序列之間的交互都是集中學習的,然后再分配到各個系列并融合在一起。
最后再通過線性層產生預測。
這個體系結構中有很多東西需要分析,我們下面更詳細地研究每個組件。
1、歸一化與嵌入
首先使用歸一化來校準輸入序列的分布。使用了可逆實例的歸一化(RevIn)。它將數據以單位方差的平均值為中心。然后每個系列分別進行嵌入,就像在iTransformer 模型。

在上圖中我們可以看到,嵌入整個序列就像應用補丁嵌入,其中補丁長度等于輸入序列的長度。
這樣,嵌入就包含了整個序列在所有時間步長的信息。
然后將嵌入式系列發送到STAD模塊。
2、STar Aggregate-Dispatch (STAD)
STAD模塊是soft模型與其他預測方法的真正區別。使用集中式策略來查找所有時間序列之間的相互作用。

嵌入的序列首先通過MLP和池化層,然后將這個學習到的表示連接起來形成核(上圖中的黃色塊表示)。
核構建好了以后就進入了“重復”和“連接”的步驟,在這個步驟中,核表示被分派給每個系列。

MLP和池化層未捕獲的信息還可以通過殘差連接添加到核表示中。然后在融合(fuse)操作的過程中,核表示及其對應系列的殘差都通過MLP層發送。最后的線性層采用STAD模塊的輸出來生成每個序列的最終預測。
與其他捕獲通道交互的方法(如注意力機制)相比,STAD模塊的主要優點之一是它降低了復雜性。
因為STAD模塊具有線性復雜度,而注意力機制具有二次復雜度,這意味著STAD在技術上可以更有效地處理具有多個序列的大型數據集。
下面我們來實際使用SOFTS進行單變量和多變量場景的測試。
使用SOFTS預測
這里,我們使用 Electricity Transformer dataset 數據集。
這個數據集跟蹤了中國某省兩個地區的變壓器油溫。每小時和每15分鐘采樣一個數據集,總共有四個數據集。
我門使用neuralforecast庫中的SOFTS實現,這是官方認可的庫,并且這樣我們可以直接使用和測試不同預測模型的進行對比。
在撰寫本文時,SOFTS還沒有集成在的neuralforecast版本中,所以我們需要使用源代碼進行安裝。
pip install git+https://github.com/Nixtla/neuralforecast.git然后就是從導入包開始。使用datasetsforecast以所需格式加載數據集,以便使用neuralforecast訓練模型,并使用utilsforecast評估模型的性能。這就是我們使用neuralforecast的原因,因為他都是一套的
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from datasetsforecast.long_horizon import LongHorizon
from neuralforecast.core import NeuralForecast
from neuralforecast.losses.pytorch import MAE, MSE
from neuralforecast.models import SOFTS, PatchTST, TSMixer, iTransformer
from utilsforecast.losses import mae, mse
from utilsforecast.evaluation import evaluate編寫一個函數來幫助加載數據集,以及它們的標準測試大小、驗證大小和頻率。
def load_data(name):
if name == "ettm1":
Y_df, *_ = LongHorizon.load(directory='./', group='ETTm1')
Y_df = Y_df[Y_df['unique_id'] == 'OT'] # univariate dataset
Y_df['ds'] = pd.to_datetime(Y_df['ds'])
val_size = 11520
test_size = 11520
freq = '15T'
elif name == "ettm2":
Y_df, *_ = LongHorizon.load(directory='./', group='ETTm2')
Y_df['ds'] = pd.to_datetime(Y_df['ds'])
val_size = 11520
test_size = 11520
freq = '15T'
return Y_df, val_size, test_size, freq然后就可以對ETTm1數據集進行單變量預測。
1、單變量預測
加載ETTm1數據集,將預測范圍設置為96個時間步長。
可以測試更多的預測長度,但我們這里只使用96。
Y_df, val_size, test_size, freq = load_data('ettm1')
horizon = 96然后初始化不同的模型,我們將soft與TSMixer, iTransformer和PatchTST進行比較。
所有模型都使用的默認配置將最大訓練步數設置為1000,如果三次后驗證損失沒有改善,則停止訓練。
models = [
SOFTS(h=horizon, input_size=3*horizon, n_series=1, max_steps=1000, early_stop_patience_steps=3),
TSMixer(h=horizon, input_size=3*horizon, n_series=1, max_steps=1000, early_stop_patience_steps=3),
iTransformer(h=horizon, input_size=3*horizon, n_series=1, max_steps=1000, early_stop_patience_steps=3),
PatchTST(h=horizon, input_size=3*horizon, max_steps=1000, early_stop_patience_steps=3)
]然后初始化NeuralForecast對象訓練模型。并使用交叉驗證來獲得多個預測窗口,更好地評估每個模型的性能。
nf = NeuralForecast(models=models, freq=freq)
nf_preds = nf.cross_validation(df=Y_df, val_size=val_size, test_size=test_size, n_windows=None)
nf_preds = nf_preds.reset_index()評估計算了每個模型的平均絕對誤差(MAE)和均方誤差(MSE)。因為之前的數據是縮放的,因此報告的指標也是縮放的。
ettm1_evaluation = evaluate(df=nf_preds, metrics=[mae, mse], models=['SOFTS', 'TSMixer', 'iTransformer', 'PatchTST'])
從上圖可以看出,PatchTST的MAE最低,而softts、TSMixer和PatchTST的MSE是一樣的。在這種特殊情況下,PatchTST仍然是總體上最好的模型。
這并不奇怪,因為PatchTST在這個數據集中是出了名的好,特別是對于單變量任務。下面我們開始測試多變量場景。
2、多變量預測
使用相同的load_data函數,我們現在為這個多變量場景使用ETTm2數據集。
Y_df, val_size, test_size, freq = load_data('ettm2')
horizon = 96然后簡單地初始化每個模型。我們只使用多變量模型來學習序列之間的相互作用,所以不會使用PatchTST,因為它應用通道獨立性(意味著每個序列被單獨處理)。
然后保留了與單變量場景中相同的超參數。只將n_series更改為7,因為有7個時間序列相互作用。
models = [SOFTS(h=horizon, input_size=3*horizon, n_series=7, max_steps=1000, early_stop_patience_steps=3, scaler_type='identity', valid_loss=MAE()),
TSMixer(h=horizon, input_size=3*horizon, n_series=7, max_steps=1000, early_stop_patience_steps=3, scaler_type='identity', valid_loss=MAE()),
iTransformer(h=horizon, input_size=3*horizon, n_series=7, max_steps=1000, early_stop_patience_steps=3, scaler_type='identity', valid_loss=MAE())]訓練所有的模型并進行預測。
nf = NeuralForecast(models=models, freq='15min')
nf_preds = nf.cross_validation(df=Y_df, val_size=val_size, test_size=test_size, n_windows=None)
nf_preds = nf_preds.reset_index()最后使用MAE和MSE來評估每個模型的性能。
ettm2_evaluation = evaluate(df=nf_preds, metrics=[mae, mse], models=['SOFTS', 'TSMixer', 'iTransformer'])
上圖中可以看到到當在96的水平上預測時,TSMixer large在ETTm2數據集上的表現優于iTransformer和soft。
雖然這與soft論文的結果相矛盾,這是因為我們沒有進行超參數優化,并且使用了96個時間步長的固定范圍。
這個實驗的結果可能不太令人印象深刻,我們只在固定預測范圍的單個數據集上進行了測試,所以這不是SOFTS性能的穩健基準,同時也說明了SOFTS在使用時可能需要更多的時間來進行超參數的優化。
總結
SOFTS是一個很有前途的基于mlp的多元預測模型,STAD模塊是一種集中式方法,用于學習時間序列之間的相互作用,其計算強度低于注意力機制。這使得模型能夠有效地處理具有許多并發時間序列的大型數據集。
雖然在我們的實驗中,SOFTS的性能可能看起來有點平淡無奇,但請記住,這并不代表其性能的穩健基準,因為我們只在固定視界的單個數據集上進行了測試。
但是SOFTS的思路還是非常好的,比如使用集中式學習時間序列之間的相互作用,并且使用低強度的計算來保證數據計算的效率,這都是值得我們學習的地方。
并且每個問題都需要其獨特的解決方案,所以將SOFTS作為特定場景的一個測試選項是一個明智的選擇。


































