☰
电力负荷预测实战:AutoTS自动化时间序列建模与泰迪杯B题代码复现
2026/9/25 3:06:04 网站建设 项目流程

简介:这份资源是2022年第十届泰迪杯数据挖掘竞赛B题的完整AutoTS建模代码,面向参加数据挖掘与时间序列预测竞赛的学生、电力负荷预测方向的研究者,以及希望用自动化框架替代手工调参的Python开发者。压缩包共25个文件,以13个csv结果数据、8个ipynb笔记本、3个py脚本和1个xls表格为主,整体约2.31MB,覆盖数据清洗、模型训练到预测结果输出的完整链路。目前已有1442人学习下载。代码围绕AutoTS自动时间序列框架展开,包含模型选择、超参数优化与特征工程等关键环节,并针对普通工业、大工业、非普通工业、商业等不同用电类型分别给出最大与最小总有功功率的预测结果,同时提供未来三个月逐日预测数据。相比LSTM与ARIMA,该方案在拟合程度和精确度上均有提升,训练更快、使用门槛更低,适合作为赛题复盘、方法对比与电力负荷预测实践的参考模板。

1. 电力负荷预测的 AutoTS 实战:从泰迪杯 B 题代码包说起

2022 年第十届泰迪杯数据挖掘竞赛 B 题,做的是电力负荷预测。赛题给了某地区若干类用电负荷的历史序列,要求预测未来三个月每天的负荷值。当年很多队伍卡在两个地方:一是 LSTM 调参调到怀疑人生,二是 ARIMA 的平稳性检验和定阶反复翻车。而这份代码包走的是另一条路——用 AutoTS 做自动化时间序列建模,把模型选择、特征工程、超参搜索交给框架,最终在拟合程度和精确度上都压过了 LSTM 和 ARIMA。这份资源就是当年那套完整可跑的代码,包含数据清洗、两大问各小问的建模脚本、结果 CSV 和未来三个月预测输出,适合正在做电力负荷预测、想找一个能直接复现的 AutoTS 基线的人。下面我按「它是什么、怎么跑、坑在哪」拆开讲。

2. AutoTS 凭什么在电力负荷上压过 LSTM 和 ARIMA

2.1 三类模型在负荷序列上的真实差异

电力负荷序列有几个典型特征:日周期、周周期、节假日突变、温度驱动的非线性波动,以及长期缓慢增长的趋势。这三类模型对这几个特征的适配方式完全不同。

ARIMA 是线性模型,它的前提是序列经过差分后近似平稳。日周期和周周期需要靠季节性差分或者外生变量硬塞进去,遇到节假日那种尖峰,线性假设直接失效。LSTM 能学非线性,但它对输入窗口长度、层数、学习率极其敏感,而且训练成本高,一个序列跑一轮可能几十分钟,调参周期长。AutoTS 的思路不一样:它把 ETS、Prophet 类模型、ARIMA 变体、以及基于树的回归器(随机森林、XGBoost 这类)都纳入候选池,用交叉验证自动挑,还自动做差分、去趋势、加周期特征。

提示:AutoTS 不是单一模型,而是一个「模型搜索 + 集成」的框架,它的优势来自候选池的多样性,而不是某个模型特别强。

对电力负荷这种既有强周期又有非线性突变的序列,AutoTS 的候选池天然覆盖了线性和非线性两端,交叉验证又会按实际误差挑,所以它比单独一个 LSTM 或单独一个 ARIMA 更稳。这也是这份代码包在 B 题里精度更高的根本原因,不是玄学,是模型选择机制在起作用。

2.2 代码包结构与各文件职责

拿到压缩包先别急着跑,先认清文件。这份资源里文件不少,按职责可以分成四类:

文件/目录职责
数据清洗.ipynb原始负荷数据清洗,输出洗好的数据.csv
洗好的数据.csv清洗后的建模输入
AutoTS模型.ipynb / AutoTS模型.py第一大问两个小问的主建模脚本
第二大问第二小问.py / .ipynb第二大问第二小问建模
第二大问*结果.csv各类负荷的最大/最小总有功功率预测结果
未来三个月每天.xls / auto未来三个月每天最大(小)值.csv未来三个月逐日预测输出

这里要注意,代码包里同时存在 .py 和 .ipynb 两种形式,内容基本对应。.py 适合命令行批量跑,.ipynb 适合在 Notebook 里逐格调试看中间结果。第一次上手建议先用 .ipynb,能直观看到每一步的 DataFrame 长什么样,确认数据没问题再切 .py 跑全量。

2.3 环境依赖与安装

AutoTS 对版本比较挑,尤其是它依赖的 statsmodels、pmdarima、scikit-learn。常见做法是单独建一个虚拟环境,避免和系统里已有的包打架:

