☰
基于LSTM的电力负荷预测与回归分析实战指南
2026/10/7 18:54:48 网站建设 项目流程

简介:本资源面向电力系统负荷预测方向的学习者与研究人员,提供一套基于MATLAB实现的长短期记忆神经网络(LSTM)电力负荷回归分析完整方案。电力负荷属于典型时间序列数据,相比普通神经网络,LSTM在捕捉时序依赖与长期趋势方面更具优势,适合本科及以上层次用于课程设计、科研复现或工程扩展。压缩包共11个文件,约2.24MB,包含5个m脚本文件、3个csv数据文件、2个xlsx表格及1个mat数据文件,脚本覆盖主程序、评价指标计算与结果输出,数据文件则提供工业与房产等场景的负荷样本,便于直接运行与二次开发。代码注释较为完整,结构清晰,可帮助读者快速理解LSTM回归建模流程、掌握MSE、RMSE、MAE、R²等评价指标的使用方式,并在此基础上替换数据或调整网络结构以适配自身课题。目前已有159人学习下载,适合需要完整代码与配套数据开展电力负荷预测实践的用户参考。

1. 电力负荷预测为什么总在下午三点翻车:LSTM 回归分析能解决什么

做过电力负荷预测的人多半遇到过这种场景:早上八点的预测曲线贴合得漂漂亮亮,到了下午三点突然整体偏低,晚高峰又被高估一截。翻看历史数据才发现,当天下午有一场持续两小时的暴雨,空调负荷骤降,而模型还沉浸在“昨天同一时刻也是高温”的记忆里。这类翻车不是数据不够,而是模型没学会“什么时候该忘、什么时候该记”。长短期记忆网络(LSTM)正是冲着这个痛点来的:它用门控机制决定哪些历史信息保留、哪些丢弃,天然适合处理电力负荷这种强周期性又叠加天气、节假日扰动的时序数据。这篇笔记围绕“基于 LSTM 的电力负荷预测与回归分析”展开,从数据构造、模型搭建、训练调参到误差排查,给出一条能直接复现的路径。适合已经会用 Python 处理表格数据、想把手里的负荷 CSV 跑出可用预测曲线的从业者,也适合需要向团队解释“为什么不用 ARIMA 或 XGBoost”的技术负责人。

2. 把负荷 CSV 变成 LSTM 能吃的监督样本:滑动窗口与特征工程

2.1 电力负荷数据的三个固有特征

电力负荷序列和普通时间序列不同,它同时受三类因素驱动。第一是周期性:日周期(早高峰、午平峰、晚高峰)、周周期(工作日与周末模式差异)、年周期(夏冬双峰)。第二是气象耦合:温度对负荷的影响不是线性的,超过 30℃ 后空调负荷陡增,低于 5℃ 后取暖负荷抬升,中间段反而平缓。第三是突变性:节假日、重大活动、极端天气会让负荷偏离历史规律,这类样本在训练集中占比小,但预测时一旦遇到就是大误差。

理解这三点,才能理解为什么直接拿原始负荷列喂给 LSTM 效果一般。LSTM 擅长的是从序列中提取时序依赖,但它不会自动帮你构造“昨天同一时刻负荷”“前 24 小时平均负荷”“当前温度”这些对预测真正有用的特征。特征工程做得好,LSTM 只需要专注学时序模式;做得差,模型会把容量浪费在拟合噪声上。

常见做法是把负荷预测拆成两步:先用滑动窗口把单变量序列变成监督学习样本,再叠加外部特征。下面这段代码展示从原始 DataFrame 到 LSTM 输入张量的完整转换。

import numpy as np import pandas as pd from sklearn.preprocessing import MinMaxScaler def build_supervised_samples(df, target_col, feature_cols, lookback=48, horizon=1): """ df: 含时间索引的负荷数据,已按时间升序排列 target_col: 待预测的负荷列名 feature_cols: 外部特征列,如温度、湿度、是否节假日 lookback: 回看步数,48 表示用过去 48 个点预测未来 horizon: 预测步长,1 表示预测下一个点 """ data = df[feature_cols + [target_col]].values scaler = MinMaxScaler() data_scaled = scaler.fit_transform(data) X, y = [], [] target_idx = len(feature_cols) # 目标列在缩放后数组中的位置 for i in range(lookback, len(data_scaled) - horizon + 1): # 取过去 lookback 步的所有特征作为输入 X.append(data_scaled[i - lookback:i, :]) # 取未来第 horizon 步的负荷值作为标签 y.append(data_scaled[i + horizon - 1, target_idx]) return np.array(X), np.array(y), scaler

