
简介这份资源面向机器学习入门与进阶学习者聚焦回归算法在家庭用电预测中的完整落地实践帮助读者理解如何从数据预处理、特征工程到模型训练与评估构建可用的用电量预测方案。压缩包共4个文件均为Python脚本整体约9KB按编号分步组织便于对照学习线性回归、多项式回归、决策树回归、随机森林回归与支持向量回归等模型的实现差异。内容涉及缺失值处理、异常值检测、标准化、时间序列特征构造以及MSE、RMSE、R²等评估指标和交叉验证调参思路适合作为课程设计、练手项目或算法对比实验的参考代码。目前已有259人学习下载可帮助读者快速搭建家庭用电预测的实验框架并在此基础上替换数据或调整模型参数进行扩展。1. 家庭用电预测回归算法为什么比分类更值得先跑通家庭用电预测这件事很多人第一次接触会以为是个分类问题——预测明天用电多还是少。但真正落地时你会发现业务方要的是具体数值明天这个小区大概用多少度电、下个月电费预算多少、储能系统该在几点充放。这就把问题拉回了回归算法的地盘。基于机器学习回归算法实现家庭用电预测核心链路其实不复杂把历史用电数据按时间切窗构造特征喂给回归模型输出未来一段时间的用电量。它适合两类人一类是刚学完线性回归、决策树想找一个有真实数据、有明确评估指标的练手项目另一类是做能源管理、智能家居的工程师需要快速搭一个能跑通、能解释、能迭代的基线。这个方向不需要 GPU 集群一台普通笔记本就能跑但坑集中在时间序列的切分方式和特征构造上后面会逐条拆。2. 数据到手先别急着 fit家庭用电数据的三个预处理动作2.1 时间序列的缺失值和异常值怎么处理家庭用电数据最常见的形态是一列时间戳加一列有功功率采样间隔从 1 分钟到 1 小时不等。真实数据里一定会有缺失电表离线、通信中断、传感器漂移。很多人上来就dropna()结果把连续几天的数据整段删掉训练集直接少三成。我一般会先做重采样把不规则时间戳统一到固定频率再用插值补缺失。import pandas as pd import numpy as np # df 至少包含 timestamp 和 power 两列 df[timestamp] pd.to_datetime(df[timestamp]) df df.set_index(timestamp).sort_index() # 统一到 15 分钟频率取均值聚合 df df.resample(15min).mean() # 短缺口线性插值长缺口标记出来 df[power] df[power].interpolate(methodlinear, limit8) df[is_gap] df[power].isna().astype(int) # 用前后 7 天同一时刻的中位数兜底长缺口 df[power] df[power].fillna( df[power].rolling(window96*7, min_periods1, centerTrue).median() )这段代码的逻辑是先重采样解决时间戳不规则再对短缺口做线性插值超过 8 个点即 2 小时的缺口用滚动中位数兜底。limit8这个参数不是拍脑袋15 分钟采样下 8 个点对应 2 小时家庭用电在 2 小时内的变化通常接近线性超过这个窗口线性假设就不成立了。is_gap这一列别扔后面做特征时可以告诉模型哪些点是补出来的避免模型把插值当真实规律学。异常值处理要克制。用电数据里的尖峰有时候是真实的大功率设备启动比如空调压缩机、电热水器直接按 3σ 删掉会把有效信号删没。我的做法是先用物理边界卡一刀家庭单户有功功率超过 20kW 的基本可以判定为采集错误先置为缺失再走上面的插值流程。剩下的波动交给模型去学不要过度清洗。2.2 构造回归特征滑窗、滞后和日历变量回归算法不会自己理解时间你得把时间信息翻译成特征。最直接的是滞后特征用过去 N 个时刻的值预测下一时刻。但滞后阶数不是越多越好家庭用电有很强的日周期和周周期滞后阶数要覆盖至少一个完整周期。def build_features(series, lags(1, 2, 4, 96, 192), rolls(4, 96)): feat pd.DataFrame(indexseries.index) for lag in lags: feat[flag_{lag}] series.shift(lag) for win in rolls: feat[froll_mean_{win}] series.shift(1).rolling(win).mean() feat[froll_std_{win}] series.shift(1).rolling(win).std() feat[hour] series.index.hour feat[weekday] series.index.weekday feat[is_weekend] (series.index.weekday 5).astype(int) feat[target] series.values return feat.dropna()lags里 1、2、4 对应 15 分钟、30 分钟、1 小时前的值96 和 192 对应一天前和两天前同一时刻。rolls里的 4 和 96 分别是一小时和一天的滚动窗口。注意所有滚动特征都用了shift(1)这是为了避免用当前时刻的信息预测当前时刻也就是数据泄漏。日历变量里hour和weekday是周期性的直接当数值喂给线性回归会出问题——23 点和 0 点数值上差 23实际只差 1 小时。如果后面用线性模型这两个特征要做 sin/cos 编码树模型可以不管。2.3 训练集和测试集必须按时间切这是家庭用电预测里翻车最多的地方。很多人习惯train_test_split(shuffleTrue)在时间序列上这是致命的。打乱之后模型在训练集里见过未来时刻的邻居测试集指标会好得离谱上线就崩。正确做法是按时间顺序切比如前 80% 做训练后 20% 做测试中间留一段 gap 防止滞后特征跨边界泄漏。n len(feat) train_end int(n * 0.8) gap 192 # 两天覆盖最大滞后阶数 train feat.iloc[:train_end - gap] test feat.iloc[train_end:] X_train, y_train train.drop(columnstarget), train[target] X_test, y_test test.drop(columnstarget), test[target]gap192是因为最大滞后是 192如果不留 gap测试集第一个样本的滞后特征会落到训练集最后一段等于偷看了训练集。这个细节在论文里经常被忽略但做工程必须卡住。3. 回归算法选型从线性回归到梯度提升的取舍3.1 先跑线性回归和决策树建立基线选型的第一步不是挑最强的模型而是建立基线。线性回归和单棵决策树训练快、可解释能帮你判断特征里到底有没有信号。如果线性回归的 R² 只有 0.3别急着上 XGBoost先回去看特征构造是不是漏了关键周期。from sklearn.linear_model import Ridge from sklearn.tree import DecisionTreeRegressor from sklearn.metrics import mean_absolute_error, r2_score models { ridge: Ridge(alpha1.0), tree: DecisionTreeRegressor(max_depth8, min_samples_leaf20, random_state42) } for name, model in models.items(): model.fit(X_train, y_train) pred model.predict(X_test) print(name, MAE, mean_absolute_error(y_test, pred), R2, r2_score(y_test, pred))Ridge的alpha1.0是正则强度特征多且共线时调大。决策树的max_depth8和min_samples_leaf20是防过拟合的家庭用电数据噪声大叶子节点样本太少会学到噪声。这两个基线跑完你心里就有数了MAE 大概在什么量级R² 能不能过 0.7。3.2 随机森林回归和梯度提升怎么选热搜里随机森林回归算法出现频率很高它在家庭用电预测里确实是个稳妥选择对特征尺度不敏感、能处理非线性、不容易过拟合。但梯度提升类模型XGBoost、LightGBM在同等特征下通常能再低 10% 到 20% 的 MAE代价是调参更麻烦、训练更慢。from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor rf RandomForestRegressor( n_estimators300, max_depth12, min_samples_leaf10, n_jobs-1, random_state42 ) gb GradientBoostingRegressor( n_estimators300, learning_rate0.05, max_depth4, subsample0.8, random_state42 ) for name, model in [(rf, rf), (gb, gb)]: model.fit(X_train, y_train) pred model.predict(X_test) print(name, MAE, mean_absolute_error(y_test, pred))随机森林的n_estimators300是起点再往上收益递减。max_depth12配合min_samples_leaf10控制单棵树复杂度。梯度提升的learning_rate0.05配n_estimators300是经典的慢学习率多轮迭代组合subsample0.8引入随机性防过拟合。如果数据量超过十万行优先试 LightGBM训练速度差距很明显。3.3 评估指标别只看 R²家庭用电预测的业务方关心的是「预测偏差多少度」所以 MAE 比 R² 更直观。但 MAE 对尖峰不敏感尖峰预测错了 MAE 可能只涨一点实际影响很大。我一般会同时看三个指标MAE 看平均偏差RMSE 看大偏差惩罚MAPE 看相对误差。MAPE 在用电量接近零时会爆炸所以只在对应用电时段算。指标含义家庭用电场景下的参考值MAE平均绝对误差单户 15 分钟粒度下 0.05~0.15 kWhRMSE均方根误差通常是 MAE 的 1.2~1.5 倍MAPE平均绝对百分比误差用电高峰时段 8%~15%参考值不是标准是让你判断模型有没有跑偏。如果 MAE 到了 0.5 kWh先查数据预处理别急着调模型。4. 避坑与排查家庭用电预测里最容易翻车的五件事4.1 现象测试集 R² 0.95上线后预测全错原因用了随机切分或者没留 gap滞后特征把未来信息泄漏进了训练集。解决按时间切分训练集和测试集之间留至少等于最大滞后阶数的 gap切完检查测试集第一个样本的滞后特征是否落在训练集范围内。4.2 现象模型在白天预测准夜间误差翻倍原因夜间用电量低且波动小模型在训练时被白天高功率样本主导夜间样本权重不足。解决对目标做对数变换或者按用电时段分层采样保证夜间样本在训练集里有足够占比。也可以给样本加权夜间样本权重调高。4.3 现象换了新用户数据MAE 直接翻三倍原因不同家庭的用电模式差异极大单户数据训练的模型直接迁移到另一户会崩。解决要么每户单独训练要么在特征里加入家庭属性户型、人数、是否有电动车做多户联合训练时用家庭 ID 做分组交叉验证。4.4 现象滞后特征重要性排第一但去掉后效果没变差原因滞后特征和滚动特征高度共线树模型随机选一个用重要性被稀释。解决看特征重要性时结合排列重要性permutation importance或者做特征聚类后每组只保留一个代表。4.5 现象预测曲线整体平移形状对但数值偏原因目标变量分布偏移训练集和测试集的均值不一致。解决检查切分点前后是否有季节性变化比如训练集覆盖冬季、测试集覆盖春季。如果有要么做差分要么在特征里加入月份或温度。5. 把 MAE 再压 15%残差修正和滚动重训的实操技巧基线跑通之后想再进一步我一般会从两个方向下手。第一个是残差修正先用梯度提升跑一版预测把残差拿出来看如果残差还有明显的日周期说明模型没学干净可以把残差作为新目标再训一个模型两个模型叠加。第二个是滚动重训家庭用电模式会随季节漂移固定模型跑三个月就退化用最近 30 天数据每周重训一次MAE 通常能再降 10% 到 15%。# 残差修正示例 base_pred gb.predict(X_test) residual y_test - base_pred # 用同样的特征训残差模型 res_model GradientBoostingRegressor( n_estimators150, learning_rate0.03, max_depth3, random_state42 ) res_model.fit(X_train, y_train - gb.predict(X_train)) final_pred base_pred res_model.predict(X_test) print(修正后 MAE, mean_absolute_error(y_test, final_pred))残差模型的max_depth3比主模型浅因为残差里剩下的信号通常更简单树太深会过拟合。learning_rate0.03配 150 棵树是保守配置残差修正宁欠勿过。滚动重训的工程实现要注意每次重训只取最近 N 天数据N 取 30 到 60 天比较合适太短学不到周周期太长引入过时模式。重训频率按数据漂移速度定家庭用电一般每周一次够用。验证方法是用滚动窗口做时间序列交叉验证每个窗口训一次测一次看 MAE 的均值和方差方差大说明模型不稳定要回去查数据质量。我自己踩过最深的坑是早期太迷信模型复杂度在特征没构造好的情况下反复调 XGBoost 参数折腾一周 MAE 只降了 0.01。后来把日历特征做对、把 gap 留够换回随机森林反而效果更好。特征决定上限模型只是逼近上限的工具。希望帮到你。本文还有配套的精品资源点击获取