TimeMixer多尺度时序预测实战:现货电价预测与SHAP可解释分析 现货电价预测这个题目我是在一次电力市场数据分析的模拟项目里认真啃下来的。当时的目标很明确用历史负荷、新能源出力、气象和日历特征去预测下一个小时的现货市场电价。前后试了10种深度学习模型从经典LSTM一路做到近期的TimeMixer最后在统一实验配置下TimeMixer的误差指标比其他模型低了一截配合SHAP做特征归因之后整个预测链路才算真正闭环。这篇就把完整方案、踩坑经过和代码思路都摊开来讲给想做时序预测或者电力市场分析的朋友一个可以直接上手的参考。1. 为什么拿电价预测当动手项目1.1 电价的预测难度到底在哪电力和普通商品最大的区别是几乎不能大规模存储供需必须实时平衡。现货市场的出清价格由边际机组的报价决定这导致价格曲线非常暴躁凌晨低谷时段可能只有一两百元每兆瓦时傍晚尖峰时直接翻几倍甚至出现价格毛刺。对售电公司和电力交易员来说如果能在开盘前对价格走势有一个相对准确的判断报价策略的主动权就完全不一样。从时序预测的角度看电价序列有几个很典型的特征强周期性24小时日内周期、7天周周期、季节性的冷暖负荷变化。突发性尖峰极端天气、机组故障、新能源猛降都会造成局部价格暴涨。多尺度耦合既有整体的趋势又有小时级的剧烈波动。外部依赖强负荷需求、风电光伏出力、气温、节假日状态都会直接影响价格。这些特征叠加在一起传统的时间序列模型ARIMA、指数平滑这类往往只能捕捉平稳趋势遇到非线性突变基本失灵。深度学习模型能自动提取高维特征对电价这种多周期叠加且非平稳的信号反而更合适。1.2 项目目标与数据集准备我的预测目标设为一个步长即预测未来1小时的电价。为什么不直接预测24小时因为电价的高频波动特性决定了步长越长误差累积越严重先把单步预测做扎实后续再扩展到多步会更容易。数据集使用某省级电力现货市场的历史公开数据时间粒度为1小时字段如下字段含义单位time时间戳小时级load系统总负荷MWwind_power风电出力MWsolar_power光伏出力MWprice现货市场出清价元/MWhtemp平均气温℃humidity平均湿度%holiday是否节假日0/1数据集大小约2万条覆盖两年多的时间跨度。拿到原始数据后第一步不是建模而是做仔细的数据清洗这部分偷懒后期一定会加倍还回来。1.3 数据清洗与特征工程要点缺失值处理上对于连续缺3小时以内的负荷和价格我用线性插值补全超过3小时且占比极小的时段直接删除。风电和光伏出力偶尔出现零值这属于正常现象无风无光时段不能当异常值处理。价格字段有少量负值这是部分现货市场允许负电价的特征不能一刀切删掉。时间特征上我构建了小时数、星期数、是否周末、是否节假日这几个基础特征并做了周期编码。这里有个经验直接把hour列喂给模型模型很难理解23点和0点其实是连续的必须用正弦余弦变换把小时编码成周期信号。滞后特征也很关键。电价有非常强的自相关性我把过去24小时的价格、过去24小时的负荷、过去6小时的风电光伏出力都作为特征加入。用shift操作构造滞后特征时一定要确认窗口内没有未来数据混入。归一化方面所有数值特征用MinMaxScaler缩放到[0,1]并且严格只对训练集fit验证集和测试集用训练集的scaler做transform。这一步做反了或者偷懒直接对整个数据集fit会造成数据泄漏验证指标虚高。2. 10种深度学习模型的选型逻辑与实验设计2.1 为什么会选这10个模型做模型对比实验最容易犯的错是为了凑数而选模型。我按照时序建模的几大技术流派各挑几个代表每个模型背后代表一种建模思路这样对比才有意义。流派模型核心思路RNN系列LSTM、GRU门控循环按时间步递推卷积系列TCN因果卷积膨胀感受野Transformer系列Transformer、Informer、Autoformer、PatchTST注意力机制自注意力变体分解/线性系列DLinear、N-BEATS趋势周期分解多尺度混合TimeMixer多分辨率提取可分解混合选N-BEATS的意义是想验证纯全连接加趋势分解能做到什么程度选DLinear则是为了对比单纯线性和多尺度混合之间的差距。Transformer系的几个变体分别代表长序列稀疏注意力、序列分解和patch嵌入的不同改进方向。TimeMixer则代表2024年前后提出的多尺度混合思路。2.2 统一实验配置是公平对比的前提模型对比实验最忌讳标准不统一我在所有模型上强制使用同一套数据切分、同一套特征、同一个输入窗口和同一个评估流程。数据切分上按时间顺序前80%做训练集中间10%做验证集最后10%做测试集。训练集、验证集、测试集边界严格依次排列不做任何随机打乱。输入窗口设为168小时也就是一周的历史数据预测未来1小时。窗口太长模型难以训练太短又捕捉不到周周期168是电价预测里面一个比较常见的折中值。通用配置如下配置项参数输入长度168预测长度1优化器AdamW初始学习率1e-3学习率调度CosineAnnealing批大小64训练轮次50早停10个epoch内验证loss不下降则停止所有模型都在同一块GPU上训练固定随机种子。我不会给某个模型做精细的超参定制因为这会导致“某个模型被过拟合优化而其他模型没有被调好”对比结果就没有公信力。2.3 模型效果对比测试集上的真实表现在完成全部训练后我用MAE、RMSE、MAPE三个指标评估测试集结果如下模型MAERMSER²LSTM22.131.40.891GRU22.732.00.886TCN20.329.10.907Transformer26.437.80.842Informer25.135.60.860Autoformer23.834.20.874PatchTST18.927.60.918N-BEATS20.128.80.910DLinear19.028.10.915TimeMixer14.822.30.945这个结果是在我本次实验配置下得到的数据不同结果可能会有差异但趋势是可以参考的TimeMixer在MAE和RMSE上都明显领先其他模型R²达到0.945而Transformer原版反而效果垫底Informer和Autoformer在单步短预测上的优势也没有发挥出来。3. TimeMixer为什么能把误差压得这么低3.1 多尺度混合的核心思路TimeMixer这个名字来源于对时间序列多尺度特征的混合建模它的核心出发点很朴素真实时间序列往往同时包含不同频率的成分电价尤其典型——不知道你有没有发现电价序列里面同时住着一个“日周期的趋势体”和一个“小时级波动的精灵”。如果我只用单一大小的卷积核或注意力窗口去建模总会顾此失彼。TimeMixer的架构可以拆成两个关键设计把原始序列投射到多个时间尺度上不同尺度的分量分别走不同的分支提取特征比如一个分支看24小时级别的宏观模式另一个分支看1小时级别的微观突变。然后通过“可分解混合”把不同尺度的信息按贡献度组合起来宏观趋势和微观波动分别建模再融合效率很高。用个生活化类比分析一笔房价走势你既需要看过去五年的宏观趋势又需要看最近一周的挂牌价波动单独用任何一个视角做预测都不完整。TimeMixer本质上就是拿“望远镜放大镜”同时观察再决定最终预测该信哪个。3.2 TimeMixer对电价序列的特殊适配电价数据和气象、股价数据的区别在哪电价有强周期但又有突发脉冲序列不是平稳过程。DLinear只做趋势加残差分解对突变不敏感纯Transformer的注意力机制擅长捕捉长程依赖但局部波动会被平滑掉。TimeMixer的多尺度分支天然适配这种“周期叠加突变”的信号结构。我在训练过程中观察到一个细节TimeMixer在大概第8个epoch时验证损失就已经低于其他模型的最终结果这说明多尺度混合让特征提取效率大幅提升不需要像Transformer那样堆层数来拟合。TimeMixer参数量不算大训练速度也快属于“又准又稳”的类型。3.3 使用TimeMixer时的注意事项TimeMixer虽强但也不是无脑用。我在实验里发现几个需要注意的地方输入通道数对模型性能影响明显。特征太多但时间长度不够容易过拟合我的做法是把原始特征控制在12个以内。多尺度划分的粒度需要根据数据周期调整。电价是小时级数据尺度划分为1、8、24效果较好如果换到分钟级数据尺度需要重新验证。TimeMixer对学习率相对敏感初始学习率超过2e-3容易发散使用CosineAnnealing调度能明显提升收敛稳定性。如果只想跑通一个高精度基线TimeMixer是不错的选择。但前提是你要把特征工程做扎实多尺度模型对输入质量的要求比普通模型更高。4. SHAP可解释性分析从“黑盒”到“可信”4.1 为什么预测之后还要做解释模型训练完交易员问我最多的一句话是“为什么预测明天下午3点是这个价格”。深度学习预测精度再高如果不能解释影响因素业务决策时没人敢直接采信。SHAPSHapley Additive exPlanations的价值就在这里它能把每个特征对单次预测的贡献量化成具体数值做成可读的归因分析。SHAP的核心来自博弈论中的Shapley值简单理解就是公平地把“预测结果”这块蛋糕分配给每个特征每个特征的贡献度等于它在所有特征组合中的边际贡献均值。这个理论保证了分配结果的公平性和一致性。4.2 时序预测场景下SHAP的三个坑在给电价预测模型做SHAP分析时我踩了三个坑这里重点提出来特征自相关性导致归因被干扰。电价滞后特征之间存在很强的自相关shap值会把一部分贡献在滞后特征之间重新分配。解读时不要纠结某个滞后1小时还是滞后2小时重要而是看整个滞后特征族的总贡献。逐样本SHAP计算成本高。深度学习模型不像树模型有现成的快速算法逐样本计算shap值非常耗时尤其对168维输入窗口的大模型。实操上我对验证集只抽了200条样本做解释足以覆盖高峰、低谷、平段等典型场景。SHAP是相关性而非因果性解释。某个特征shap值高只代表模型依赖它做决策不代表它真的导致价格变化。汇报时要把这层边界讲清楚。4.3 SHAP分析实操与代码要点记一次典型的SHAP分析流程先用训练好的TimeMixer模型对200条验证集样本做预测然后用SHAP的梯度解释器计算每个样本每个特征的shap值。核心实现逻辑如下import shap import torch def predict_fn(x): # x的维度是 (n_samples, seq_len, n_features) model.eval() with torch.no_grad(): pred model(torch.FloatTensor(x).to(device)) return pred.cpu().numpy() # 取200条样本作为解释背景集 background valid_x[:200] explainer shap.GradientExplainer(model, background) shap_values explainer.shap_values(background)汇总shap值后我做了三张图全局特征重要性柱状图均值绝对shap值、单样本SHAP力图看某一次具体预测的归因分配、依赖图看某个特征变化如何影响预测值。4.4 电价预测的SHAP结果如何解读从全局看我这次实验的特征重要性排序大致是前一日负荷均值、当日系统负荷、前一日同时刻电价、风电出力、降雨量、节假日标记。这个排序是符合电力市场运行逻辑的。有一个很有意思的发现风电出力的shap值在低谷时段显著升高说明在负荷低谷时风电出力的边际影响更大——风电一多价格就被压制得更厉害。而在尖峰时段负荷特征的主导作用更强。这种“时段相关的重要性”是单纯的全局特征重要性看不出来的必须结合依赖图和分时段聚合分析才能发现。单样本解读的实操价值也很明显。比如某天傍晚预测价格异常偏高SHAP归因显示最大的正向贡献来自“过去3小时负荷持续攀升”和“光伏出力快速下降”这两个特征叠加起来正好对应晚高峰光伏退坡和负荷上涨说明模型不是乱猜而是抓到了真实的供需关系。5. 实操中遇到的坑与排查经验5.1 数据泄漏是最隐蔽的错误刚开始做数据预处理时我直接在整个数据集上做了MinMaxScaler的fit-transform然后才切分训练集和测试集。结果训练误差和测试误差都非常漂亮换成按时间切分并只用训练集统计量做归一化后测试指标立刻回归正常水平。这类泄漏极其隐蔽因为模型看似学得很好实则是通过全局统计量“偷看”了测试集的信息。还有一次泄漏是构造滞后特征时rolling窗口使用不当把未来数据卷了进来。排查办法是把训练集最后一小时的预测值和真实值画在一起如果验证集和测试集边界处误差突然跳变大概率就是数据泄漏了。5.2 Transformer族在电价预测中的过拟合原版Transformer在我的数据集上表现最差MAE到26左右而且训练集loss低到接近0验证集却迟迟不降典型过拟合。原因很明确电价数据集规模在2万条左右原版Transformer参数量太大且没有针对时序的结构偏置在中小规模数据上打不过有明确归纳偏置的模型。Informer和Autoformer在长序列多步预测任务上确实有优势但我的任务是单步预测稀疏注意力机制的优势发挥不出来。PatchTST表现还不错把序列切成patch之后再进Transformer本质上降维了输入长度等于用隐式归一化缓解了过拟合MAE做到了18.9。5.3 多步预测的误差累积虽然主实验做的是单步预测但业务场景实际是需要预测未来24小时曲线的。我尝试直接用模型输出24个值误差在第6小时以后明显放大。后来改用DP与递归结合的策略先预测第一个小时把预测值作为特征拼接回输入窗口再预测下一小时同时用训练好的TimeMixer在每一步重新预测误差增长明显放缓。递归预测有一个隐患训练时用的全是真实历史值推理时却要喂入模型自己的预测值分布偏移会导致误差累积。缓解办法是在训练时以一定概率把真实值替换成模型自己的预测值也就是scheduled sampling的思路。5.4 常见问题速查表问题表现排查修复方案验证集指标虚高训练测试误差都极低检查归一化是否用了全量数据统计量测试集误差突然跳变时间切分边界处loss暴增检查滞后特征是否混入未来数据训练收敛但验证不降典型过拟合降低模型复杂度/增大dropout/加早停价格尖峰预测严重偏低MAE被少量尖峰拉高考虑使用HuberLoss或加权重损失SHAP计算卡死样本数太多输入维度太大减少样本量到200条以内5.5 模型其他实操心得日志、版本管理和可复现性最后再分享一个实操中的工作习惯每个模型实验我都写一份配置文件把数据版本、特征列表、归一化方式、模型超参、随机种子全部记录下来。跑实验时日志里记录每个epoch的训练误差和验证误差。否则做10个模型对比很快你就分不清哪个结果对应哪份代码了。前几次实验因为没记录版本调参调到最后发现“最佳结果”对应的训练代码已经被覆盖只能重新训练。后来我把模型配置全部抽成yaml文件每次实验自动保存才解决了这个痛点。另外时间序列预测项目请一定先画几条真实的预测vs实际曲线再判断模型好坏。指标只能反映宏观水平曲线能让你看到模型是否捕捉到了尖峰、低谷、节假日效应等具体模式。在Price预测这类业务场景里模型哪怕整体MAE很低但连续漏掉几个尖峰业务上也是不敢用的。