# 建虚拟环境,Python 3.8~3.10 兼容性最好 python -m venv autots_env source autots_env/bin/activate # Windows 用 autots_env\Scripts\activate # 核心依赖,版本别乱升 pip install autots==0.5.* pandas numpy scikit-learn statsmodels pip install pmdarima xlrd openpyxl jupyter

参数说明:autots 锁在 0.5.x 是因为 0.6 之后部分 API 有调整,老代码直接跑可能报参数名错误;xlrd 是读 .xls 用的,openpyxl 读 .xlsx;pmdarima 提供 auto_arima,AutoTS 内部会调用。装完先python -c "import autots; print(autots.__version__)"确认能导入,再往下走。

3. 从洗好的数据到 AutoTS 建模:完整复现步骤

3.1 数据清洗环节要看什么

数据清洗.ipynb 干的事不复杂,但决定了后面模型的上限。电力负荷原始数据常见的问题是:缺失值、异常尖峰(采集故障)、时间戳不连续、单位不统一。清洗脚本一般会做插值补缺、按 3σ 或 IQR 剔除异常、重采样到统一频率。

import pandas as pd import numpy as np # 读原始数据,注意 .xls 要指定引擎 df = pd.read_excel("原始负荷数据.xls", engine="xlrd") # 时间列转 datetime 并设为索引,这是时间序列的硬要求 df["时间"] = pd.to_datetime(df["时间"]) df = df.set_index("时间").sort_index() # 缺失值用时间插值,比均值填充更符合负荷的连续性 df["负荷"] = df["负荷"].interpolate(method="time") # IQR 剔除异常尖峰 q1, q3 = df["负荷"].quantile([0.25, 0.75]) iqr = q3 - q1 lower, upper = q1 - 1.5 * iqr, q3 + 1.5 * iqr df["负荷"] = df["负荷"].clip(lower, upper) df.to_csv("洗好的数据.csv", encoding="utf-8-sig")

逻辑说明:时间插值利用负荷的连续性,比全局均值合理;IQR 用 clip 而不是直接删行,是为了保持时间索引连续,删行会让后面按频率建模出问题。参数上 1.5 倍 IQR 是标准阈值,如果数据本身波动极大,可以放宽到 3 倍,否则会把真实的高峰负荷当异常砍掉。

注意:清洗后的 csv 一定要检查行数和时间跨度,如果插值后出现整段平坦的直线,说明原始缺失太多,插值已经失真,这种段落在建模前要单独标记。

3.2 AutoTS 核心建模代码

这是整份资源的核心。AutoTS 的用法比想象中简单,关键在几个参数:模型候选列表、集成方式、预测长度、交叉验证轮数。

from autots import AutoTS import pandas as pd # 读清洗后的数据,宽表格式:索引是时间,列是各负荷类型 df = pd.read_csv("洗好的数据.csv", index_col=0, parse_dates=True) model = AutoTS( forecast_length=90, # 未来三个月,按天约 90 天 frequency="D", # 日频 ensemble="simple", # 简单集成,多个模型加权 model_list="default", # 默认候选池,含 ETS/ARIMA/树模型 max_generations=5, # 进化搜索代数,越大越慢越准 num_validations=2, # 交叉验证轮数 validation_method="backwards", # 从末尾往前切验证集 n_jobs="auto", # 并行核数 ) model = model.fit(df) # 输出各候选模型的评分,看谁被选中 print(model.results()) # 预测 prediction = model.predict() forecast = prediction.forecast forecast.to_csv("未来三个月每天.csv", encoding="utf-8-sig")

逻辑说明:forecast_length 设 90 对应赛题「未来三个月每天」;frequency="D" 告诉框架按日频处理,如果数据是小时级要改成 "H";ensemble="simple" 是加权平均,比 "horizontal" 更省内存;max_generations 控制搜索深度,5 代是精度和耗时的折中,赛题环境里再往上加收益递减。model.results() 会打印每个候选模型的 MASE、SMAPE 等指标,这是判断模型有没有选对的关键,别跳过。

参数怎么改:如果某类负荷预测误差明显偏大,先把 model_list 从 "default" 换成显式列表,比如["ETS", "ARIMA", "LastValueNaive", "RollingRegression"],缩小搜索范围再看结果;如果数据量小,num_validations 降到 1,否则验证集切太碎,每轮训练样本不够。

3.3 多类负荷批量预测与结果落盘

B 题第二问涉及普通工业、大工业、非普通工业、商业等多类负荷,每类都要出最大和最小总有功功率预测。逐列循环是最直接的做法:

import os from autots import AutoTS df = pd.read_csv("洗好的数据.csv", index_col=0, parse_dates=True) os.makedirs("results", exist_ok=True) for col in df.columns: series = df[[col]] # 保持 DataFrame 格式,AutoTS 要二维输入 m = AutoTS(forecast_length=90, frequency="D", ensemble="simple", max_generations=3, num_validations=1) m = m.fit(series) fc = m.predict().forecast fc.to_csv(f"results/{col}_预测.csv", encoding="utf-8-sig") print(col, "done")

