現(xiàn)家庭用電預(yù)測(cè):特征工程與避坑指南)
簡(jiǎn)介這是一份機(jī)器學(xué)習(xí)回歸算法實(shí)戰(zhàn)資源面向數(shù)據(jù)科學(xué)初學(xué)者與需要完成課程項(xiàng)目的學(xué)生旨在解決家庭用電量預(yù)測(cè)問題。資源系統(tǒng)覆蓋線性回歸、多項(xiàng)式回歸、決策樹回歸、隨機(jī)森林回歸與支持向量回歸等主流算法并涉及缺失值處理、異常值檢測(cè)、標(biāo)準(zhǔn)化、特征工程及時(shí)間序列分析同時(shí)展示MSE、RMSE、R2等評(píng)估指標(biāo)的使用。壓縮包共4個(gè)Python腳本0205家庭用電預(yù)測(cè).py按算法難度遞進(jìn)編排適合對(duì)照調(diào)試、對(duì)比不同模型效果整體大小僅9KB輕量無依賴負(fù)擔(dān)。已有262人下載學(xué)習(xí)適合用于入門實(shí)踐、作業(yè)參考或算法原理驗(yàn)證可幫助讀者快速跑通回歸建模全流程并理解各模型在實(shí)際數(shù)據(jù)中的適用場(chǎng)景與調(diào)參思路。1. 家庭用電預(yù)測(cè)一個(gè)被低估的回歸問題切入點(diǎn)月初看到電費(fèi)單才后悔上月空調(diào)沒節(jié)制這是絕大多數(shù)家庭的常態(tài)。但如果你手里有一套智能電表或者能讀到家庭總閘的功率數(shù)據(jù)完全可以把「后悔」變成「預(yù)判」用機(jī)器學(xué)習(xí)回歸算法基于過去一段時(shí)間的用電曲線、時(shí)間戳和天氣特征預(yù)測(cè)未來一小時(shí)甚至未來一天的家庭用電量。這背后就是典型的回歸任務(wù)——輸入是時(shí)間、歷史負(fù)荷、溫度等特征輸出是一個(gè)連續(xù)數(shù)值未來某個(gè)時(shí)刻的用電功率。這個(gè) zip 包標(biāo)題里的「回歸算法實(shí)現(xiàn)家庭用電預(yù)測(cè)」拆開看就是三件事把家庭用電數(shù)據(jù)整理成監(jiān)督學(xué)習(xí)樣本、構(gòu)建能擬合用電曲線的回歸模型、以及把預(yù)測(cè)結(jié)果落到能用的場(chǎng)景里。適合誰去做手里有計(jì)量數(shù)據(jù)、想給自家或某棟樓做用電分析的開發(fā)者以及剛?cè)腴T機(jī)器學(xué)習(xí)、想找一個(gè)不涉及圖像和文本的干凈回歸案例來練手的人。這類問題的好處是數(shù)據(jù)容易理解、特征可以自己構(gòu)造、評(píng)估指標(biāo)直觀翻車點(diǎn)卻不少下面按我實(shí)際做過的路線來講。2. 為什么家庭用電預(yù)測(cè)適合用回歸算法問題定義與特征構(gòu)造2.1 先定性這是回歸任務(wù)不是分類任務(wù)家庭用電預(yù)測(cè)的目標(biāo)是給出未來時(shí)刻的功率數(shù)值比如「15 分鐘后這棟房子大概用 1.8 kW」。這會(huì)讓人猶豫能不能把用電量分成「高/中/低」三檔做成分類能做但代價(jià)很大——分類會(huì)丟掉用電強(qiáng)度的連續(xù)信息當(dāng)你需要判斷「要不要開熱水器、會(huì)不會(huì)超容量」時(shí)分類結(jié)果沒法給出精確參考。回歸輸出的是一個(gè)連續(xù)值能直接和電表讀數(shù)、電網(wǎng)容量、電費(fèi)單價(jià)做算術(shù)運(yùn)算這是它在用電場(chǎng)景里的根本優(yōu)勢(shì)。另外一類選擇是時(shí)序模型LSTM、GRU它們確實(shí)能捕捉長(zhǎng)距離依賴但對(duì)數(shù)據(jù)量和訓(xùn)練調(diào)參的要求高得多家庭用電數(shù)據(jù)往往只有幾個(gè)月到一兩年的粒度樣本量不大樹模型和線性模型在這種規(guī)模下更容易穩(wěn)定出效果。我見過某開發(fā)者用一萬多條小時(shí)級(jí)記錄去訓(xùn) LSTM結(jié)果比隨機(jī)森林還差問題就出在樣本太少、特征時(shí)序沒構(gòu)造好而不是模型不夠先進(jìn)?;貧w算法在這個(gè)規(guī)模下是性價(jià)比最高的起點(diǎn)。2.2 特征設(shè)計(jì)用電預(yù)測(cè)的勝負(fù)手在特征不在模型用電曲線的規(guī)律性很強(qiáng)晚上高、白天低、工作日和周末不一樣、夏天開空調(diào)和冬天開暖氣也不一樣。這些規(guī)律沒法直接喂給模型必須轉(zhuǎn)成特征。我一般把特征拆成三組。第一組是時(shí)間特征。小時(shí)數(shù)0~23、星期幾0~6、是否周末、是否節(jié)假日這幾列能幫模型區(qū)分不同時(shí)段的用電模式。時(shí)間特征要用數(shù)值編碼小時(shí)可以同時(shí)用周期編碼sin/cos因?yàn)?23 點(diǎn)和 0 點(diǎn)其實(shí)相鄰直接喂「23」和「0」兩個(gè)數(shù)字線性模型會(huì)以為它們差得很遠(yuǎn)。第二組是滯后特征過去 1 小時(shí)、24 小時(shí)、168 小時(shí)即一周前同一時(shí)刻的用電量。家庭用電有很強(qiáng)的日周期和周周期滯后特征是預(yù)測(cè)準(zhǔn)確率的最大貢獻(xiàn)者。第三組是滾動(dòng)統(tǒng)計(jì)特征過去 6 小時(shí)均值、過去 24 小時(shí)最大值、用電量標(biāo)準(zhǔn)差這些能刻畫最近的用電趨勢(shì)和波動(dòng)水平。外部環(huán)境特征也不能忽略溫度和濕度對(duì)空調(diào)/暖氣負(fù)荷影響很大。常見做法是把氣象站發(fā)布的逐小時(shí)溫度、濕度按時(shí)間戳 join 進(jìn)來同時(shí)把體感溫度或「當(dāng)日最高溫」這類衍生變量一起放進(jìn)去。如果拿不到氣象數(shù)據(jù)就退而求其次用「日期序號(hào)」從數(shù)據(jù)集起點(diǎn)算起的天數(shù)讓模型自己學(xué)季節(jié)性趨勢(shì)——效果會(huì)差一點(diǎn)但至少能捕捉大方向。2.3 評(píng)估指標(biāo)看 MAE、RMSE更要把誤差換算成「度電」回歸模型的評(píng)估不能用準(zhǔn)確率常用的是 MAE、RMSE、MAPE。MAE 是平均絕對(duì)誤差單位是 kW直接解釋為「平均每次預(yù)測(cè)偏了多少千瓦」RMSE 對(duì)大誤差懲罰更重適合你特別在意峰值預(yù)測(cè)不準(zhǔn)的場(chǎng)景MAPE 把誤差歸一化成百分比方便和不同用電量級(jí)別的家庭對(duì)比。我自己會(huì)額外算一個(gè)「誤差電量」如果預(yù)測(cè)值比實(shí)際值平均高 0.2 kW持續(xù)一小時(shí)就是 0.2 度電乘以電費(fèi)單價(jià)就能估算預(yù)測(cè)誤差帶來的經(jīng)濟(jì)損失。這對(duì)說服別人接受你的模型很有用——用「誤差造成的電費(fèi)偏差」比單純報(bào) RMSE 更直觀。需要留意的是MAPE 在用電量接近 0 的深夜時(shí)段會(huì)爆炸因?yàn)榉帜柑∷栽u(píng)估時(shí)要么把深夜樣本單獨(dú)看要么在 MAPE 計(jì)算公式里給分母加一個(gè)平滑項(xiàng)。3. 把用電數(shù)據(jù)轉(zhuǎn)成回歸樣本從原始表到可訓(xùn)練數(shù)據(jù)集3.1 數(shù)據(jù)清洗與重采樣先用對(duì)粒度再談模型家庭用電原始數(shù)據(jù)通常是一條條功率記錄來自智能插座或電表間隔可能是秒級(jí)也可能不均勻。訓(xùn)練回歸模型前要先把數(shù)據(jù)重采樣成統(tǒng)一粒度我一般用小時(shí)粒度——預(yù)測(cè)未來 1~24 小時(shí)的需求小時(shí)級(jí)足夠分鐘級(jí)反而會(huì)讓訓(xùn)練集膨脹、收益卻很小。重采樣時(shí)注意用電量在 15 分鐘內(nèi)的均值比瞬時(shí)值穩(wěn)定得多所以優(yōu)先用均值聚合而不是直接取某一條記錄。import pandas as pd df pd.read_csv(household_power.csv, parse_dates[timestamp]) df.set_index(timestamp, inplaceTrue) # 統(tǒng)一成小時(shí)粒度用電功率取均值缺失值用前向填充 hourly df[power].resample(1h).mean() hourly hourly.fillna(methodffill) # 只保留連續(xù)且完整的時(shí)間范圍去掉頭部和尾部不完整的片段 hourly hourly.loc[2022-01-01:2023-12-31] print(hourly.describe())這段代碼的用途是把任意間隔的原始記錄轉(zhuǎn)成時(shí)間索引對(duì)齊的小時(shí)序列。前向填充能處理短時(shí)間缺失但如果某段連續(xù)缺失超過數(shù)小時(shí)前向填充會(huì)讓模型學(xué)到「用電量一直不變」的假規(guī)律所以我在代碼里限制了時(shí)間范圍把不完整的首尾切掉。resample 的規(guī)則里1h是按小時(shí)對(duì)齊如果你的數(shù)據(jù)來自不同時(shí)區(qū)先統(tǒng)一轉(zhuǎn)成當(dāng)?shù)貢r(shí)間再重采樣避免早晨和晚上的用電高峰被整體平移一個(gè)小時(shí)。3.2 構(gòu)造監(jiān)督學(xué)習(xí)樣本滯后特征必須放在同一條樣本里模型需要的是「特征矩陣 X 目標(biāo)值 y」的監(jiān)督學(xué)習(xí)格式這一步核心是shift()操作。預(yù)測(cè)未來 1 小時(shí)的樣本長(zhǎng)這樣X 是當(dāng)前時(shí)刻的時(shí)間特征、過去 N 小時(shí)的用電量、天氣數(shù)據(jù)y 是未來 1 小時(shí)的用電量。構(gòu)造時(shí)最容易犯的錯(cuò)是把滯后特征算到未來去了——比如用 t1 時(shí)刻的用電量去預(yù)測(cè) t1這在訓(xùn)練時(shí)看起來準(zhǔn)確率極高上線后立刻崩掉。import numpy as np def make_features(hourly: pd.Series, temp: pd.Series None, lags[1, 2, 24, 168]): data pd.DataFrame({power: hourly}) data[hour] hourly.index.hour data[dayofweek] hourly.index.dayofweek data[is_weekend] (data[dayofweek] 5).astype(int) # 周期編碼小時(shí)保留“23點(diǎn)和0點(diǎn)相鄰”這個(gè)信息 data[hour_sin] np.sin(2 * np.pi * data[hour] / 24) data[hour_cos] np.cos(2 * np.pi * data[hour] / 24) for lag in lags: data[flag_{lag}h] hourly.shift(lag) # 滾動(dòng)統(tǒng)計(jì)特征過去6小時(shí)的均值和過去24小時(shí)的最大值 data[roll_mean_6h] hourly.rolling(6).mean() data[roll_max_24h] hourly.rolling(24).max() if temp is not None: data[temp] temp return data data make_features(hourly) data[target] data[power].shift(-1) # 預(yù)測(cè)未來1小時(shí) data data.dropna()代碼里每一列的含義都在名字里。滯后特征lag_1h是上一小時(shí)用電量lag_24h是昨天同一時(shí)刻的用電量lag_168h是上周同一時(shí)刻的用電量分別對(duì)應(yīng)短時(shí)慣性、日周期和周周期。滾動(dòng)窗口特征用rolling().mean()和rolling().max()做出來它們對(duì)捕捉「空調(diào)剛開機(jī)還在爬坡」這類狀態(tài)很有幫助。target用shift(-1)表示把未來一小時(shí)的用電量拉到當(dāng)前行——這一步是監(jiān)督學(xué)習(xí)樣本構(gòu)造的核心滯后特征和 target 的 shift 方向一定不能搞反。dropna 去掉構(gòu)造滯后特征時(shí)產(chǎn)生的前幾行空值。3.3 時(shí)序切分隨機(jī)打亂是回歸預(yù)測(cè)里最隱蔽的死法分類任務(wù)里隨機(jī)劃分訓(xùn)練集和驗(yàn)證集是常規(guī)操作但時(shí)間序列不行。用電數(shù)據(jù)有強(qiáng)自相關(guān)性上周四的用電模式和這周四接近如果隨機(jī)打亂模型會(huì)直接記住「這個(gè)時(shí)間段的用電量大概是多少」驗(yàn)證集里全是它見過的鄰近樣本看起來效果極好部署后立刻現(xiàn)原形。正確做法是按時(shí)間順序切分前 80% 的時(shí)間段做訓(xùn)練后 20% 做驗(yàn)證。train_size int(len(data) * 0.8) train, val data.iloc[:train_size], data.iloc[train_size:] feature_cols [c for c in data.columns if c ! target] X_train, y_train train[feature_cols], train[target] X_val, y_val val[feature_cols], val[target]3.4 三個(gè)基線模型先線性后樹模型一步一個(gè)腳印先把線性回歸跑通拿到一個(gè)基線分?jǐn)?shù)再上隨機(jī)森林和梯度提升樹。線性回歸的好處是能快速驗(yàn)證特征構(gòu)造有沒有硬傷如果線性回歸的 RMSE 大得離譜多半是特征里混進(jìn)了非數(shù)值類型或者有大量缺失值沒處理如果線性回歸表現(xiàn)還行但樹模型提升不明顯說明特征和目標(biāo)之間主要是線性關(guān)系不必盲目堆模型復(fù)雜度。這種先基線后增強(qiáng)的順序能幫你定位問題是出在特征還是出在模型。from sklearn.ensemble import RandomForestRegressor from sklearn.linear_model import LinearRegression from sklearn.ensemble import GradientBoostingRegressor from sklearn.metrics import mean_absolute_error, mean_squared_error models { linear: LinearRegression(), random_forest: RandomForestRegressor(n_estimators200, max_depth12, random_state42, n_jobs-1), gbr: GradientBoostingRegressor(n_estimators300, max_depth6, learning_rate0.05, random_state42) } for name, model in models.items(): model.fit(X_train, y_train) pred model.predict(X_val) mae mean_absolute_error(y_val, pred) rmse mean_squared_error(y_val, pred, squaredFalse) print(f{name}: MAE{mae:.3f} kW, RMSE{rmse:.3f} kW)參數(shù)不是拍腦袋定的隨機(jī)森林的max_depth12是讓樹有足夠深度去擬合復(fù)雜的交互關(guān)系但又不至于深到過擬合n_estimators200在這個(gè)樣本量下已經(jīng)是穩(wěn)健區(qū)間再加大收益很小、耗時(shí)翻倍。梯度提升樹的學(xué)習(xí)率設(shè)成0.05配合 300 棵樹這個(gè)組合在小時(shí)級(jí)用電數(shù)據(jù)上通常是省心的默認(rèn)值。跑完以后對(duì)比三個(gè)數(shù)字線性回歸如果 MAE 在 0.3 kW 左右說明特征已經(jīng)抓住了主要規(guī)律隨機(jī)森林和 GBR 如果能壓到 0.2 kW 以下就算入門了。4. 必調(diào)參數(shù)與多步預(yù)測(cè)策略從預(yù)測(cè) 1 小時(shí)到預(yù)測(cè) 24 小時(shí)4.1 滯后窗口的選擇預(yù)測(cè)步長(zhǎng)不同特征配置完全不同上面 3.2 的例子默認(rèn)預(yù)測(cè)未來 1 小時(shí)滯后特征是[1, 2, 24, 168]。如果要預(yù)測(cè)未來 24 小時(shí)即明天的用電曲線特征配置就要變當(dāng)天 0 點(diǎn)去預(yù)測(cè) 24 小時(shí)后時(shí)lag_1h是昨天 23 點(diǎn)的用電量它和明天 0 點(diǎn)的用電量相關(guān)性已經(jīng)弱了很多此時(shí)lag_24h昨天 0 點(diǎn)和lag_168h上周 0 點(diǎn)反而更有參考價(jià)值。經(jīng)驗(yàn)法則是預(yù)測(cè)步長(zhǎng)越長(zhǎng)短時(shí)滯后特征1~2 小時(shí)的權(quán)重越低周期滯后特征24 小時(shí)、168 小時(shí)的權(quán)重越高。我一般會(huì)把滯后特征設(shè)成幾組并排對(duì)比[1, 2, 3]、[24, 48]、[168, 336]分別覆蓋超短期慣性、日周期、周周期。如果預(yù)測(cè)目標(biāo)改成未來 24 小時(shí)的平均用電量還可以把滾動(dòng)窗口調(diào)大到rolling(24).mean()把「過去一天的總用電量」這個(gè)強(qiáng)特征直接暴露給模型。用樹模型的特征重要性去看如果lag_24h始終排第一說明日周期性是你這戶用電數(shù)據(jù)里最強(qiáng)的規(guī)律。參數(shù)調(diào)整節(jié)奏建議這樣走固定預(yù)測(cè)目標(biāo)為未來 1 小時(shí) → 只調(diào)滯后特征 → 只看驗(yàn)證集 MAE → 找到滯后特征組合后 → 再調(diào)樹模型深度和學(xué)習(xí)率。不要同時(shí)調(diào)整所有旋鈕不然根本分不清效果變化來自哪個(gè)參數(shù)。4.2 樹模型參數(shù)小心 max_depth 和 min_samples_leaf 的配合在家庭用電這種上千到上萬樣本的規(guī)模里隨機(jī)森林和梯度提升樹最容易翻車的參數(shù)不是n_estimators而是讓單棵樹長(zhǎng)得過深。max_depth太大比如 30時(shí)單棵樹會(huì)記住訓(xùn)練集里的個(gè)別極端用電日驗(yàn)證集上一旦出現(xiàn)沒見過的峰值預(yù)測(cè)就會(huì)跑偏。min_samples_leaf 是另一個(gè)常被忽略的參數(shù)它控制葉子節(jié)點(diǎn)的最少樣本數(shù)設(shè)得大一點(diǎn)能防止樹去擬合那些只出現(xiàn)一次的深夜低用電量樣本。一個(gè)省心的檢查方式是看訓(xùn)練集和驗(yàn)證集的 MAE 差距如果訓(xùn)練 MAE 是 0.05 而驗(yàn)證 MAE 是 0.25說明嚴(yán)重過擬合優(yōu)先調(diào)大min_samples_leaf到 5~10同時(shí)把max_depth往下壓如果兩邊都高到 0.3 以上說明欠擬合先回去加滯后特征而不是繼續(xù)加深模型。以下是一組我在小時(shí)級(jí)用電數(shù)據(jù)上常用的參數(shù)范圍。參數(shù)常見范圍調(diào)整方向說明n_estimators100~400不動(dòng)優(yōu)先調(diào)其他參數(shù)超過 200 后收益急劇變小只在最終訓(xùn)練時(shí)加大max_depth6~15過擬合時(shí)減小家庭用電數(shù)據(jù)量不大沒必要超過 15min_samples_leaf3~10過擬合時(shí)增大比 max_depth 更平滑地控制過擬合learning_rateGBR0.03~0.1欠擬合時(shí)調(diào)大過擬合時(shí)調(diào)小配合 n_estimators先定 learning_rate 再定樹數(shù)量max_featuresauto/sqrt樹之間相關(guān)性高時(shí)調(diào)小讓每棵樹更“獨(dú)立”提升集成效果參數(shù)說明n_estimators在這個(gè)規(guī)模下 200 和 400 的差距基本在 0.01 kW 以內(nèi)沒必要用 GridSearch 去掃max_features用默認(rèn)的 sqrt隨機(jī)森林/ 1.0GBR起步如果發(fā)現(xiàn)樹之間的預(yù)測(cè)結(jié)果非常一致、像一個(gè)模型在重復(fù)投票就調(diào)小到 0.6 左右讓樹更具多樣性。調(diào)參的終點(diǎn)不是驗(yàn)證集 MAE 最低而是訓(xùn)練集和驗(yàn)證集的誤差差距在一個(gè)可接受的范圍內(nèi)。4.3 多步預(yù)測(cè)單步模型怎么滾動(dòng)預(yù)測(cè)未來 24 小時(shí)模型輸出的是「未來 1 小時(shí)的用電量」要預(yù)測(cè)未來 24 小時(shí)有三種常見做法多輸出回歸、遞歸預(yù)測(cè)、直接訓(xùn)練 24 個(gè)模型。遞歸預(yù)測(cè)是先用當(dāng)前特征預(yù)測(cè) t1再把 t1 的預(yù)測(cè)值當(dāng)作滯后特征去預(yù)測(cè) t2不斷滾動(dòng)到 t24。它實(shí)現(xiàn)簡(jiǎn)單但誤差會(huì)累積第 1 小時(shí)預(yù)測(cè)偏了 0.1第 2 小時(shí)把偏了的 0.1 當(dāng)輸入后面越錯(cuò)越多通常到第 8 小時(shí)以后預(yù)測(cè)基本失去參考價(jià)值。多輸出回歸是讓模型直接輸出 24 個(gè)值對(duì)應(yīng)未來 24 小時(shí)sklearn 里用MultiOutputRegressor包裝任意回歸模型每個(gè)預(yù)測(cè)頭單獨(dú)訓(xùn)練。它的好處是 24 小時(shí)的誤差相互獨(dú)立不會(huì)滾動(dòng)累積壞處是樣本量沒有增加24 個(gè)模型共享同一份訓(xùn)練數(shù)據(jù)模型容量不夠時(shí)反而擬合不好。我自己實(shí)際用的方案是混合策略用多輸出模型預(yù)測(cè)未來 1~6 小時(shí)的曲線從第 7 小時(shí)開始切到遞歸預(yù)測(cè)——先用多輸出的第 6 小時(shí)預(yù)測(cè)結(jié)果刷新滯后特征再遞歸往后推。這樣既避開了短期的誤差累積又減少了需要訓(xùn)練的全天模型數(shù)量。做多步預(yù)測(cè)時(shí)驗(yàn)證集必須按「預(yù)測(cè)第 N 小時(shí)的誤差」分別報(bào)告不能只報(bào)全時(shí)段平均否則你會(huì)以為全天預(yù)測(cè)都很準(zhǔn)實(shí)際是前面幾小時(shí)拉低了整體誤差。5. 家庭用電預(yù)測(cè)避坑清單五條血淚經(jīng)驗(yàn)5.1 時(shí)序泄漏驗(yàn)證集結(jié)果好得離譜先查 shuffle 和 feature 方向現(xiàn)象模型在驗(yàn)證集上 MAE 只有 0.05 kW比訓(xùn)練集還好或者 RMSE 小到不真實(shí)。 原因一是用了train_test_split的默認(rèn)隨機(jī)切分驗(yàn)證集里全是訓(xùn)練集時(shí)間段的鄰近樣本二是構(gòu)造滯后特征或 target 時(shí) shift 方向?qū)懛戳藢?dǎo)致未來信息泄漏進(jìn)了特征。 解決切分改成按時(shí)間順序參考 3.3 的代碼并逐個(gè)檢查shift(1)到底是把過去的值拉到現(xiàn)在還是把未來的值拉到現(xiàn)在。檢查方法很簡(jiǎn)單打印一條樣本看lag_1h是不是樣本 timestamp 前一小時(shí)的用電量target是不是樣本后一小時(shí)的用電量。5.2 節(jié)假日和社會(huì)事件模型把節(jié)假日當(dāng)天當(dāng)成普通工作日現(xiàn)象春節(jié)、國(guó)慶這些天預(yù)測(cè)值比實(shí)際值高出 30%~50%因?yàn)槟P蛯W(xué)到的規(guī)律是「工作日用電低、周末略高」長(zhǎng)假里人在家待著用電曲線更像周末但又有做飯和取暖的高峰。 原因只用「星期幾」做特征模型沒見過長(zhǎng)假這種長(zhǎng)尾場(chǎng)景。 解決構(gòu)造is_holiday布爾特征把本地法定節(jié)假日按日期生成一列 0/1 加進(jìn)特征矩陣。長(zhǎng)假前后的幾天也要單獨(dú)處理放假前一天晚上用電量會(huì)異常升高這可以做成is_day_before_holiday。沒有官方節(jié)假日表時(shí)退而求其次把日期序號(hào)做成特征讓樹模型自己學(xué)著分開「正常日」和「異常日」。5.3 溫度滯后今天的氣溫不會(huì)立刻影響今天的用電現(xiàn)象加入溫度特征后模型效果反而變差或者特征重要性里溫度排第一但預(yù)測(cè)依舊不準(zhǔn)。 原因空調(diào)和暖氣對(duì)氣溫變化的響應(yīng)有滯后性人體對(duì)溫度的感受也不光是當(dāng)前小時(shí)的溫度連續(xù)幾個(gè)小時(shí)的累積熱效應(yīng)影響更大。 解決不要只加入當(dāng)前小時(shí)的溫度改用「過去 24 小時(shí)平均溫度」「過去 48 小時(shí)平均溫度」以及「當(dāng)日最高溫」這些滑動(dòng)平均溫度特征。我一般會(huì)構(gòu)造temp_avg_24h和temp_max_1d再判斷滯后溫度特征的重要性如果temp_avg_24h遠(yuǎn)高于temp說明這戶用電明顯受到累積熱效應(yīng)影響。5.4 峰值預(yù)測(cè)平均誤差好看關(guān)鍵時(shí)刻的尖峰全偏現(xiàn)象驗(yàn)證集 MAE 不錯(cuò)但你去看每天 18:00~21:00 的晚高峰預(yù)測(cè)值普遍偏低 0.5 kW 甚至更多剛好是做飯熱水器同時(shí)工作的時(shí)段。 原因家庭用電的峰谷差異極大峰值樣本在訓(xùn)練集里占比少回歸模型為了降低整體誤差會(huì)把預(yù)測(cè)值往中位數(shù)方向收縮峰值被犧牲了。 解決訓(xùn)練時(shí)給高峰時(shí)段樣本加權(quán)比如對(duì) 17:00~22:00 的樣本在損失函數(shù)里乘 1.5 或 2.0 的權(quán)重或者單獨(dú)訓(xùn)練一個(gè)「高峰時(shí)段模型」只用高峰時(shí)段的數(shù)據(jù)訓(xùn)練預(yù)測(cè)時(shí)先判斷當(dāng)前時(shí)間是否在高峰窗口內(nèi)。如果目標(biāo)是電網(wǎng)側(cè)的容量管理峰值預(yù)測(cè)的準(zhǔn)確率比全天平均誤差重要得多評(píng)估時(shí)建議分組報(bào)告高峰時(shí)段的 MAE。5.5 特征管道不一致訓(xùn)練時(shí)好好的部署后預(yù)測(cè)全亂現(xiàn)象模型在驗(yàn)證回歸腳本里表現(xiàn)正常你把特征構(gòu)造代碼復(fù)制到線上服務(wù)后預(yù)測(cè)值普遍偏移。 原因最常見的兩個(gè)一是線上構(gòu)造滯后特征時(shí)歷史數(shù)據(jù)庫的時(shí)間沒對(duì)齊lag_24h取到的不一定是 24 小時(shí)前那條記錄二是訓(xùn)練時(shí)做了fillna(0)或歸一化但線上推理時(shí)沒有做同樣的處理尤其是新用戶沒有足夠歷史數(shù)據(jù)時(shí)滯后特征全是空值。 解決把特征構(gòu)造封裝成一個(gè)函數(shù)訓(xùn)練和推理共用同一份代碼不要在兩個(gè)地方各寫一份。線上推理時(shí)如果滯后特征為空不要填 0用前向填充最近的可用值并在模型側(cè)記錄哪些樣本是「冷啟動(dòng)」樣本——它們天然預(yù)測(cè)不準(zhǔn)單獨(dú)標(biāo)記出來比硬塞一個(gè)好結(jié)果更重要。6. 小步快跑的進(jìn)階技巧從預(yù)測(cè)到可解釋的用電顧問回歸模型跑通后的下一個(gè)層面不是換更大的模型而是把預(yù)測(cè)結(jié)果變成能指導(dǎo)行動(dòng)的信息。我最常用的技巧是特征重要性分析拿訓(xùn)練好的隨機(jī)森林或梯度提升樹輸出feature_importances_你會(huì)看到lag_24h和hour幾乎總是排在最前面這能反過來幫你理解這戶人家的用電習(xí)慣——是晚上固定時(shí)間高還是空調(diào)連續(xù)運(yùn)行幾天不關(guān)。帶交互作用的 SHAP 值分析能進(jìn)一步看出「高溫 傍晚」這兩個(gè)特征組合時(shí)預(yù)測(cè)會(huì)跳升這比單看重要性的信息量大得多。另一個(gè)可以做的小工具是把預(yù)測(cè)結(jié)果和實(shí)時(shí)功率做差值監(jiān)控當(dāng)實(shí)際用電量連續(xù) 30 分鐘顯著高于預(yù)測(cè)值比如超過 1 個(gè)標(biāo)準(zhǔn)差就推送一條消息提醒「家里可能有大功率設(shè)備運(yùn)行異?;蛲P(guān)空調(diào)」。這類應(yīng)用不要求預(yù)測(cè)絕對(duì)精準(zhǔn)更看重趨勢(shì)偏離的靈敏度和誤報(bào)率控制。做完這一層你手里的東西就不只是「一個(gè)預(yù)測(cè)模型」而是一個(gè)有輸入有輸出、能被家人信任的用電顧問。建議你先從自己家的數(shù)據(jù)跑通第 3 章的最小流程隨機(jī)森林拿到 0.2 kW 以內(nèi)的 MAE 后再考慮往多步預(yù)測(cè)和部署走。我自己的習(xí)慣是每周跑一次預(yù)測(cè)并復(fù)盤誤差最大的三個(gè)時(shí)段基本上一兩周下來就能總結(jié)出這戶人家獨(dú)有的用電規(guī)律比盲目調(diào)參有用得多。希望幫到你。本文還有配套的精品資源點(diǎn)擊獲取