时间序列预测12:用电量预测 02 特征工程与模型调优
1. 特征工程从原始数据中挖掘黄金做时间序列预测就像炒菜特征工程就是准备食材的过程。我处理过不少用电量预测项目发现特征质量直接决定模型上限。那个法国用电量数据集有7个原始变量但真正用起来能玩出几十种花样。1.1 时序特征构建实战滞后特征是最基础的招式。比如预测明天用电量最近7天的数据肯定比一个月前的有用。用pandas生成滞后特征特别简单# 生成1-7阶滞后特征 for i in range(1, 8): dataset[flag_{i}] dataset[Global_active_power].shift(i)但要注意处理缺失值我一般用.fillna(methodbfill)向后填充。滑动窗口统计量更厉害它能捕捉短期波动规律# 7天滑动窗口的均值和标准差 dataset[rolling_mean_7] dataset[Global_active_power].rolling(window7).mean() dataset[rolling_std_7] dataset[Global_active_power].rolling(window7).std()周期性特征是电力数据的灵魂。法国人工作日和周末用电模式差异很大我通常会这样处理# 提取星期几特征0-6对应周一到周日 dataset[day_of_week] dataset.index.dayofweek # 是否为周末 dataset[is_weekend] dataset[day_of_week].apply(lambda x: 1 if x 5 else 0)1.2 外部特征融合技巧温度对用电量影响巨大特别是空调使用率高的地区。我曾在一个项目中发现气温每升高1℃用电量增加5%。处理外部数据要注意三点时间对齐确保温度数据的时间戳与用电量数据完全匹配缺失处理用线性插值补全缺失的温度数据非线性转换尝试温度平方项捕捉极端天气影响节假日特征也很关键。法国人圣诞节用电模式很特殊我通常会手动标注重要节日holidays [2007-12-25, 2008-12-25,...] dataset[is_holiday] dataset.index.isin(pd.to_datetime(holidays)).astype(int)1.3 数据标准化那些坑电力数据量纲差异大比如电压单位是伏特功率是千瓦。我吃过没做标准化的亏模型完全跑偏。现在固定用这两种方法MinMaxScaler当数据分布较均匀时from sklearn.preprocessing import MinMaxScaler scaler MinMaxScaler(feature_range(0, 1)) scaled_data scaler.fit_transform(dataset[[Global_active_power, Voltage]])RobustScaler当存在异常值时from sklearn.preprocessing import RobustScaler scaler RobustScaler() scaled_data scaler.fit_transform(dataset[[Global_reactive_power]])特别注意要先用训练集fit再用相同的scaler转换验证集和测试集否则会数据泄露。2. 模型选择没有银弹只有合适2.1 SARIMA传统方法依然能打SARIMA适合有明显季节性的数据。配置一个基础模型from statsmodels.tsa.statespace.sarimax import SARIMAX model SARIMAX(train_data, order(1,1,1), # (p,d,q) seasonal_order(1,1,1,24)) # (P,D,Q,s) results model.fit() print(results.summary())调参时我常用网格搜索找最优参数组合但要注意差分阶数d一般不超过2季节性周期s要根据数据定电力数据常用24小时/7天用AIC/BIC指标比较模型值越小越好2.2 XGBoost特征工程的好搭档XGBoost对特征质量要求高但效果惊人。这是我的标配参数from xgboost import XGBRegressor model XGBRegressor( n_estimators200, max_depth5, learning_rate0.1, subsample0.8, colsample_bytree0.8, early_stopping_rounds20, random_state42 ) model.fit(X_train, y_train, eval_set[(X_val, y_val)], verbose10)特征重要性分析能帮我们优化特征工程import matplotlib.pyplot as plt plt.barh(feature_names, model.feature_importances_)2.3 LSTM/GRU深度学习的双刃剑LSTM处理时序数据确实强但调参难度也大。一个实用的网络结构from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense model Sequential([ LSTM(64, input_shape(look_back, n_features), return_sequencesTrue), LSTM(32), Dense(16, activationrelu), Dense(1) ]) model.compile(lossmse, optimizeradam)几个血泪教训数据量小于1万条时慎用Batch_size建议设为24/48等周期值用EarlyStopping防止过拟合输出层不要用激活函数3. 模型调优从能用变好用3.1 交叉验证的特殊姿势时间序列不能随机打乱要用TimeSeriesSplitfrom sklearn.model_selection import TimeSeriesSplit tscv TimeSeriesSplit(n_splits5) for train_index, test_index in tscv.split(X): X_train, X_test X[train_index], X[test_index] y_train, y_test y[train_index], y[test_index]我习惯保留最后20%数据作为独立测试集用前80%做交叉验证。3.2 超参数搜索实战网格搜索太耗时我改用贝叶斯优化from skopt import BayesSearchCV search_space { n_estimators: (100, 500), max_depth: (3, 10), learning_rate: (0.01, 0.3, log-uniform) } opt BayesSearchCV( XGBRegressor(), search_space, n_iter20, cvtscv, scoringneg_mean_squared_error ) opt.fit(X_train, y_train)3.3 集成策略提升鲁棒性单一模型总有局限我常用三种集成方式加权平均给不同模型分配不同权重Stacking用第二层模型整合基模型输出残差学习用LSTM学习其他模型的预测残差一个简单的加权平均实现final_pred 0.4*lstm_pred 0.3*xgb_pred 0.3*sarima_pred4. 部署落地模型上线那些坑4.1 实时预测架构设计生产环境要考虑延迟和吞吐量。我常用的架构[数据流] - [特征工程微服务] - [模型预测集群] - [结果缓存Redis] - [API网关]4.2 模型监控与迭代上线才是开始要监控这些指标预测偏差实际值-预测值特征分布变化用KL散度检测预测延迟P99100ms我设置了一个自动retrain机制当误差连续3天超过阈值时触发。4.3 业务指标对齐技术指标好不等于业务效果好。曾经有个项目MSE降了但调度成本反而上升后来才发现要优化的是负荷峰谷差。建议与业务方共同定义损失函数在测试环境跑业务模拟做AB测试验证实际效果用电量预测看似简单但想做好需要不断迭代。我现在的项目已经迭代到第7版每次以为到天花板时总能发现新的优化空间。最近在试验Transformer模型效果还有待验证。
