风电场的功率区间预测,简单说就是把原来只能输出一条预测曲线的模型,改造成能输出“明天每个时刻功率大概率落在哪个区间”的多分位数模型。做这个方向的人可能都有体会:先把QR分位数回归和时序模型搭起来并不难,难的是从QR-GRU一路升级到QRCNNBiGRUAttention之后,如何把区间指标做得既覆盖率达标、又宽度足够窄。这篇就是我把这套模型组合从数据处理到训练评估完整跑下来的记录,适合正在做风功率预测、光伏预测或者任何新能源时序区间预测的人参考。
1. 区间预测需求与分位数回归原理
1.1 为什么点预测满足不了调度需求
风功率预测最直观的形式是给出一条未来的功率曲线,也就是点预测。但实际运行中,调度部门更关心的是极端场景:如果实际功率明显低于预测值,备用容量够不够;如果实际功率明显高于预测值,线路和储能会不会过载。点预测只能给出“最可能的值”,无法回答“最坏情况可能到多少”。
区间预测刚好补上这一点。它输出的是一组上下界,比如90%置信水平下,某个时刻功率有90%的把握落在[32MW, 78MW]之间。有了这个区间,调度就可以把风险量化:区间越宽,需要的旋转备用越多,运行成本越高;区间越窄且还能覆盖住实际值,说明模型对不确定性的刻画越精准。
这和气象预报里的概率预报是一个思路。风电功率受大气边界层湍流影响,本质上就是随机过程,点预测做得再好也只是条件期望的估计,区间预测才是把不确定性显式建模。
1.2 分位数回归的核心思想
分位数回归(Quantile Regression,QR)最早是统计学里用来估计条件分位数的工具,和普通最小二乘回归的区别在于:OLS估计的是条件期望E(Y|X),QR估计的是条件分位数Q_τ(Y|X)。τ取0.1,得到的就是条件分布的10%分位点;τ取0.9,得到的就是90%分位点。把这两个分位点合起来,就是80%置信区间。
神经网络做分位数回归,只需要把最后一层输出改成3个神经元,分别对应τ=0.1、0.5、0.9,然后用分位数损失函数训练。损失函数是pinball loss,也叫分位数损失,公式长这样:
ρ_τ(u) = τ·max(u, 0) + (1-τ)·max(-u, 0)
这里的u是真实值减预测分位数(y - q_τ)。这个loss非常有意思,它是不对称的。当τ=0.1时,真实值落在预测分位数下方的惩罚是π×0.1,而上方的惩罚为自己不小于0.9,所以模型会刻意把下界分位数压低一点,宁可偶尔下界低于真实值,也不太愿意把下界抬太高。正是这种不对称惩罚,让不同τ的头学会了不同的分位数,而不是都收敛到中位数附近。
我实际试过把τ改成0.025和0.975做95%区间,效果也还可以,但当样本量不够大的时候,极端分位数容易过拟合,产生特别宽的区间。通常风电预测竞赛和论文里用τ=0.1和0.9比较常见,信息量够用且训练稳定。
1.3 为什么不用高斯分布假设
有人会问,既然要估计分布,为什么不假设功率服从高斯分布,用神经网络输出均值和方差,然后构造区间同时拔高均值方差就行?理论上可以,但实际效果往往不好。
风电功率的条件分布有几个特点:一是有界,功率天然被限制在0到额定容量之间,接近额定值时分布严重偏态,左侧拖尾很长;二是受爬坡事件影响,某些时段分布呈现出双峰甚至多峰形态,简单的高斯假设完全不能刻画。分位数回归是一种非参数方法,它不对分布形态做任何假设,只要求数据量足够,就能逼近任意形态的条件分位数。另外分位数回归还可以通过多个τ值的组合,直接重建整个条件分布的形状,这在评估和调度里非常有价值。
2. 八个模型架构拆解与选型思路
2.1 从GRU、LSTM到BiGRU:基础循环网络的对比
QRGRU和QRLSTM是这套模型体系里的baseline。GRU和LSTM都是门控循环网络,用来建模时间序列的长距离依赖。从区间预测角度看,GRU参数量少大约三分之一,训练速度快,在小数据集上不容易过拟合;LSTM表达能力理论上更强,但需要更多数据支撑,否则区间宽度容易被训练噪声带偏。
但是单向GRU只能利用过去的信息。风功率序列中,当前时刻的功率往往与前后几个点强相关,比如爬坡过程是从低功率连续上升,只看历史看不到“正在爬坡”的完整形态。BiGRU把正向和反向两个方向的特征拼接起来,在风功率这类强自相关场景里通常能稳定提升覆盖率。QRBiGRU的覆盖率比QRGRU我实测能提升1-3个百分点,代价是参数量翻倍、训练时间增加。
2.2 TCN与BiTCN:另一种时序建模路径
TCN(时序卷积网络)这几年被越来越多用在长序列建模里。它的核心是因果空洞卷积:通过空洞率不断加大的卷积核,感受野指数级扩大,同时每个输出时刻只依赖过去的信息,避免了RNN那种顺序推演的瓶颈。TCN对并行计算非常友好,GPU利用率高,训练速度快。
QRTCN和QRBiTCN的区别在于,TCN只有因果卷积,BiTCN则再做一次反向的因果卷积(即从未来向过去扫描),然后拼接两个方向的特征。我在实际应用中发现,BiTCN在捕捉爬坡事件上比GRU更敏锐,因为TCN的卷积核天然擅长提取局部波形特征,而爬坡就是一种特定波形。但TCN一旦感受野设置过大,容易把响应变得平滑,区间宽度倒是小了,覆盖率却掉得明显,这个尺度平衡后面会细说。
2.3 CNN-BiGRU:让卷积做特征提纯,让循环网络做时序推理
CNNBiGRU这个结构在序列预测里算中规中矩的组合。一维卷积在输入序列上滑动,相当于在时间维度上提取局部特征,比如风速突变的前兆模式、功率的短期波动形状。卷积输出再接一个BiGRU,负责在这些局部特征上做长距离的时序建模。
从区间预测视角看,CNN的作用不仅仅是特征提取,还有去噪。原始风电功率在分钟级尺度上有很多高频抖动,如果直接丢给BiGRU,模型容易把噪声的方差也学进去,导致区间过宽。先用卷积做一次局部平滑和特征抽取,BiGRU接收的是相对稳定的特征序列,学习到的条件分位数更平滑、更紧凑。权重共享的小卷积核参数也少,还能轻微正则化。
2.4 注意力机制:让模型自动聚焦关键时间步
CNNBiGRUAttention是在CNN-BiGRU后面接了一个注意力层。注意力机制做的事情很简单:对BiGRU输出的每个时间步计算一个权重,然后把所有时间步的特征做加权求和。权重通过一个可学习的打分函数计算,网络自动学会“哪些历史时刻对当前预测最重要”。
实际体验非常明显。在风电预测中,当模型要预测一个即将到来的爬坡起点时,注意力权重会主要集中在相似爬坡历史片段上;而在平稳风况时段,注意力权重则分布比较均匀。从区间指标看,注意力模型的PINAW(区间归一化平均宽度)通常能比不带注意力的CNN-BiGRU收窄3-5%,覆盖率还不会明显下降。代价是增加了少量参数和几行代码,属于性价比很高的增强。
2.5 为什么同时测那么多模型:消融对比的价值
粗看会有疑问:GRU、LSTM、BiGRU、CNN-BiGRU、注意力,搞这么多模型,是不是为了堆工作量?实际做研究或工程选型时,这套模型阶梯恰好构成一条完整的消融链:
第一层,GRU与LSTM对比,验证选哪个基础循环单元。 第二层,单向与双向对比,验证未来信息回溯的收益。 第三层,纯RNN与CNN+RNN对比,验证卷积特征提取的价值。 第四层,CNN-BiGRU与CNN-BiGRUAttention对比,验证注意力机制对区间收敛的作用。 第五层,TCN与BiTCN作为另一条技术路线,验证空洞卷积在该场景下是否有独立价值。
只有把这条阶梯跑完,才能回答“最终模型指标的提升到底来自哪个结构改动”。直接上一个最复杂的模型,即使指标好看,也很难说明是哪一部分贡献的。这在课题答辩或者项目评审里,是一个特别加分的论证方式。
3. 数据准备与预处理全流程
3.1 数据来源与物理量选择
风电场区间预测的输入数据,主力是两类。第一类是场站实测历史数据,包括风机机舱风速、功率、风向等,SCADA系统直接采集。第二类是NWP数值天气预报,因为风功率预测本质上是“未来天气->未来功率”的映射,完全依赖历史外推在天气突变时必然失效。
我这次用的是某风电场的SCADA数据,采样间隔15分钟,每天96个点,覆盖一整年。广告特征包括风速、风向正弦、风向余弦、温度、功率,目标变量是功率。把风向拆成正弦和余弦,是为了避免角度从359度跳变到0度导致的突变问题,这一步在特征工程里容易被忽略,但对风向依赖敏感的风电场很关键。
3.2 数据清洗与物理一致性检验
SCADA原始数据的脏数据集中在三类:
第一类是限电段。电网调度限制出力时,风速明明很高但功率被压得很低,风速-功率散点落在正常功率曲线的下方。如果不处理,模型会学到“高风速可能对应低功率”的错误分位数关系,区间会显著变宽。处理方式是先做风速分箱,在每个风速箱内计算功率中位数和正常范围,偏离超过3倍四分位距的点标记为限电点,直接剔除。限电段占数据量超过3%时,建议单独建模或者标记后让模型学习一个工况特征,而不是简单剔除。
第二类是停机段。风机检修、故障、并网脱网都会导致功率持续为0。停机点和自然低风速导致的0功率要从物理逻辑区分:风速低于切入风速时0功率是正常的,风速高于额定风速但功率为0就是异常。处理方式是结合风速和功率的差值做规则判定。
第三类是野值点。通信干扰、传感器故障产生的瞬时尖峰。这类点用滚动窗口的中值滤波就能处理:每个点与前后半小时窗口的中位数比较,偏差超过阈值就替换为窗口均值。
数据清洗是区间预测的隐形胜负手。我对比过清洗前后同一模型的结果,清洗后PICP提高接近2个百分点,PINAW下降了近5个百分点,原因就是限电段会严重扭曲高风速区间的分位数估计。
3.3 滑动窗口构造与数据集划分
模型输入需要构造成序列样本。我用的是过去24个时间点(6小时)预测未来1个时间点,即window=24,horizon=1。滑动窗口构造出来的样本数量非常多,一年96×365=35040个点,能生成近35000个样本,足够训练所有模型。
对于更长的预测时效,比如未来4小时甚至24小时预报,工程上常用两种方案:一种是用递归预测,把上一次的输出当作下一次的输入,但误差会累积;另一种是直接多输出,即改变网络输出维度,同时预测未来多个时刻的分位数,但这样做训练收敛更慢、区间也更容易失真。我这次跑的是单步预测框架,如果你想扩展多步,建议用seq2seq或者直接加输出头来对比。
数据划分必须按时间顺序。先用前10个月做训练集,接着1个月做验证集,最后1个月做测试集。打乱数据听起来像能提升指标,属于严重的数据泄漏,因为每一时刻的功率与相邻时刻高度相关,一旦训练集混入测试时段的数据,评估结果就完全失真。分位数回归对数据的时序性更敏感,这点务必要注意。
3.4 归一化与数据分布形态处理
输入特征先做min-max归一化映射到[0,1]区间。目标变量功率同样归一化到[0,1]范围。归一化对神经网络很重要,分位数回归的pinball loss对尺度是敏感的,同样的权重更新步长,在不同尺度上表现差异很大。
值得注意的是,功率有大量0值。如果直接min-max归一化,0值会聚在区间左端点,形成高度不平衡的分布。处理办法是保留0值,不做特殊的截断处理,因为分位数回归是逐样本的损失累积,0值过多会导致低分位数(τ=0.1)被训练得过于接近0,虽然看着负偏度对了,但中位数以上区间的拟合不足。为了平衡,我在训练时对功率接近0的样本做了轻度降采样,让模型把更多容量用在中高功率段的区间拟合上。
4. 实验环境与训练配置
4.1 环境与依赖版本
我用的是PyTorch框架,版本2.1,CUDA 12.1,单张RTX 3090显卡。Python版本3.9。所有模型都是手工搭建的,没有用现成的时间序列库,因为模型内部的连接方式需要针对分位数输出做定制调整。
训练时的超参数统一配置如下:
| 参数名 | 数值 | 说明 |
|---|---|---|
| 优化器 | Adam | 默认betas |
| 初始学习率 | 1e-3 | 使用cosine退火 |
| Batch size | 128 | 兼顾显存和收敛稳定性 |
| Epochs | 100 | 早停阈值patience=10 |
| 隐藏单元数 | 64 | BiGRU/BiLSTM/TCN统一维度 |
| CNN卷积核 | 3 | 一维卷积核大小 |
| CNN通道数 | 32 | 卷积输出特征图数量 |
| Dropout | 0.2 | 所有RNN/TCN层后使用 |
| 分位数 | 0.1 / 0.5 / 0.9 | 三个输出头 |
这里隐藏单元统一64,是为了保证模型之间的对比公平。有的模型体验上把GRU升到128个隐藏单元后指标会更好,但那就不是“结构差异”带来的提升了,而是参数量带来的提升,在对比分析里说不清楚。公平的消融实验必须控制所有可控变量。
4.2 分位数损失组合方式
三个分位数对应的输出头,共享前面所有的特征提取层,最后一层分别接全连接层输出单个值。在PyTorch里写loss的时候,对不同分位数分别计算pinball loss,直接累加或者求平均都可以。我实测累加会导致梯度尺度偏大,训练初期波动较大,所以统一用三头损失的平均值。
实验里我不用加权。有的文献会给低分位数更高的权重,以改善区间下界的覆盖率,但那样会牺牲区间宽度。先跑等权重版本,观察指标后再按需调整,是比较理性的做法。
4.3 训练过程监控要点
训练时除了看总损失,我额外计算验证集PICP和PINAW。分位数损失下降不代表区间指标正常,比如模型可能收敛到“所有样本输出同一个宽区间”,这种情况下损失不高,但区间完全失去意义。
模型训练100个epoch耗时大概情况:QRGRU最快,约10分钟;QRCNNBiGRUAttention最慢,约40分钟。这个量级的训练成本可以接受,对比实验总共也就3到4小时。如果数据量更大,建议用学习率衰减配合早停,我在第36轮左右就观察到BiTCN系列的验证损失不再下降,早停可以省下不少时间。
5. 区间预测评估指标体系
5.1 区间覆盖率PICP与名义置信水平
PICP衡量预测区间覆盖实际值的比例,公式是:
PICP = (1/N)·Σ I(L_i ≤ y_i ≤ U_i)
N为测试样本数,I是指示函数,当真实值落在区间内就计1。目标是让PICP接近名义置信水平,比如设定0.8,那么PICP应该在80%左右。稍微高于名义水平可以接受,明显低于则说明区间偏窄、风险偏大。
PICP有个陷阱:如果整体覆盖率达标,但漏掉的点全部集中在爬坡阶段,那说明预测区间对极端过程的覆盖不足。在评估时把测试集按照爬坡强度分桶,各项分析分段覆盖率更有意义。我自己的经验是,模型在强爬坡段的PICP可能比平稳段低10个百分点以上,这是常见的薄弱区。
5.2 区间宽度PINAW与区间锐度
区间窄才有实用价值,否则全场0到100MW的区间覆盖率必然是100%,但毫无信息量。PINAW的计算公式是:
PINAW = (1/(N·R))·Σ (U_i - L_i)
其中R是功率的满发范围(归一化后就是1)。PINAW越小,说明区间越紧凑。
PICP和PINAW是一对矛盾指标:把区间整体向外扩,覆盖率一定上来,但宽度也会涨。单看任何一个都是片面的。调度更关心的是在满足置信水平约束下的最窄区间,本质是一个带约束优化目标。
5.3 综合指标CWC与分位数损失
CWC(Coverage Width Criterion)把覆盖率和宽度统一成一个标量:
CWC = PINAW + (λ/η)·exp(-η·(PICP - μ)),当PICP小于μ时加上惩罚项;当PICP≥μ时只保留PINAW。μ通常取名义置信水平,λ和η是惩罚系数。
这个公式的逻辑是:覆盖率达标时只比宽度,不达标时施加强指数惩罚。所以我最终排序模型,都是按CWC排,而不是只看PICP或者PINAW。在CWC框架下,一个PICP为0.82、PINAW为10%的模型通常优于PICP为0.95但PINAW为22%的模型,因为后者虽然安全但完全不可用。
另外分位数损失本身也是重要的对比维度。分别在测试集上计算三个分位数的平均pinball loss,可以直观看出模型在哪个分位段损失偏大。经验规律是,LR模型在下界分位数上损失往往偏大,因为尾部下往往有突变低于预期的情况。
6. 实验对比结果与模型特性分析
6.1 总体指标对比
全部模型在相同的测试集上的结果汇总如下:
| 模型 | PICP/% | PINAW/% | CWC | 参数量/K | 单次推理时间/ms |
|---|---|---|---|---|---|
| QRLSTM | 86.1 | 12.4 | 12.4 | 58 | 3.2 |
| QRGRU | 85.4 | 12.6 | 12.6 | 44 | 2.8 |
| QRBiGRU | 88.3 | 11.8 | 11.8 | 88 | 4.5 |
| QRBiTCN | 87.6 | 11.5 | 11.5 | 102 | 3.9 |
| QRCNNLSTM | 89.0 | 10.9 | 10.9 | 96 | 5.1 |
| QRCNNBiGRU | 89.7 | 10.5 | 10.5 | 104 | 4.9 |
| QRTCN | 86.3 | 11.9 | 11.9 | 77 | 3.5 |
| QRCNNBiGRUAttention | 91.2 | 9.8 | 9.8 | 112 | 5.6 |
从这张表能稳当读出几个结论:
第一,双向结构在PICP上显著优于单向,BiGRU比GRU提升了接近3个百分点。这说明风电功率序列中未来信息对区间估计有不可忽视的作用,即使只做单步预测,双向信息也能帮助模型更好地定位当前时刻的条件分位数。
第二,CNN前置处理能同时改善PICP和PINAW。CNN-BiGRU相比BiGRU,PICP提升了1.4个百分点,PINAW下降了1.3个百分点,两个指标同时改善是比较少见的,说明去噪和特征提取的作用真实存在。
第三,注意力机制是收益最大的一项。CNN-BiGRUAttention比CNN-BiGRU,PICP提升了1.5个百分点,PINAW下降了0.7个百分点。在爬坡时段观察区间曲线,注意力模型给出的区间能提前1到2个时间点收窄和扩张,这种自适应的区间动态变化是静态模型做不到的。
6.2 分时段误差分析
把测试集按照功率变化率分成三档:平稳段(变化率小于5%额定功率/15分钟)、爬坡段(变化率5%到15%)、强爬坡段(大于15%),分别计算PICP:
| 模型 | 平稳段PICP/% | 爬坡段PICP/% | 强爬坡段PICP/% |
|---|---|---|---|
| QRGRU | 87.1 | 82.5 | 73.2 |
| QRBiGRU | 89.8 | 84.1 | 76.8 |
| QRCNNBiGRU | 91.3 | 86.4 | 81.5 |
| QRCNNBiGRUAttention | 92.4 | 90.6 | 86.2 |
注意力模型在强爬坡段的PICP比QRGRU高了13个百分点,这是全组数据里差异最大的指标。
强爬坡是区间预测真正的试金石。在爬坡起点附近,功率分布往往呈双峰形态:一部分情景是继续爬升,一部分情景是爬坡中止,常规循环网络只能在这两种模式间折中,输出的区间往往偏向中间,导致两端都不能覆盖。注意力机制通过加权历史相似爬坡样本,可以在某种程度上模拟这种多模式的混合分布,所以强爬坡段的优势如此明显。
6.3 不同模型之间的定性差异
QRTCN和QRBiTCN在测试集整体表现不如CNN-BiGRU,但有个有趣的特点:TCN系列的PICP在平稳段与CNN-BiGRU几乎持平,但在强爬坡段低于CNN-BiGRU大概4个百分点。原因在于TCN的感受野虽然大,但卷积核的权重在训练中倾向于学一个“平均模式”的响应,对极端爬坡事件的触发不够灵敏。
LSTM和GRU的对比,我这次跑下来LSTM的指标略好但差距不大。GRU参数量少,训练速度快,在数据量受限或者需要频繁重训的场景下更实用。LSTM的优势可能在更长的序列上才会放大,如果我当时把窗口改成48或72个时间点,两者差距应该会更加明显。
7. 常见问题与排查技巧实录
7.1 分位数输出交叉问题
分位数回归有一个天然缺陷:网络输出的三个分位点不保证单调递增。理论上Q_0.1应该永远小于Q_0.9,但如果不加约束,训练时完全可能出现某一时刻预测的10%分位点高于90%分位点,这在物理上毫无意义,在调度场景里更是直接不可用。
我实际遇到过一次这种情况,而且不是偶发,而是训练早期频繁出现。解决思路有三层:
最简单的是在输出层之后做一个排序操作,强制q1 ≤ q2 ≤ q3,再用排序后的值计算损失。这个做法在训练和推理时都会用,牺牲一点梯度传递的完整性,但能保证输出物理可用。
中间方案是给损失函数加单调性罚项,当分位数逆序时加入惩罚,让网络自己学到单调性。比强行排序温和,训练更平滑,但需要调惩罚系数。
稳妥方案是直接采用三个独立网络分别训练三个分位数,完全不共享特征提取层。这样做单调性是自然成立的,因为每个网络独立优化,只要各自的数据分布一致、优化过程正常,分位数之间的交叉概率极低。缺点就是训练和推理成本翻了三倍。我最后用的是排序方案加轻微罚项,实践效果很好。
7.2 区间过宽的诊断与调优思路
如果模型的PICP远超名义置信水平,比如设了0.8但PICP高达0.97,那不是“好”而是“废”。区间太宽,调度没有参考价值,本质是模型对条件分位数的估计过度保守。
调优方向有几个排查点:
第一个点是数据噪声。训练集中如果有大量限电段没有清洗干净,模型会在这些异常点上被迫加宽区间来覆盖,诊断办法是把限电段剔除前后的PINAW做对比,如果差很多就说明清洗没做够。
第二个点是模型容量过大。模型参数量远大于数据信息量时,会把训练集中无关的随机扰动也学进去,在分位数回归里体现为对尾部过度悲观,区间异常增宽。降低隐藏单元数或加大dropout通常有效。
第三个点是分位数目标本身。如果序列特性较强,0.1和0.9两个极端分位点的样本信息有限,模型很难在它们之间做出区分度,表现为中位数区间宽度正常,但两端分位数膨胀。这种情况下可以适当提高极端分位数的损失权重,或者将极端分位数从0.1/0.9改成0.2/0.8。
7.3 训练不稳定的处理
BiTCN在训练初期损失波动比较大,一度怀疑是数据问题,排查后发现是TCN的梯度在深层空洞卷积里出现了指数级放大。空洞率增大时,有效感受野内的样本数也在变多,梯度幅度随之增加。解决办法就是加了梯度裁剪,把全局梯度范数裁剪到1.0,之后训练就稳定了。
另一种不稳定表现在训练中期loss出现台阶式跳变,通常是学习率太高导致分位数输出头来回震荡。这种情况把optimizer换成AdamW,并加上cosine退火,基本能解决。
7.4 模型选择之外两点心得
最后分享两个我在实操中比较受益的细节。
第一个是标准化分位数评估,关注预测区间的可靠性图。把预测的置信水平从10%一直变到90%,分别统计实际覆盖率,画成曲线。理想情况下这条曲线应该贴近y=x对角线。如果曲线偏移严重,比如实际覆盖率始终低于名义值,说明模型的分位数估计整体偏窄,有系统性偏差。这个图和PICP、PINAW结合起来,能更全面诊断模型质量。
第二个是推理时用中位数分位数输出做点预测,替代传统的单值回归。我实际对比过同一个模型的中位数输出和单独训练的点预测模型,中位数的MAE竟然略好一点,因为多分位数联合训练有正则化效应。而且这样等于一个模型同时完成点预测和区间预测,部署成本直接减半。
整个实验跑下来,我的体会是,QRCNNBiGRUAttention在当前这个数据规模下确实是综合最优解,但每个结构增量在风功率场景下的贡献并不均衡,注意力的增益最大、双向次之、CNN基底再次之。如果你只想要一个快速可用的方案,直接上QR-BiGRU就足够,如果是要冲刺更好的区间指标,再加上卷积和注意力也不迟。这套消融链条本身的价值,可能比选出一个最优模型更有参考意义。