这段代码有三个参数需要根据实际数据调整。lookback决定模型能“看多远”,日周期数据一般取 24 到 48,如果采样间隔是 15 分钟,48 对应 12 小时,能覆盖半天模式;取太大不仅增加计算量,还会引入过多远期噪声。horizon是预测步长,做日前调度通常取 96(15 分钟粒度下的一天),做实时校正取 1 到 4。feature_cols里温度是必选项,节假日标志建议用 0/1 编码,不要用序号编码,否则模型会误以为周三和周日有线性关系。

2.2 归一化为什么必须在划分训练测试集之前做

这是一个高频翻车点。很多人先把全量数据归一化,再切训练集和测试集,结果测试集的极值信息泄漏到了训练阶段。正确顺序是:先按时间切分,用训练集拟合 scaler,再 transform 测试集。时间序列不能随机打乱划分,否则未来信息会污染过去。

# 正确做法:按时间顺序切分 split = int(len(df) * 0.8) train_df = df.iloc[:split].copy() test_df = df.iloc[split:].copy() # 用训练集拟合 scaler scaler = MinMaxScaler() scaler.fit(train_df[feature_cols + [target_col]]) # 分别 transform train_scaled = scaler.transform(train_df[feature_cols + [target_col]]) test_scaled = scaler.transform(test_df[feature_cols + [target_col]])

如果负荷序列有明显的长期增长趋势(比如某工业园区逐年扩产),MinMaxScaler 会把早期数据压缩到很小区间,这时改用 StandardScaler 或先做一阶差分更稳。差分后再预测,最后要记得把差分还原回去,这一步漏掉的话预测曲线会整体平移。

2.3 外部特征怎么选、怎么编码

温度特征不要只给一个原始值。常见做法是同时给当前温度、过去 3 小时平均温度、以及温度的二次项。二次项的作用是让模型能表达“高温和低温都推高负荷”的 U 型关系。节假日特征建议拆成两个 0/1 列:是否法定节假日、是否周末,不要合并成一个,因为两者的负荷模式并不相同。

提示:如果数据里有明显的缺失段,不要用前向填充糊弄过去。负荷缺失往往对应采集故障,前向填充会制造一段虚假的平稳序列,模型学到之后在真实预测时反而更容易出错。缺失超过 4 个连续点的段落,建议整段剔除并在训练时用掩码标记。

3. 搭一个能收敛的 LSTM 回归模型:层数、门控与损失函数选择

3.1 从 nn.LSTM 到回归输出层的最小结构

LSTM 做回归和做分类的区别只在最后一层:分类用 softmax 输出各类概率,回归直接用一个线性层输出标量。下面是一个可以直接跑的最小模型,输入维度等于特征数,输出维度为 1。

import torch import torch.nn as nn class LoadLSTM(nn.Module): def __init__(self, input_dim, hidden_dim=64, num_layers=2, dropout=0.2): super().__init__() self.lstm = nn.LSTM( input_size=input_dim, hidden_size=hidden_dim, num_layers=num_layers, batch_first=True, dropout=dropout if num_layers > 1 else 0 ) self.fc = nn.Linear(hidden_dim, 1) def forward(self, x): # x: (batch, lookback, input_dim) out, (h_n, c_n) = self.lstm(x) # 取最后一个时间步的隐状态做回归 last_step = out[:, -1, :] return self.fc(last_step).squeeze(-1)

hidden_dim控制记忆容量,负荷预测一般 32 到 128 够用,再大容易过拟合。num_layers超过 2 层后收益递减明显,而且训练时间翻倍,建议从 1 层开始试,欠拟合再加。dropout只在多层时生效,单层 LSTM 加 dropout 没有意义。batch_first=True让输入维度是 (batch, seq, feature),和 PyTorch 默认的 (seq, batch, feature) 不同,写反了模型也能跑但学不到东西,这是新手最常见的静默错误。

