測的分解與重構(gòu)方法)
簡介一份關(guān)于鐵路車站月度客流發(fā)送量預(yù)測的學(xué)術(shù)論文面向軌道交通、機器學(xué)習(xí)與數(shù)據(jù)建模方向的研究者及從業(yè)者。該研究提出基于變分模態(tài)分解與反向傳播神經(jīng)網(wǎng)絡(luò)的組合模型用于處理非線性、非平穩(wěn)的客流發(fā)送數(shù)據(jù)并與基于經(jīng)驗?zāi)B(tài)分解的反向傳播神經(jīng)網(wǎng)絡(luò)、極限學(xué)習(xí)機等基準(zhǔn)模型對比驗證該組合模型預(yù)測精度最高可為列車開行對數(shù)和運輸管理提供決策依據(jù)。論文為便攜式文檔格式整個資源包僅含一個文件數(shù)據(jù)量約一點六七兆字節(jié)。內(nèi)容涵蓋模型構(gòu)建、變分模態(tài)分解與經(jīng)驗?zāi)B(tài)分解原理、算法對比、實驗指標(biāo)分析并以蘭州西站日發(fā)送客流為原始數(shù)據(jù)建立了滾動月度預(yù)測機制案例完整便于論文參考、算法復(fù)現(xiàn)或課程學(xué)習(xí)。已有一百五十人學(xué)習(xí)對希望掌握神經(jīng)網(wǎng)絡(luò)與信號分解組合建模、提升客流預(yù)測精度者具有實用參考價值。1. 為什么月度客流預(yù)測從BP直接上手容易翻車鐵路車站的月度客流發(fā)送量是一種典型的非平穩(wěn)、強周期、帶節(jié)假日脈沖的時間序列。春運、暑運、小長假、學(xué)生流疊加在一起序列里同時混著趨勢、季節(jié)、脈沖和噪聲。若直接把原始序列丟給BP神經(jīng)網(wǎng)絡(luò)網(wǎng)絡(luò)要在一個模型里同時擬合這幾種性質(zhì)完全不同的成分結(jié)果往往是低頻趨勢學(xué)得像高頻波動卻嚴(yán)重失真訓(xùn)練集上R2不錯一到預(yù)測月就偏移。VMD-BP的思路是從源頭把這個問題拆開先用VMD變分模態(tài)分解把原始序列按頻率分層拆成幾個相對平穩(wěn)的子序列再對每個子序列單獨建BP最后把預(yù)測結(jié)果疊加回真實尺度。這種“先分解、后預(yù)測、再重構(gòu)”的組合方式本質(zhì)上是用信號處理簡化了神經(jīng)網(wǎng)絡(luò)的擬合目標(biāo)。適合的人群是運輸統(tǒng)計、交通規(guī)劃、車站調(diào)度方向的算法工程師以及任何手上握著月度客流、電力負荷、水位這類非平穩(wěn)序列、需要把預(yù)測精度再往前推一步的從業(yè)者。2. VMD變分模態(tài)分解的分解邏輯與關(guān)鍵參數(shù)K值2.1 VMD為什么比EMD更適合做客流預(yù)處理經(jīng)驗?zāi)B(tài)分解EMD在工程里被用了很多年但它的分解過程是基于極值包絡(luò)遞歸篩分的對噪聲敏感容易出現(xiàn)模態(tài)混疊同一個頻率成分被切到兩個IMF里。VMD變分模態(tài)分解換了一套數(shù)學(xué)框架它把分解問題定義成一個約束變分問題目標(biāo)是在所有模態(tài)之和等于原始信號的約束下讓每個模態(tài)的估計帶寬之和最小。每個模態(tài)通過Hilbert變換得到解析信號再預(yù)估一個中心頻率最終在頻域里迭代更新出K個有限帶寬的IMF。對月度客流這類長度短通常只有幾十到一百多個點、信噪比不高的序列來說VMD有兩個實測優(yōu)勢。第一它的分解結(jié)果是基于頻帶劃分的模態(tài)混疊比EMD少第二它的模態(tài)個數(shù)K是顯式參數(shù)可以直接控制分解粒度能拆出幾條IMF就拆幾條不依賴極值點的自然分布。需要說明的是VMD在工程預(yù)測任務(wù)里指的就是變分模態(tài)分解和圖形渲染中間件、動作捕捉文件格式里的VMD縮寫沒有關(guān)系檢索資料時注意區(qū)分。2.2 VMD的數(shù)學(xué)目標(biāo)和參數(shù)含義VMD的求解目標(biāo)可以簡化理解為對每個模態(tài)分量求Hilbert變換構(gòu)造解析信號乘上指數(shù)項把頻譜搬到基帶然后計算梯度平方范數(shù)作為帶寬估計最小化各模態(tài)帶寬之和并且滿足各模態(tài)相加等于原始信號。在Python里做VMD分解常見做法是使用vmdpy庫調(diào)用代碼非常簡短from vmdpy import VMD import numpy as np # series: (N,) 的一維月度客流序列 # K: 分解模態(tài)個數(shù), alpha: 帶寬懲罰因子, tau: 噪聲容忍度 # DC: 是否將第一個模態(tài)作為直流分量, init: 中心頻率初始化方式, tol: 收斂容差 u, u_hat, omega VMD(series, K4, alpha2000, tau0, DC0, init1, tol1e-7) # u 的形狀是 (K, N)u[0] 是最低頻模態(tài)u[-1] 是最高頻模態(tài) reconstructed u.sum(axis0) print(重構(gòu)誤差:, np.max(np.abs(reconstructed - series)))這段代碼里返回值u是分解出的K個模態(tài)omega保存迭代過程中各模態(tài)中心頻率的變化最后一行用來驗證分解是否完整。重構(gòu)誤差通常在1e-6級別如果明顯偏大說明tau設(shè)置不當(dāng)或迭代沒有收斂。各參數(shù)的實際工程含義可以參照下表參數(shù)取值作用與調(diào)參方向K4~6模態(tài)個數(shù)。K過小會欠分解趨勢和周期混在一起K過大會過分解出現(xiàn)中心頻率接近的冗余模態(tài)alpha1000~4000帶寬懲罰因子。alpha越大模態(tài)帶寬越窄適合信號較光滑的序列alpha越小模態(tài)越寬能吸收更多細節(jié)tau0噪聲容忍度。客流序列一般設(shè)0表示嚴(yán)格重構(gòu)若信號噪聲強可調(diào)大以犧牲重構(gòu)精度換取穩(wěn)定性DC0置1時強制第一個模態(tài)為原始序列的直流分量均值趨勢客流序列帶趨勢但不恒定通常設(shè)0init1中心頻率初始化方式1為均勻分布隨機初始化0為全零初始化一般保持默認3. BP神經(jīng)網(wǎng)絡(luò)的輸入構(gòu)造與網(wǎng)絡(luò)結(jié)構(gòu)設(shè)計3.1 分解之后為什么要對每個模態(tài)單獨建BPVMD輸出的是K個窄帶子序列每個序列的頻率成分相對單純。對每個子序列分別建BP本質(zhì)上是讓每個網(wǎng)絡(luò)只學(xué)一個窄頻帶的時間演變規(guī)律。低頻模態(tài)學(xué)趨勢外推中頻模態(tài)學(xué)季節(jié)周期高頻模態(tài)學(xué)節(jié)假日脈沖和噪聲形態(tài)各網(wǎng)絡(luò)分工明確互不干擾。如果把分解后的K個模態(tài)直接拼接成多維輸入喂給同一個BP相當(dāng)于又把頻率辨識的任務(wù)丟回給網(wǎng)絡(luò)分解的意義就丟失了。常見的實現(xiàn)方式有三種。第一種是K個模態(tài)各自訓(xùn)練獨立的BP預(yù)測值直接相加第二種是先對高頻模態(tài)做閾值降噪把幅值小于某個比例的模態(tài)直接歸零再相加第三種是把低頻模態(tài)用回歸模型外推只對高頻模態(tài)用BP。鐵路月度客流預(yù)測的常見方案是第一種實現(xiàn)簡單效果穩(wěn)定。3.2 輸入窗口長度和訓(xùn)練樣本的構(gòu)造月度客流序列每月只有一個點樣本天然稀少。即便有10年數(shù)據(jù)也只有120個樣本BP又是數(shù)據(jù)消耗型模型所以輸入特征不能貪多。最常用的做法是滑動窗口回歸用前p個月的發(fā)送量預(yù)測當(dāng)月發(fā)送量每個窗口構(gòu)成一個樣本。import numpy as np def make_samples(modal_series, lookback3): X, y [], [] for i in range(len(modal_series) - lookback): X.append(modal_series[i:i lookback]) y.append(modal_series[i lookback]) return np.array(X), np.array(y)lookback取3到4個月在工程上比較穩(wěn)妥。月度客流的一階自相關(guān)很強三個月內(nèi)的近期客流變化已經(jīng)包含了短趨勢信息把lookback拉到12個月雖然形式上引入了年周期但會讓樣本量直接縮水120個月的數(shù)據(jù)去掉前12個月只剩108個樣本模型很容易過擬合。如果非要引入年周期更推薦把去年同期值作為一個額外特征拼在窗口后面而不是簡單拉長窗口。3.3 BP結(jié)構(gòu)圖與隱含層神經(jīng)元選擇單個模態(tài)的BP網(wǎng)絡(luò)結(jié)構(gòu)很簡單三到四層足夠輸入層3個節(jié)點t-3期、t-2期、t-1期客流→ 隱含層8個節(jié)點tanh激活→ 輸出層1個節(jié)點t期預(yù)測值。隱含層神經(jīng)元個數(shù)沒有統(tǒng)一標(biāo)準(zhǔn)。經(jīng)驗公式是sqrt(mn)a其中m是輸入維度n是輸出維度a取1到10之間的整數(shù)。對lookback3的單輸出任務(wù)理論范圍在3到13之間工程上取6到10不容易出現(xiàn)欠擬合或過擬合。神經(jīng)元太多高頻模態(tài)的訓(xùn)練集誤差很低測試集上反而震蕩明顯。from sklearn.neural_network import MLPRegressor model MLPRegressor( hidden_layer_sizes(8,), # 單隱層8個神經(jīng)元樣本量少時不建議再加第二層 activationtanh, # tanh 比 relu 在窄幅時間序列上收斂更平穩(wěn) solverlbfgs, # 小樣本下 lbfgs 收斂快于 adam max_iter3000, random_state42 ) model.fit(X_train, y_train)這里solver選lbfgs是因為每個模態(tài)的訓(xùn)練集樣本量通常不到100條批量梯度優(yōu)化的線性搜索策略比隨機梯度下降更穩(wěn)。如果數(shù)據(jù)量到了幾千條則可以換回adam。還有個細節(jié)是激活函數(shù)用tanh時間序列的模態(tài)分量在歸一化后既有正負區(qū)間振蕩tanh的梯度變化能保留正負方向的對稱性relu會把負半軸信息直接截斷在低頻趨勢上容易丟失趨勢方向信息。3.4 中間章注意訓(xùn)練集和測試集必須順序切分處理時間序列時絕不能直接調(diào)用train_test_split并random_shuffle高頻模態(tài)的相鄰樣本間有強相關(guān)關(guān)系打亂后訓(xùn)練集和測試集的分布幾乎一致評估結(jié)果會虛高。正確做法是按時間先后切分train_size int(len(X) * 0.7) X_train, X_test X[:train_size], X[train_size:] y_train, y_test y[:train_size], y[train_size:]如果數(shù)據(jù)跨越了完整的客流周期建議保證訓(xùn)練集至少覆蓋兩個完整年份這樣季節(jié)模態(tài)才能學(xué)到完整的周期形態(tài)。4. VMD-BP完整預(yù)測流程分解、訓(xùn)練、重構(gòu)的實驗配置4.1 整體流程與評價指標(biāo)一個可復(fù)現(xiàn)的VMD-BP月度客流預(yù)測流程按順序由五個模塊構(gòu)成原始數(shù)據(jù)歸一化、VMD分解、逐模態(tài)構(gòu)造滑動窗口樣本、逐模態(tài)訓(xùn)練BP、模態(tài)預(yù)測值疊加并反歸一化。預(yù)測效果評估在真實尺度上進行不要在歸一化后的區(qū)間里判斷好壞。誤差指標(biāo)最常用的是MAPE平均絕對百分比誤差、RMSE均方根誤差和R2決定系數(shù)。MAPE能直觀反映預(yù)測偏差的百分比但旺季值大、淡季值小時MAPE會被旺季樣本主導(dǎo)所以要同時報RMSE。下表是結(jié)果報告中應(yīng)包含的指標(biāo)信息指標(biāo)公式含義結(jié)果判定方向MAPEmean(abs((y_true-y_pred)/y_true))小于5%為優(yōu)秀5%-10%為可用RMSEsqrt(mean((y_true-y_pred)^2))對大誤差敏感關(guān)注客流高峰月份的偏離R21 - SS_res/SS_tot越接近1越好但月度樣本下0.9以上的結(jié)果要警惕過擬合4.2 模態(tài)處理細節(jié)最低頻成分單獨外推直接對K個模態(tài)逐個訓(xùn)練BP并疊加能跑通但最低頻模態(tài)往往表現(xiàn)出近乎線性的趨勢BP學(xué)習(xí)這種單調(diào)趨勢需要較高的訓(xùn)練步數(shù)且序列末端容易外推過頭。一個實用技巧是對最低頻模態(tài)用一階差分后訓(xùn)練BP預(yù)測時累加回原始量級。差分之后原趨勢變?yōu)榻瓢自肼曅蛄蠦P的擬合目標(biāo)更平穩(wěn)外推誤差反而更低。# 最低頻模態(tài)做一階差分后再進BP其余模態(tài)正常訓(xùn)練 diff_low np.diff(u[0]) # 訓(xùn)練過程同普通模態(tài)預(yù)測得到 diff_pred last_value u[0][-1] low_freq_pred last_value np.cumsum(diff_pred)這類操作的邏輯是VMD把非平穩(wěn)序列分解后各模態(tài)的平穩(wěn)性已經(jīng)大幅提升。最低頻成分雖然平穩(wěn)度改善明顯但依然帶單調(diào)性差分可以把它轉(zhuǎn)化成均值為常數(shù)的序列等于在BP前面又做了一層輸入預(yù)處理。4.3 MATLAB環(huán)境下的對應(yīng)實現(xiàn)做鐵路運輸方向研究時MATLAB也是高頻選擇。MATLAB內(nèi)置的vmd函數(shù)可以直接調(diào)用分解部分BP部分常用feedforwardnet或newff實現(xiàn)。核心流程對應(yīng)關(guān)系如下% 分解過程x是列車座位數(shù)或發(fā)送量的歷史月度數(shù)據(jù) [imf, ~, info] vmd(x, NumIMF, 4); % 對第i個IMF訓(xùn)練BP網(wǎng)絡(luò) net feedforwardnet(8, trainlm); net train(net, X_train_i, y_train_i); % 第i個IMF的預(yù)測值 y_pred_i net(X_test_i);對月度數(shù)據(jù)這樣的中小規(guī)模樣本MATLAB的trainlmLevenberg-Marquardt收斂效果通常好于traingd。與Python的vmdpy對比MATLAB的vmd輸出順序在默認參數(shù)下也同樣是低頻在前、高頻在后方便直接做最低頻差分處理。4.4 歸一化范圍選擇每個模態(tài)在進入BP之前需要單獨做歸一化。高頻模態(tài)的幅值可能只有低頻模態(tài)的十分之一到百分之一如果整體歸一化高頻成分的網(wǎng)絡(luò)輸入在數(shù)值上被低頻淹沒訓(xùn)練時梯度會被低頻主導(dǎo)高頻信息就丟了。from sklearn.preprocessing import MinMaxScaler scalers [] X_trains, y_trains [], [] for i in range(K): scaler_x MinMaxScaler(feature_range(-1, 1)) scaler_y MinMaxScaler(feature_range(-1, 1)) X_trains.append(scaler_x.fit_transform(X[i])) y_trains.append(scaler_y.fit_transform(y[i].reshape(-1, 1)).ravel()) scalers.append((scaler_x, scaler_y))feature_range取(-1, 1)而不是(0, 1)是為了讓零值落在區(qū)間中間匹配tanh激活函數(shù)在零點附近梯度最大的特性讓網(wǎng)絡(luò)在訓(xùn)練初期有更明顯的權(quán)重更新幅度。5. 預(yù)測效果驗證中心頻率觀察法與對比實驗的實操要點訓(xùn)練結(jié)束后先驗證VMD分解質(zhì)量再判斷BP訓(xùn)練是否正常不要直接跳到指標(biāo)對比。第一步看分解出來的中心頻率是否合理。把omega的最后一列打出來也就是迭代收斂后的各模態(tài)中心頻率for K in range(3, 8): u, u_hat, omega VMD(series, KK, alpha2000, tau0, DC0, init1, tol1e-7) centers omega[-1, :] # 各模態(tài)最終中心頻率 print(fK{K}: centers{centers})如果K5和K6時有兩到三個中心頻率擠在同一個數(shù)值附近說明存在過分解那些頻率相近的模態(tài)沒有實際區(qū)分度。比較不同K值下的中心頻率分布后再確定最終K這是工程上選擇模態(tài)數(shù)最直接的手段不需要依賴信息熵等復(fù)雜準(zhǔn)則。K4到6是月度客流序列的常見取值區(qū)間若序列只有60個月左右的數(shù)據(jù)K取4更穩(wěn)妥分解出的模態(tài)數(shù)太多會讓單個模態(tài)有效信息過少。第二步做對照實驗。K1時VMD-BP退化為直接用BP預(yù)測原始序列這個設(shè)置天然是一個baseline。對照實驗建議設(shè)計三組原始序列直接BP、EMD-BP、VMD-BP。VMD-BP相對第一組的優(yōu)勢主要落在MAPE和RMSE上相對第二組的優(yōu)勢落在高頻段的模態(tài)混疊減少上。報告結(jié)果時統(tǒng)一用同一段測試集時間窗比如最后一個完整年度逐月滾動預(yù)測。若VMD-BP在訓(xùn)練集指標(biāo)遠好于測試集先懷疑每個模態(tài)獨立訓(xùn)練是否疊加放大誤差。一個模態(tài)的過擬合可能被其他模態(tài)修正但三個以上模態(tài)同時過擬合時疊加結(jié)果通常會在測試集尾部出現(xiàn)明顯的震蕩放大。最后可以再給預(yù)測值加一道后處理對疊加結(jié)果做一次窗口為3的簡單滑動平均削掉極端跳變點。這個操作能把MAPE再壓低零點幾個百分點但注意不要把平滑窗口拉太長否則節(jié)假日峰值的預(yù)測結(jié)果也會被抹平客流高峰期恰恰是預(yù)測最需要準(zhǔn)確的時候。月度客流預(yù)測的價值不在平均誤差上而在旺季的峰值預(yù)判上分解、建模和后處理都是圍繞把峰值的相位和幅度擬合準(zhǔn)來做的。本文還有配套的精品資源點擊獲取