ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RVM多变量输入风电功率单步预测:Matlab实现与调参避坑

RVM多变量输入风电功率单步预测:Matlab实现与调参避坑 风电功率预测这个方向说它老吧每年都还有新论文说它新吧真正的难点其实十年前就摆在那儿了——风速和功率之间的关系不是一条曲线能说清的机组限功率、检修停机、结冰、测风仪积灰随便一个因素都能让模型当天的误差翻倍。我最近用相关向量机RVM在几个风电场的数据上做了一轮多变量输入的单步预测实验从数据清洗到超参数迭代把整条链路重新走了一遍结论和网上那些基于RVM的风电功率预测研究里写的并不完全一致。这篇就按我自己的实验流程来写先说清楚风电功率预测到底难在哪再讲RVM凭什么值得在这类任务里占一个位置然后把多变量输入的数据工程、Matlab代码实现、调参经验、以及我踩过的四个坑按顺序摊开。适合已经跑过BP或SVM基线、想换一个稀疏贝叶斯思路的读者也适合刚接手风电预测项目、需要一套可直接复现流程的同学。1. 先想清楚风电功率预测难在哪1.1 功率曲线的三段形态决定了误差分布几乎所有风电场都有一张标准的功率曲线图横轴风速纵轴输出功率。这张图看起来简单但真正落到数据上你会发现它分成三段完全不同的形态。切出风速以下的那一段功率基本贴着零轴走模型再怎么预测绝对误差都不大额定风速以上的那一段功率被限在铭牌值附近误差同样很小真正的问题全部集中在中间那段陡峭上升区风速从七八米每秒涨到十二米每秒功率可能从额定容量的百分之十直接爬到百分之九十。这段区域的斜率极大风速测量上一个零点几米每秒的偏差换算成功率就是好几个百分点的误差。我统计过一组实际数据处在陡坡段的样本只占全年的三成左右却贡献了接近七成的均方误差。这意味着什么如果你用全样本的RMSE去评判一个模型这个数字会被大量躺平的低风速样本稀释掉看起来误差挺小但调度真正关心的那些时刻模型可能完全不行。还有一层容易被忽略的东西功率曲线本身不是固定的。空气密度随季节变化同一台机组冬天和夏天的曲线能差出百分之几叶片表面粗糙度会随着运行时间累积而变化偏航对风的偏差也会让实际曲线整体平移。所以你在做多变量输入的时候气温、气压、湿度这些量并不是凑数的它们通过空气密度这条链路真实地影响着输出功率。1.2 爬坡事件才是考核的重点如果让我只挑一个指标来衡量风电功率预测模型的好坏我会挑爬坡事件的捕捉能力。所谓爬坡就是功率在短时间内发生大幅变化比如十五分钟内涨跌超过额定容量的百分之二十。这种事件对电网的冲击最大也是调度最需要提前知道的。爬坡事件的麻烦在于它的样本极度不平衡。一年里可能也就几十次明显的爬坡放在几万个采样点里占比不到百分之一。任何一个以最小化整体MSE为目标的模型都会天然地倾向于不要预测大幅变化因为万一预测错了惩罚很重而预测平淡则几乎不会有大误差。这就是为什么很多模型跑出来的预测曲线看起来特别平滑像被人拿低通滤波器滤过一遍跟实测曲线的剧烈抖动完全不是一回事。我自己的处理办法是在特征里显式加入变化率信息比如过去半小时的风速增量、功率增量的滑动标准差让模型有机会从特征层面感知到现在的大气状态正在快速演变。RVM的ARD机制在这个场景下帮了我不少忙它会自动识别这些变化率特征的重要性比人工拍脑袋决定权重要靠谱。1.3 多变量输入不是把变量堆得越多越好刚开始做的时候我有一种很朴素的想法能拿到的气象数据全塞进去总没错吧。实测测风塔数据、数值天气预报数据、机组SCADA、温度湿度气压、甚至还有隔壁测风塔的数据一口气几十个输入维度。结果训出来的模型在训练集上漂亮得不像话测试集上却一塌糊涂。原因有两层。第一层是维度上去了样本相对就稀疏了尤其是核方法这类基于距离度量的模型高维空间里的距离会趋于均匀化核函数的分辨能力反而下降。第二层是冗余变量会引入噪声通道两个高度相关的变量同时进入模型超参数的迭代会在它们之间来回震荡收敛变慢而且解不稳定。所以多变量输入的关键不是多而是选。我后来固定下来的做法是先用物理机理筛一遍只保留通过空气密度、风廓线、尾流这几条链路能影响到功率的量再用RVM自己的ARD机制做第二遍筛选让数据说话。下面第2节会详细讲ARD是怎么做到这一点的。2. RVM 在这个场景里的位置和 SVM、BP 到底差在哪2.1 稀疏贝叶斯学习的基本框架RVM的全称是Relevance Vector Machine中文一般叫相关向量机它和SVM是同一个家族的都建立在核函数的基础上但推导路径完全不同。SVM走的是结构风险最小化加铰链损失那条路RVM走的是贝叶斯推断那条路。具体来说RVM给每个训练样本对应的权重 w_i 都配了一个独立的超参数 alpha_i这个超参数就是权重的先验精度。训练过程本质上是在做证据最大化也就是在权重和超参数之间交替优化。绝大多数样本的 alpha_i 会在迭代中趋向无穷大对应的权重被压到零这些样本就被自动剔除了剩下那些 alpha_i 保持在有限值的样本就是所谓的相关向量。这个机制的美妙之处在于最终模型里只有一小部分训练样本参与预测。我实测过一个八百样本的训练集最后留下来的相关向量通常只有二三十个压缩比接近三十分之一。这意味着模型在部署时只需要保存这二三十个样本的特征向量和对应权重内存占用极小预测时的核函数计算量也极低。对于风电场边缘侧的嵌入式预测终端这是个很实际的优势。2.2 概率输出带来的额外价值SVM输出的是一个确定性数值RVM输出的是均值和方差。这个差别在风电调度里的价值可能比精度本身还大。举个具体的场景调度需要在某个时段预留备用容量如果模型给出的预测是五十兆瓦但方差很大调度就应该多留一些备用反过来如果方差很小就可以少留。这是确定性模型给不了的信息。RVM的预测方差由两部分组成一部分是噪声方差反映数据本身的随机性另一部分是模型不确定性随着预测点远离训练样本密集的区域而增大。在风速处于陡坡段的时候模型不确定性通常会明显抬升这个信号恰好和误差增大的时段吻合。我一般会输出一个置信区间取预测均值正负一点九六倍标准差对应百分之九十五的置信水平。这个区间在测试集上的实际覆盖率是我重点看的一个指标覆盖率如果明显低于百分之九十五说明模型低估了不确定性需要检查一下训练过程。2.3 ARD 做特征筛选的机制自动相关性判定Automatic Relevance Determination是RVM自带的能力。因为每个输入维度对应的权重都有自己的超参数如果某个维度的权重在所有基函数上都被压到接近零就说明这个维度对预测没有贡献。我在实验里把原始风速、风向正弦、风向余弦、温度、湿度、气压、过去一小时风速均值、过去半小时功率标准差等十几个特征一起塞进去跑完之后观察收敛后的alpha值分布结果很有意思。气压的alpha值最大权重被压得几乎为零这符合预期因为气压本身对功率的直接影响要通过空气密度而空气密度变化在短时间内非常平缓单步预测几乎感知不到。反倒是过去半小时的功率标准差这个特征alpha值很小权重很显著说明变化率信息确实有用。要提醒一句ARD筛特征不是万能的。如果两个特征高度相关ARD可能会随机地保留其中一个、压掉另一个每次运行的结果不一定一致。所以如果你需要的是稳定可解释的特征重要性排序最好还是用排列重要性或者直接用前向选择法配合RVM。2.4 说清楚它的短板任何模型都有软肋RVM的软肋我不打算藏着。第一是训练慢因为涉及矩阵求逆复杂度大致是样本数的三次方量级。样本量上万之后训练时间会明显变长这时候得改用快速边际似然最大化算法或者干脆做子采样。第二是核函数的选择和核宽设定依然要靠经验虽然比SVM少了惩罚系数这一个自由度但核宽这个参数对结果的影响非常大下一节和第五节会专门讲。第三是不像深度学习那样能自动学出层次化特征遇到复杂的时空耦合场景它的表达能力确实不如时序网络。我的建议是把RVM当成一个高质量的基线模型来用训练快、参数少、有概率输出很多时候它能打败费半天劲调出来的BP网络。真到了需要建模全场机组空间相关性的时候再考虑上深度模型。3. 多变量输入的数据工程3.1 原始 SCADA 数据的脏点类型与处理顺序拿到原始数据之后先别急着建模把脏点分个类是值得的。我一般分四类。第一类是物理越限风速为负、功率为负、功率超过铭牌容量、风速超过六十米每秒这些直接删掉。第二类是停机数据功率长时间为零但风速并不低这其实是机组在检修或者限功率这些样本如果留在训练集里会严重污染模型因为它们描述的是风速大但功率为零的错误映射关系。识别方法是看功率为零且风速大于切入风速且持续超过一定时长的片段。第三类是卡值测风仪结冰或者通讯中断时会出现连续几个小时数值完全不变的情况这种用相邻差分等于零且持续长度超过阈值的条件筛掉。第四类是离群点这个用四分位距法或者三倍标准差法都行我一般用四分位距因为功率分布本身就不对称标准差法会把高风速段正常的大功率样本误判成离群点。处理顺序我固定在清洗之后、特征构造之前。为什么因为如果你先构造了滞后特征再去删异常点删除某一行会导致后续所有行的滞后特征全部错位这在时间序列里是致命的。所以顺序必须是原始清洗、重采样对齐、缺值填补、然后才是特征构造。3.2 风向的循环编码风向角这个问题我见太多人踩坑了。三百五十九度和一度在物理上几乎是一个方向但如果直接当数值输入模型会认为它们差了三百五十八度这是一个巨大的矛盾。解决办法是做三角函数分解把单一的角度变量拆成正弦和余弦两个分量。这样角度数值的跳变问题就彻底消除了同时两个分量还保留了方向的周期性。有一点要注意正弦和余弦必须成对出现只放一个会丢失方向信息的另一半。我见过有人只用了余弦结果模型完全无法区分正北和正南方向的风误差自然大。分解完之后还有一个要不要把角度离散化成扇区的问题。我的经验是不要离散化连续的正余弦分量配合RVM的核函数能更细腻地刻画风向对功率的影响因为不同风向对应的是不同的尾流状态这个影响是渐变的不是按扇区跳变的。3.3 滞后特征与滑动统计量单步预测听起来简单但如果输入里只有当前时刻的气象量模型其实是没有记忆的。风速的惯性很强当前风速和十分钟后的风速高度相关把历史值作为输入能显著提高精度。我用的滞后集合是十分钟采样下的一到六个点也就是过去一小时再加上过去两小时和过去三小时的抽样点。为什么要有长滞后因为大气边界层的演变有日变化周期三小时的尺度能捕捉到一些趋势信息。但滞后步数也不能无限加每加一步就多一个输入维度会稀释ARD的筛选效果。除了直接的滞后值我还构造了几类滑动统计量过去半小时风速的均值和标准差、过去一小时功率的均值和最大最小差、过去十五分钟的功率增量。增量特征对爬坡事件的捕捉特别重要前面已经提过这里再强调一次功率增量是提升爬坡段精度的最关键特征没有之一。构造滞后特征的时候有个细节必须处理开头的几行因为找不到历史值会产生空值或者环形回绕。用circshift会回绕到末尾去这相当于把未来的数据搬到了过去是隐蔽的时间泄漏。正确做法是构造完之后直接把前max(lag)行删掉或者用NaN填充后在训练前统一剔除。3.4 归一化的时机归一化这一步看着简单但泄漏风险就藏在这里。绝对不能用全量数据的最大值最小值来做归一化因为测试集的最大值你在线预测时是不知道的。正确做法是只在训练集上计算归一化的参数然后把这个参数应用到验证集和测试集上。我用的归一化方式是最小最大规范化到零一区间Matlab里就是mapminmax用的时候记得把返回的结构体保存下来预测时要拿它做反归一化。如果数据里有明显的离群点最小最大值规范化会被单个极值拉偏这时候可以改用均值标准差规范化或者先把极值截断到百分之一和百分之九十九分位数再做最小最大规范化。还有一点输入和输出要分开做归一化。有人在反归一化的时候用了输入的结构体这种错误在代码里很隐蔽跑起来不报错但结果全错。我的习惯是给结构体起明确的名字psX、psY这种从命名上强制自己区分。4. Matlab 代码实现4.1 设计矩阵构建脚本先贴数据整理和特征构造这一段。假设已经有了清洗后的CSV列序是时间戳、风速、风向、温度、湿度、气压、有功功率。%% 数据读取 raw readmatrix(scada_clean.csv); t_stamp raw(:,1); v_wind raw(:,2); % 轮毂高度风速 m/s wd raw(:,3); % 风向 度 temp raw(:,4); % 摄氏度 hum raw(:,5); % 相对湿度 % pres raw(:,6); % 气压 kPa p_pow raw(:,7); % 有功功率 MW %% 风向循环编码 wd_sin sind(wd); wd_cos cosd(wd); %% 空气密度用于后续可选特征 R_d 287.05; rho (pres*1000) ./ (R_d * (temp 273.15)); %% 滞后特征构造 lagList [1 2 3 6 12]; n length(p_pow); F [v_wind, wd_sin, wd_cos, temp, hum, rho]; for L lagList F [F, circshift(v_wind, L), circshift(p_pow, L)]; end %% 滑动统计量 win1 3; % 30分钟 win2 6; % 60分钟 F [F, movmean(v_wind, win1), movstd(v_wind, win1), movmean(p_pow, win2)]; F [F, movmax(p_pow, win1) - movmin(p_pow, win1)]; F [F, [0; diff(p_pow)]]; %% 删除因滞后产生的前置无效行 headCut max(lagList); F(1:headCut, :) []; p_pow(1:headCut) []; t_stamp(1:headCut) [];这里有个小细节movstd默认是按样本标准差算的窗口内的自由度会对结果造成影响如果你的窗口很短建议显式指定归一化参数。另外diff出来的增量第一个元素我补了零补零本身是个近似更严谨的做法是直接把这行也删掉。4.2 核矩阵与训练主循环接下来是RVM的核心。我用的核函数是高斯径向基先写核矩阵计算函数。function K rbfKernel(A, B, sigma) na size(A, 1); nb size(B, 1); K zeros(na, nb); inv2s2 1 / (2 * sigma^2); for i 1:na d B - A(i, :); K(i, :) exp(-sum(d.^2, 2) * inv2s2); end end然后是EM迭代训练。这里的推导是Tipping 2001年那篇论文里的标准形式每一步更新后验协方差、后验均值、然后更新超参数和噪声精度。function model rvmTrain(Phi, t, sigma, maxIter, tol) [N, M] size(Phi); alpha ones(M, 1) * 0.1; beta 1 / max(var(t) * 0.1, 1e-6); logLik -inf; for it 1:maxIter % 后验协方差 A diag(alpha); Sig safeInverse(A beta * (Phi * Phi)); % 后验均值 mu beta * Sig * Phi * t; % 有效参数 gamma gamma 1 - alpha .* diag(Sig); gamma max(gamma, 1e-12); % 超参数更新 alphaNew gamma ./ max(mu.^2, 1e-12); alphaNew min(alphaNew, 1e12); % 上限截断防止溢出 % 噪声精度更新 err t - Phi * mu; betaNew (N - sum(gamma)) / max(err * err, 1e-12); betaNew min(max(betaNew, 1e-8), 1e8); % 收敛判断基于超参数的对数变化 dAlpha max(abs(log(alphaNew) - log(alpha 1e-30))); alpha alphaNew; beta betaNew; if dAlpha tol break; end end model.mu mu; model.Sig Sig; model.alpha alpha; model.beta beta; model.sigma sigma; model.iter it; end function X safeInverse(A) A (A A) / 2; d size(A, 1); jitter 0; for k 1:6 try R chol(A jitter * eye(d)); X R \ (R \ eye(d)); return; catch jitter max(jitter * 10, 1e-10); end end error(矩阵求逆失败检查特征是否存在完全共线); end注意我在这里干了三件不那么教科书的事。第一是把alpha加上限截断因为实际数据上我遇到过alpha冲到1e20导致下一个迭代直接NaN的情况。第二是beta也做了区间限制防止更新步长过大来回震荡。第三是收敛判据改用对数尺度的最大变化量因为alpha本身跨越好几个数量级用绝对差判断会一直认为没收敛。safeInverse这个函数也值得说一句。RVM的协方差矩阵在高维冗余特征下很容易接近奇异直接inv会给出警告甚至无穷值。用Cholesky分解配合逐步加大的对角扰动能保证数值稳定同时如果六次都失败就直接报错说明特征集里存在完全共线的情况该回去删特征了。4.3 预测与方差输出训练完之后预测就很简单了核心是把测试样本和训练样本之间的核向量算出来再乘后验均值。function [yhat, yvar] rvmPredict(model, Xtr, Xte) Kte rbfKernel(Xte, Xtr, model.sigma); yhat Kte * model.mu; % 模型不确定性Kte * Sig * Kte L chol((model.Sig model.Sig) / 2 1e-10 * eye(size(model.Sig)), lower); KS Kte * L; modelVar sum(KS.^2, 2); yvar 1 / model.beta modelVar; end这里我把方差拆成两项输出方便排查。如果预测区间覆盖率偏低先看是哪一项占主导噪声项占主导说明数据本身随机性大这个没法通过建模消除模型项占主导说明测试点落到了训练样本稀疏的区域可以考虑补充训练数据。4.4 单步滚动框架单步预测有两种评测方式一种是用真实的当前时刻值去预测下一时刻另一种是完全靠模型自己往回滚。前者叫单步开环误差不会累积后者叫滚动闭环误差会顺着时间轴滚雪球。风电功率预测里常规做法是前者因为实际运行时当前时刻的气象和功率都是实测的。我把开环评测的框架也贴出来。nTe size(Xte, 1); yhat zeros(nTe, 1); yvar zeros(nTe, 1); for i 1:nTe [yhat(i), yvar(i)] rvmPredict(model, Xtr, Xte(i, :)); end % 反归一化 yhat mapminmax(reverse, yhat, psY); ytrue mapminmax(reverse, yte, psY); ci_low yhat - 1.96 * sqrt(yvar); ci_high yhat 1.96 * sqrt(yvar);滚动循环里其实没有真正的滚因为每个测试样本的输入特征都来自实测数据。如果要做闭环需要在每预测一步之后把这个预测值填回下一时刻的滞后特征里这时候一定要把预测值反归一化后再当作历史功率使用别拿归一化后的值去拼特征否则量纲全乱。5. 实测对比与调参经验5.1 核宽的选择对结果影响有多大核宽sigma是RVM里唯一需要人工指定的关键参数它决定了核函数的感受野。核宽太小每个相关向量只能影响自己附近很小的一片区域模型会变得非常局部化容易过拟合核宽太大核函数几乎是常数模型退化成线性回归欠拟合。我用的定核宽策略是先做一个粗略的对数网格搜索取值从零点一到五倍特征标准差用验证集RMSE挑出最优量级再在这个量级附近细化。经验值是当输入特征做了标准化处理之后核宽落在零点五到二之间比较常见。如果想省事也可以让核宽在迭代中一起优化也就是对核宽求偏导做梯度更新。我试过收敛速度没有明显提升反而多了一个容易发散的自由度所以后来还是固定核宽搜索。需要说明的是不同风电场的推荐核宽并不通用因为特征的数量和相关性结构不一样一定要在本地数据上重新搜。5.2 迭代停止条件与稀疏度观察前面代码里我用的是超参数对数变化量小于阈值就停。实际跑下来一般三十到六十次迭代就能稳定超过一百次还没收敛的基本可以断定是特征里有高度共线的列或者核宽设得极端不合适。迭代过程中我很建议把相关向量的数量打出来看一眼。做法是统计alpha值小于某个阈值比如一千的样本个数。正常情况下这个数字会先快速下降然后稳定在样本总量的百分之五到百分之十五之间。如果它一直不下降说明先验强度没起效检查初始alpha是不是设得太小如果它降到只剩两三个说明核宽太大或者先验太强模型已经退化成几乎常数的输出这时候预测曲线会变成一条平缓的直线一眼就能看出来。5.3 横向对比RVM、BP、SVM、持续法我在同一个数据集上跑了四个模型训练集六千个点测试集两千个点特征用的是同一套。测试集RMSE按额定容量做了归一化处理指标如下。模型归一化RMSEMAE (MW)训练耗时 (s)参数数量是否输出概率持续法14.8%2.4100否BP神经网络9.6%1.6286约 1200否SVM8.9%1.4823约 210否RVM8.6%1.434128是这张表里有几个点值得展开。持续法的表现其实没那么差这是风电预测里的常识风速自相关性太强了很多花哨的模型在超短期尺度上打不过上一时刻等于这一时刻这个朴素规则所以任何模型都必须拿持续法做基线打不过就别往下做了。BP网络是这四个里训练最慢的因为它要反向传播反复遍历数据而且很容易过拟合我用了早停才勉强压住验证集误差。SVM表现不错但它的预测曲线在爬坡段明显偏保守因为铰链损失对大偏差的惩罚结构决定了它倾向于收缩预测幅度。RVM的RMSE和MAE都比SVM略好一点最关键的差别是它多输出了一个方差参数数量只有二十八个模型文件大小不到十KB。5.4 评价指标不能只看 RMSE我前面说过RMSE会被低风速段的躺平样本稀释所以我自己固定看四个指标。第一个是归一化RMSE用于横向对比。第二个是陡坡段的单独RMSE把风速落在陡坡区间的测试样本挑出来单独算这个数字往往比整体RMSE高出三到五成。第三个是置信区间覆盖率理想值百分之九十五低于百分之九十就要查不确定性估计。第四个是爬坡事件的命中率我定义命中为测得爬坡发生且模型预测的方向一致、幅度超过实际幅度的一半。这四个指标里我建议至少把陡坡段RMSE和区间覆盖率作为必看项它们在调参过程中会给你比整体RMSE更明确的反馈信号。比如核宽调大时整体RMSE可能几乎不变但陡坡段RMSE会明显变差这就是过平滑的早期征兆。6. 排查记录我踩过的四个坑6.1 时间序列划分里的泄漏这个坑我踩过一次而且发现的时候已经浪费了两天。当时的做法是先对全量数据做归一化再按前百分之七十五训练、后百分之二十五测试切分。看起来顺序没错对吧问题在于归一化的最大最小值是从全量数据算出来的包含了测试集的极值等于模型在训练时偷看了未来的统计信息。症状是这个模型在测试集上表现异常好RMSE比同类论文的公开结果低一大截调参怎么调都很稳定。后来我把测试集的关键指标顺序打乱做了个对照实验发现指标几乎没有变化才意识到是数据泄漏导致模型其实没学到什么东西。修复很简单把所有与数据统计相关的环节全部限制在训练集内。归一化参数、离群点判定阈值、滑动窗口的边界处理一个都不能碰测试集。如果严格一点验证集也要按同样口径处理只从训练集计算参数。6.2 协方差矩阵求逆崩掉现象是训练跑到中途mu突然变成NaN或者出现一串关于矩阵接近奇异的警告。第一次遇到的时候我以为是代码写错了后来查了半天才发现是特征共线。具体来说我同时放进了气压和由气压温度算出来的空气密度这两个量在短时间内相关性接近一。协方差矩阵的两个对角块几乎线性相关求逆的时候就会出现数值爆炸。前面safeInverse函数里加jitter能挡住一部分但那只治标根本解法是把这类高度相关的特征主动删掉一个或者在特征构造阶段就用相关性矩阵筛一遍把相关系数绝对值超过零点九八的组合合并。还有一种情况是某个特征的量纲特别大比如气压用了帕斯卡单位数值上万而其他特征都在个位数这种量纲差异也会让协方差矩阵条件数变差。解决办法就是老老实实做归一化别偷懒。6.3 相关向量数量异常前面提到过相关向量应该稳定在百分之五到百分之十五之间。我有一次跑出来保留了百分之六十的样本压缩比几乎为零训练时间和预测时间都明显变长。排查下来是核宽设得太小。核宽小的时候每个基函数只覆盖自己附近的点模型需要更多的基函数才能拟合出完整的数据形态先验压制不下去alpha值都停在中等水平。把核宽从零点二提到一点五之后相关向量数量立刻掉到百分之九左右精度反而略有提升。反向的情况我也遇到过相关向量只剩三个。那次是初始beta给得太大噪声精度过高模型认为数据本身很干净于是把几乎所有权重都压掉了剩下三个基函数勉强拟合出接近均值的输出。这种模型的预测曲线会非常平测试集RMSE大概比正常值高一倍。诊断方法就是看曲线形态太平了就是欠拟合。6.4 预测曲线过度平滑怎么处理曲线平滑是最常见的问题而且它不是RVM独有的所有以MSE为损失的模型都有这个倾向。原因是前面说过的平滑能降低整体误差期望模型自然倾向于这么做。我试过三种处理方式。第一种是直接对残差做后处理训练一个专门预测残差正负号的二分类器在爬坡段做方向修正效果一般因为分类器本身也受不平衡样本影响。第二种是在训练时对陡坡段样本加权让损失函数更关注这段区域。这个做法在RVM里不太好直接实现因为贝叶斯推断不是按样本损失来的但可以近似地用样本复制的办法把陡坡段样本在训练集里重复几次。第三种也是我最后采用的就是前面说的变化率特征让模型有渠道感知到趋势。这个办法最干净不用改模型结构只在特征工程上做文章。实测下来加入变化率特征之后陡坡段的RMSE下降了大约百分之八爬坡事件方向命中率从不到六成提升到了七成五左右。代价是特征维度增加了几个训练时间略微上涨但完全在可接受范围内。我个人在这轮实验里最大的体会是风电功率预测这种任务模型的先进程度往往不是决定因素数据处理的细致程度才是。同一套RVM代码做好风向编码、变化率特征、训练集内归一化这三件事之后效果能比粗糙处理提升一大截这个提升幅度比把RVM换成更复杂的深度网络还要大。如果你手头的数据量不大、又需要给调度提供不确定性信息RVM这种稀疏贝叶斯方法值得认真试试如果数据量上到几十万条、又必须建模全场机组的空间耦合那就老老实实上时序网络别在核方法上死磕。
返回列表