逻辑说明:AutoTS 要求输入是二维 DataFrame,所以用df[[col]]而不是df[col],这是新手最容易踩的格式坑。每类负荷单独建模,是因为不同负荷的周期结构差异大,混在一起建模会互相干扰。max_generations 降到 3 是为了批量跑时控制总耗时,如果只跑单列可以调回 5。

4. 避坑与排查:跑这份代码最容易翻车的五个点

4.1 报错 KeyError 或列名对不上

现象:读 csv 后 fit 直接抛 KeyError,或者提示找不到时间列。原因:洗好的数据.csv 的索引列在保存时被写成了普通列,或者编码不对导致中文列名乱码。解决:读的时候显式指定index_col=0, parse_dates=True,保存时统一用encoding="utf-8-sig",避免 Excel 打开乱码。如果列名是中文,确认 pandas 读进来后df.columns打印正常。

4.2 预测结果全是同一条直线

现象:forecast 输出每一行数值几乎一样。原因:多半是数据里存在大段缺失被插值成常数,或者 frequency 设错(比如数据是小时级却设了 "D"),框架把序列当成无周期噪声。解决:先画一下历史序列,确认周期形态;检查 frequency 是否和数据实际采样间隔一致;如果确实有长缺失段,考虑截断或换用能处理缺失的模型。

4.3 训练时间过长甚至卡死

现象:fit 跑几十分钟没动静。原因:max_generations 设太大、num_validations 太多、n_jobs 没开并行,或者候选池里某个模型在长序列上极慢。解决:先把 max_generations 降到 2~3 试跑,确认流程通;n_jobs 设成 CPU 核数减一;必要时用 model_list 显式限定几个快模型,排除掉慢的。

4.4 不同负荷类型结果差异巨大

现象:商业负荷预测很准,工业负荷误差很大。原因:工业负荷受生产排班影响,突变多,周期不如商业规律,AutoTS 默认候选池可能没覆盖到。解决:对这类序列单独调 model_list,加入对突变敏感的模型;或者先做差分去掉趋势再喂给模型。别指望一套参数打天下。

4.5 .ipynb 和 .py 结果不一致

现象:Notebook 里跑出来的结果和命令行跑 .py 不一样。原因:Notebook 里可能残留了之前单元格的变量,或者随机种子没固定。解决:跑 .py 前确认没有依赖 Notebook 内存状态;在脚本开头固定np.random.seed(42);AutoTS 内部有随机性,固定种子能让结果可复现。

5. 进阶技巧:让 AutoTS 结果可复现、可对比

跑通只是第一步,真正要用这份代码做对比实验,得解决可复现和可对比两个问题。我一般会在建模前固定随机种子,并把每次实验的配置和结果指标一起落盘,方便回头对比不同参数的效果。

import numpy as np, json, pandas as pd from autots import AutoTS np.random.seed(42) # 固定种子,保证同配置结果一致 config = {"forecast_length": 90, "frequency": "D", "ensemble": "simple", "max_generations": 5, "num_validations": 2, "seed": 42} df = pd.read_csv("洗好的数据.csv", index_col=0, parse_dates=True) m = AutoTS(**{k: v for k, v in config.items() if k != "seed"}) m = m.fit(df) # 把候选模型评分和配置一起存,方便复现对比 results = m.results() results.to_csv("model_scores.csv", encoding="utf-8-sig") with open("run_config.json", "w") as f: json.dump(config, f, ensure_ascii=False, indent=2) # 验证:用回测误差判断模型是否真的比基线好 print(m.results().head(10))

逻辑说明:种子固定后,同一份数据同一套参数,两次运行结果应当一致,这是做对比实验的前提。model_scores.csv 里存的是各候选模型的交叉验证误差,看它比只看最终预测值更有信息量——如果最优模型和第二名差距很小,说明这份数据本身区分度不高,别过度解读精度提升。run_config.json 记录配置,下次想复现某个结果直接读这个文件。

验证方法上,我习惯做两件事:一是把 AutoTS 的预测和「朴素法」(直接用上周同一天的值)对比,如果 AutoTS 连朴素法都赢不了,说明数据或配置有问题;二是把预测区间也画出来,AutoTS 的 predict() 会返回 upper/lower forecast,区间过宽说明模型对这段序列没把握,精度数字好看也不能信。

提示:赛题类代码包最容易犯的错是「只跑一次就下结论」。AutoTS 的搜索有随机性,多跑几次取平均,或者固定种子跑,结论才站得住。

从那以后我每次拿到这类竞赛代码包,都强制先固定种子、存配置、跑一遍基线对比,再谈精度。希望这份拆解帮到你,代码包里的数据清洗和 AutoTS 建模脚本可以直接拿去改,重点是把避坑那五条过一遍再跑全量。

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

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

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

立即咨询