3.2 损失函数选 MSE 还是 MAE

电力负荷预测里,MSE 对大误差惩罚重,适合你更在意“不要出现离谱预测”的场景;MAE 对中小误差更敏感,适合你更在意整体曲线贴合度。实际做日前调度时,一个 500MW 的偏差比十个 50MW 的偏差危害大得多,所以 MSE 或 HuberLoss 更常用。HuberLoss 在误差小于 delta 时表现为 MSE,大于 delta 时表现为 MAE,兼顾了两者。

# HuberLoss 用法 criterion = nn.HuberLoss(delta=0.1) # delta 需根据归一化后的误差尺度调整

如果负荷已经归一化到 [0,1],delta 取 0.05 到 0.2 之间比较合理。delta 太小退化成 MAE,太大退化成 MSE,可以用验证集误差曲线来选。

3.3 训练循环里必须监控的三个量

训练 LSTM 不能只看 loss 下降。下面三个量建议每个 epoch 都打印:训练 loss、验证 loss、验证集上的平均绝对百分比误差(MAPE)。训练 loss 降但验证 loss 升,说明过拟合;两者都降但 MAPE 卡在某个值不动,说明模型学到了均值但没学到波动,这时候要检查特征里是不是缺少关键外部变量。

def train_one_epoch(model, loader, optimizer, criterion): model.train() total_loss = 0 for xb, yb in loader: optimizer.zero_grad() pred = model(xb) loss = criterion(pred, yb) loss.backward() # 梯度裁剪防止 LSTM 梯度爆炸 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) optimizer.step() total_loss += loss.item() * xb.size(0) return total_loss / len(loader.dataset)

梯度裁剪是 LSTM 训练的后悔药。LSTM 的反向传播路径长,梯度容易爆炸,表现为 loss 突然变成 nan。max_norm=1.0是常用起点,如果训练稳定可以放宽到 5.0,如果频繁 nan 就收紧到 0.5。

4. 调参与误差排查:学习率、窗口长度和残差分析

4.1 学习率与 batch size 的搭配经验

LSTM 对学习率比 CNN 敏感。常见起点是 1e-3 配 batch size 64,如果 loss 震荡就降到 3e-4,如果收敛太慢就升到 3e-3 但不要超过。batch size 太小(如 8)会让梯度噪声大,太大(如 512)会让泛化变差。负荷数据样本量通常几千到几万,batch size 取 32 到 128 比较稳。

学习率调度器建议用 ReduceLROnPlateau,监控验证 loss,连续 5 个 epoch 不降就乘以 0.5。这比固定步长衰减更适应不同数据集。

scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau( optimizer, mode='min', factor=0.5, patience=5 ) # 每个 epoch 后调用 scheduler.step(val_loss)

4.2 lookback 到底取多长:用自相关函数定

不要凭感觉设 lookback。先对负荷序列做自相关分析(ACF),看哪个滞后阶数的自相关系数降到 0.2 以下,lookback 取那个阶数附近即可。日周期数据通常在滞后 96(15 分钟粒度)或 24(小时粒度)处有强相关,在 192 或 48 处二次相关。如果 ACF 显示 7 天前仍有 0.5 以上相关,说明周周期很强,lookback 至少要覆盖 7 天。

from statsmodels.tsa.stattools import acf acf_vals = acf(train_df['load'], nlags=200) # 找第一个降到 0.2 以下的滞后 for i, v in enumerate(acf_vals): if v < 0.2: print(f"建议 lookback 不小于 {i}") break

4.3 残差分析:预测曲线贴合但残差有规律就是没学好

模型跑完后,不要只看 MAPE。把残差(真实值减预测值)按时间画出来,如果残差在每天同一时段呈现固定正负模式,说明模型没学到那个时段的特征。常见原因是该时段对应特殊负荷(如晚高峰的照明负荷)但特征里没有对应变量。另一个检查是把残差和温度做散点图,如果呈现明显 U 型,说明温度的非线性没被模型捕捉,需要加温度二次项或改用更宽的网络。

注意:残差如果呈现自相关(今天残差和昨天残差相关),说明模型欠拟合,增加 hidden_dim 或 num_layers 通常有效。残差如果方差随时间增大,说明负荷波动性在变化,考虑对目标做对数变换再预测。

5. 避坑与常见问题:从数据泄漏到预测偏移的 5 个真实翻车

现象一:验证集 MAPE 只有 2%,上线后 MAPE 飙到 15%。原因:归一化时用了全量数据的极值,测试集信息泄漏。或者划分时随机打乱,未来数据混入训练。 解决:严格按时间切分,scaler 只在训练集上 fit。上线前用最近一个月数据做一次滚动回测,不要只看单次划分结果。

现象二:训练 loss 正常下降,但预测曲线是一条接近均值的平线。原因:LSTM 最后一层取了平均池化而不是最后时间步,或者输入序列被错误地 shuffle 打乱了时序。 解决:确认out[:, -1, :]取的是最后一步,确认 DataLoader 的shuffle=False(时间序列不能 shuffle)。如果特征里目标列的历史值被错误地归一化到接近 0,模型也会退化成均值预测。

现象三:预测值整体偏高或偏低,形状对但平移了。原因:差分还原时漏加了基准值,或者归一化逆变换时用错了 scaler。 解决:检查scaler.inverse_transform的输入维度是否和 fit 时一致。如果做了差分,预测后要累加回原始水平,累加起点用测试集第一个真实值。

现象四:遇到节假日预测完全失效。原因:训练集中节假日样本太少,模型没见过这种模式。 解决:节假日单独建模,或者把节假日标志作为强特征输入,并在损失函数里给节假日样本更高权重。另一种做法是训练时对节假日样本过采样。

现象五:GPU 上训练正常,CPU 上推理结果不一致。原因:PyTorch 某些操作在 CPU 和 GPU 上的数值精度不同,LSTM 的浮点累加顺序差异被放大。 解决:推理时统一用同一种设备,或者导出 ONNX 后固定算子实现。如果必须跨设备,在 CPU 上用 float64 做一次校准。

6. 用滚动预测和置信区间把 LSTM 回归结果变成可决策输出

单点预测给调度员的信息有限,他更想知道“明天晚高峰负荷大概率在哪个区间”。LSTM 本身输出的是点估计,但可以通过两种方式给出区间。第一种是 Monte Carlo Dropout:推理时保持 dropout 开启,多次前向传播取均值和标准差。第二种是分位数回归:把最后一层改成输出三个值,分别对应 0.1、0.5、0.9 分位数,用分位数损失训练。

class QuantileLSTM(nn.Module): def __init__(self, input_dim, hidden_dim=64): super().__init__() self.lstm = nn.LSTM(input_dim, hidden_dim, batch_first=True) self.fc = nn.Linear(hidden_dim, 3) # 三个分位数 def forward(self, x): out, _ = self.lstm(x) return self.fc(out[:, -1, :]) def quantile_loss(pred, target, quantiles=(0.1, 0.5, 0.9)): losses = [] for i, q in enumerate(quantiles): e = target - pred[:, i] losses.append(torch.max((q - 1) * e, q * e)) return torch.stack(losses, dim=1).mean()

分位数损失的关键是torch.max((q-1)*e, q*e),它让模型在低估和高估时受到不对称惩罚。训练完后,0.1 和 0.9 分位数之间的区间就是 80% 置信区间。实际用的时候,如果区间宽度突然变大,说明模型对当前输入不确定,调度端可以据此留更多旋转备用。

滚动预测是另一个实用技巧。不要一次性预测未来 96 个点,而是每次预测 1 个点,把预测值填回输入序列再预测下一个点。这样误差不会累积太快,但推理时间线性增长。折中方案是每次预测 4 个点,滚动 24 次覆盖一天。

我自己的习惯是:每次模型上线前,先用最近 7 天做滚动回测,把每天晚高峰的预测误差单独拉出来看。如果连续三天晚高峰误差超过 5%,不管整体 MAPE 多好看,都先回滚模型检查特征。这个习惯帮我拦住了好几次因为温度传感器漂移导致的系统性偏差。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询