资讯动态

新能源出力场景生成与削减:时序相关性建模与工程实践

发布时间:2026/10/15 6:50:46 来源:尧图企业网站定制
做新能源出力场景的人都知道一句话场景好不好不只看分布像不像还要看曲线“像不像真实发生的事”。我之前在处理某个光伏基地的出力场景生成任务时第一版直接用蒙特卡洛对每个时段的分布独立抽样生成了1000条日曲线。分布检验全过——每个时刻的均值、方差、分位数都对得上历史。可把任意一条曲线画出来立刻露馅上午十点还是满发十一点突然掉到10%下午两点又拉回满发。相邻时段之间完全没有“记忆”而这种锯齿在真实光伏出力里几乎不会出现。这就是典型的“抛弃了时序相关性”的蒙特卡洛场景生成。这篇内容就围绕“考虑时序相关性MC的场景生成与削减”这个主题展开讲讲为什么时序相关性这么重要、怎么把相关性“装进”MC抽样以及生成几千条场景之后如何用削减算法收缩成十几条有代表性的场景供随机规划、生产模拟、容量评估使用。整理的都是我在实际项目中反复验证过的做法适合做电力系统不确定性分析、新能源功率建模、随机规划基础场景库构建的同行参考。1. 时序相关性为什么是场景生成里最容易被忽略的坑1.1 独立抽样满足的是“分布”不是“过程”蒙特卡洛最直觉的用法是把一天24个时段当成24个独立的随机变量对每个时段单独拟合一个边缘分布然后独立抽一条随机数再逐时段映射回功率。问题是这种做法的潜台词是“t时刻取什么值与t-1时刻毫无关系”这在很多场景中都不成立。真实的风电出力是一条连续受惯性约束的物理过程光伏出力受云层和地表辐照度的转移规律影响相邻时段的功率变化率天然受限。从数据上讲我统计过某光伏基地历史日曲线的相邻时段Pearson相关系数白天时段普遍在0.75到0.9之间而独立抽样生成的场景集同样指标只有0.2左右。分布形态完全一致自相关结构却被抹平了。这种“分布正确、过程失真”的问题恰恰是独立MC抽样最容易踩的坑。1.2 过程失真之后下游优化模型会被“骗”场景最终是要喂给下游随机规划的最常见的是机组组合、储能调度、容量配置。这些模型都包含爬坡约束或者电量平衡约束因为物理上火电、储能、可调负荷的爬坡都不是无限的。如果场景里的时序关系被破坏模型会看到一个“一会满发一会骤降”的世界于是为应对高频大幅波动去预留更多向上/向下备用或者反过来低估了连续几个时段低出力带来的电量缺口风险。我做过一个小实验同一组历史数据生成两个场景集一个独立抽样一个考虑时序相关性分别代入一个模拟风电的随机调度模型。结果独立抽样那组多了约一倍的备用需求。原因是锯齿曲线把相邻时段的变化率拉大模型的爬坡约束被极大地激活。可以这么理解场景集是模型认知世界的“训练样本”样本过程不对模型学出来的策略自然不对。1.3 什么时候可以不用管时序相关性这不是所有场景生成都需要考虑时序。如果你的目标只是评估每个时段的边际分布比如做概率潮流时想得到节点电压的概率分布各时段独立抽样就够了。但只要你关心跨时段行为比如储能充放电策略、备用容量、连续阴天/无风段的最大缺额时序相关性就必须进入建模视野。有没有一个“量化判断标准”可以算一下相邻时段互信息的占比或者直接画滞后1阶自相关函数的衰减曲线对比独立抽样下自相关衰减速度差异一目了然。以光伏为例如果滞后1阶自相关系数低于0.4对调度类应用的失真就比较明显了如果把目标改成“连续两小时低出力频次”独立抽样和带相关性抽样可以差出一个量级这种差距不是靠增加抽样次数能补回来的。2. 给MC抽样加上“时间记忆”三种可落地的相关结构建模方案2.1 路线A马尔可夫链转移矩阵最早想到的是马尔可夫链。把每个时段出力离散成若干个状态比如把额定功率按0~0.1、0.1~0.3、0.3~0.6、0.6~1.0分成4个档再用历史数据统计相邻时段的状态转移概率矩阵。生成场景时从初始状态分布出发按转移矩阵逐时段抽样整条路径。这个方案的优点是直白代码量很小而且天然保留了一阶时序相关性。缺点是状态划分边界敏感状态数太少会丢失出力精度状态数太多转移矩阵又变得稀疏。在光伏场景里云层遮挡带来的多状态转移有时远超一阶马尔可夫链容易把“中间阴天、后面转晴”的长期依赖模拟成随机游走。2.2 路线BARIMA模型加残差重抽样第二种路线是直接对历史序列拟合ARIMA模型核心思路是把时间序列分解成确定性的自回归结构加白噪声残差。具体做法对每一日的历史出力曲线做季节差分或去趋势处理估计AR(p)项的系数然后从历史残差中重抽样再通过模型递推合成新的完整序列。这条路线的好处是保留了线性自相关结构而且残差重抽样比纯正态假设灵活。问题在于ARIMA对非线性相关、异方差特征适配一般。光伏出力的方差在正午大、早晚小如果不对方差做额外建模容易在峰谷时段生成不合理的波动。如果手里是风电数据、时序线性特征比较强ARIMA可以作为一个快速基线。2.3 路线Ct-copula加多元Student-t抽样我最推荐我最终保留在项目里的方案是t-copula。它的核心思想是“边缘分布与相关结构解耦”先不管曲线整体形状只用概率积分变换把每个时段的历史功率转换到[0,1]均匀空间再用均匀分位数去估计时段间的相关结构抽样时先生成带相关结构的多元随机数再逆变换回功率空间。这样做的好处非常明显边缘分布可以任意复杂哪怕逐时段用非参数分布拟合而相关性由一张相关系数矩阵单独表达两者互不污染。下面这段是我在项目里的核心抽样代码刻意注释得很详细import numpy as np from scipy.stats import t as student_t # X_hist: 历史日曲线矩阵, shape(n_days, T)T为日内时段数 T 24 # 1) 对每个时段t用历史数据拟合边缘分布F_t核密度或参数分布均可 # 2) 概率积分变换把每列的功率值转为[0,1]均匀分位数 U np.zeros_like(X_hist) for t in range(T): U[:, t] fitted_cdf_list[t](X_hist[:, t]) # 3) 估计相关结构把均匀分位数映射到t分布空间 nu 5 Y student_t.ppf(U, dfnu) # 每列是t_nu分布的分位数 Sigma np.corrcoef(Y, rowvarFalse) # 时段间的相关矩阵 # 4) 生成MC场景先抽独立t分布随机数再用Cholesky分解叠加相关结构 n_scen 1000 Z student_t.rvs(dfnu, size(n_scen, T)) L np.linalg.cholesky(Sigma) S Z L.T # 行向量带上相关矩阵 U_scen student_t.cdf(S, dfnu) # 回到均匀空间 X_scen np.empty_like(U_scen) for t in range(T): X_scen[:, t] fitted_ppf_list[t](U_scen[:, t]) # 逆变换回功率几个设定说一下自由度nu取5而不是更大的数是为了保留“尾部相关性”让连续极端天气有合理出现概率。nu太大会退化成正态copula。相关矩阵用的是Spearman秩相关还是Pearson相关对于光伏功率这类强非高斯变量我建议用秩相关对均匀分位数算Pearson相关等价于Spearman秩相关避免被极端值带偏。三条路线的取舍我也整理成了表格方案实现成本时序相关性保留非线性/异方差适配适用场景马尔可夫链低一阶一般快速原型ARIMA残差重抽样中线性多阶弱长期序列建模t-copula多元t抽样中高秩相关全时段强工程主力方案2.4 还有一个“笨办法”时序块抽样如果历史数据量非常充足还可以直接做块抽样从历史日曲线里随机抽一段连续长度为L的子块拼接成新曲线。因为子块来自真实数据它的非线性相关、异方差、尖峰特性全都被原样保留。缺点是需要数据覆盖足够多的天气类型否则容易反复抽到同几条模板曲线多样性不够。在我这个项目里历史有近3年日曲线我会把块抽样生成的场景作为t-copula方案的“对照组”两者分位数带和极值覆盖基本一致时就认为场景库是可靠的。3. 场景削减把千条曲线收缩到十几条本质是加权取舍3.1 为什么非削减不可MC场景生成很容易一把生成几千条曲线这本身不是问题问题是下游优化。以两阶段随机机组组合为例每多一个场景不代表仅仅多一个决策分支而是整个目标函数里多一组带权重的约束和变量。一千个场景可以直接让一个原本几分钟能解完的混合整数规划在数小时内都无法收敛。所以工程上几乎必然要做一个场景削减步骤用少量典型曲线带权重地逼近原始场景集合。削减的目标不是“挑长得好看的曲线”而是最小化削减后的概率分布与原始分布之间的某种距离。工程里最常用的是Kantorovich概率距离它本质上是带权重的Wasserstein距离在多维欧氏空间中的近似。简单理解在原始场景集里找到一些“代表点”把周边场景的概率归并给代表点让整体概率分布尽量不塌缩。3.2 快速前向选择算法从零开始挑典型场景我项目里最常用的是快速前向选择。它从空集开始第一个场景选“离所有场景加权距离之和最小”的那个即最居中的曲线随后每一步迭代从剩余场景中选一个“使得整体概率距离下降幅度最大”的场景加入集合。等价地说每次挑一个能把最没有代表的区域重新覆盖住的场景。下面是核心骨架代码为了可读性我没做任何复杂度优化思路很清楚import numpy as np from scipy.spatial.distance import cdist def forward_selection(scenarios, probs, n_select): n scenarios.shape[0] D cdist(scenarios, scenarios, metriceuclidean) selected [] remain set(range(n)) # 选第一个加权距离和最小的那个 total_dist np.sum(probs[:, None] * D, axis0) first int(np.argmin(total_dist)) selected.append(first) remain.remove(first) for _ in range(n_select - 1): best_gain -1.0 best_cand None for cand in remain: # 计算每个未选场景在加入cand后距离已选集合的“下降增益” gain 0.0 for i in remain: if i cand: continue d_before min(D[i, k] for k in selected) d_after min(D[i, k] for k in selected [cand]) gain probs[i] * (d_before - d_after) if gain best_gain: best_gain gain best_cand cand selected.append(best_cand) remain.remove(best_cand) # 归并权重把每个未选场景的概率加到离它最近的已选场景上 weights np.zeros(n) for i in range(n): if i in selected: weights[i] probs[i] else: nbr min(selected, keylambda k: D[i, k]) weights[nbr] probs[i] return selected, weights注意遍历里有一个for i in remain嵌套n1000时大约是百万量级的min操作计算机能跑但偏慢实际工程我会用numpy矩阵化重写上面版本是为了讲清楚过程。3.3 同步回代削减从满集出发反向删场景与快速前向相对的是同步回代即从完整的场景集出发每一轮找出“删除后导致概率距离增加最小”的场景把它删掉同时把它被归并的概率加到离它最近的剩余场景上。前向选择的优点是最终场景之间相距较远“居中代表”明显回代削减的优点是计算过程中一直保留原始场景的全局分布信息。我个人的偏好是如果目标场景数量与原始数量相差一个数量级以上比如1000削到10前向选择往往表现更稳如果只是从100削到50这种“轻削减”同步回代会保留更多细节。两个方法的时间复杂度都比较高但都有成熟的高效实现动态规划版的快速前向在实际工程里很常用。方法思路适用削减比例优点缺点快速前向选择从空集挑代表大比例10~20倍以上代表性强初始迭代慢同步回代削减从满集删除冗余小比例2~5倍保留全局分布细节大比例时计算量大3.4 削减到多少个场景合适找概率距离曲线的“拐点”削减数量不是一个拍脑袋参数。我会固定原始MC场景集然后依次削减到5、10、20、50、100个分别计算削减后的场景集与原始场景集之间的概率距离。画出来的曲线通常在10到30之间出现明显拐点30个场景以后继续增加场景数量概率距离下降已经微乎其微。我的经验是对于日内24时段的风光功率场景500到1000条原始场景削到10到30条概率距离可以控制在15%以内如果削到5条概率距离会跳到30%以上这时候除非你对计算速度极度敏感否则不建议。提示概率距离曲线不是单调下降的因为每个场景被选中后还会带走周边概率个别迭代步可能出现距离短暂回升。要判断拐点看整体趋势而不是单点波动。4. 削减效果验证不能只盯一张图要看下游闭环4.1 三个局部指标概率距离、统计矩、自相关结构削得好不好我习惯从三个层面看。第一是概率距离本身这已经由削减算法优化过了但要看绝对值有没有失控。第二是逐时段统计矩把原始MC场景集和削减场景集分别算均值、标准差、P10和P90分位数画在同一张图上。如果削减后的分位数带宽明显变窄说明场景多样性被砍掉了。第三是时间结构很多人在这个环节失守——削减后虽然每个时刻分布都对但场景数量太少时段间的自相关结构会被拉平这是削减方法用欧氏距离作为相似度度量时很常见的副作用。我在项目里的实际对照数据大致如下只列几个代表指标指标原始MC场景1000条削减场景15条平均时段均值误差基准0.8%以内P90分位数偏移基准4.2%相邻时段平均自相关0.820.71极端低出力场景覆盖100%93%自相关从0.82降到0.71绝对值看起来还行但如果你拿着这15条场景去做储能调度低谷段的连续时长会被低估。所以我在削减后还会做一次“自相关校验”如果退化严重就改用带一阶差分距离加权的相似度矩阵或者直接额外保几条“过程响应”的极端场景。4.2 最关键的一步把场景喂进下游模型做闭环测试所有分布指标都是间接证据真正要看的是场景削减前后的策略质量差异。我在模拟项目中做过一次完整闭环先把场景集A1000条代入随机机组组合模型求出的最优期望成本作为“全场景基准”再把削减后的15条场景代入同一个模型比较期望成本和第一阶段的决策变量差异。结果是期望成本偏差在1.5%左右第一阶段机组启停方案的重合度在90%以上。作为对照如果从原始场景里“随手挑15条”而不是用削减算法期望成本偏差会跳到8%到10%启停方案也频频变化。这组实验强烈说明削减算法不是可有可无的锦上添花而是保证随机规划结果稳定的必要步骤。我还会做一个更苛刻的鲁棒性测试用削减场景训练出来的调度方案拿到另外独立生成的1000条“未见场景”上回测看是否频繁出现切负荷或弃风。在我的项目里约束违反率控制在3%以下我才敢把场景库交给下游。4.3 可视化的呈现方式分享一个比较实用的展示方法削减后的15条场景不要全画实线按概率权重给透明度画成“瀑布图”一眼能看出哪些是主线、哪些是小概率的尾部场景。再叠加上原始MC场景的P10-P90阴影带能直观看到削减场景是不是恰好把分位数带的界覆盖住了。这种方法在写报告、给非算法背景的同事评审时特别管用比贴一堆数值表有效得多。尤其是场景库要移交到别的团队使用时一张“权重透明度图加分位数带图”就能把代表性讲清楚。5. 踩坑记录与参数建议5.1 坑一削减算法输出的权重被下游丢掉这是我最常见到的低级错误严格说不是算法的坑而是接口的坑。很多开源工具削减完只导出“场景曲线列表”权重单独存一个数组下游优化程序如果只读曲线没读权重就等于默认15条场景等概率。这会彻底毁掉削减的意义——为极小概率的尾部场景分配了过高权重导致结果整体偏移。建议在交付场景库时把场景和权重打包成结构化文件并在接口测试里专门做一个“权重和为1”的断言。如果用的还是老式CSV交接建议加一列权重并在文档里用小例子说明削减前100条场景里只有2条极端大风场景权重加起来不超过0.05如果不读权重这两条极端场景就占了两份的“话语权”结果会明显失真。5.2 坑二t-copula的自由度选太大自由度nu是t-copula的敏感旋钮。nu趋近于无穷时t分布退化为正态分布尾部相关性完全丢失。对风光这种经常出现连续极端天气的过程低估尾部相关性会让场景库漏掉最危险的组合。我测试过nu50和nu5两组场景后者的P1分位数的极值深度明显更深。建议从nu3到10之间遍历测试用历史极端事件的发生频率来反推哪个值能让场景库的极值频率对得上就用哪个。不要因为“t分布在线性相关结构上没有解析解”这类理由回避它工程里更关心的是极值能不能被覆盖而不是解析优雅。5.3 坑三每时段单独拟合分布时过拟合逐时段拟合边缘分布听起来很合理实际上很容易被小样本坑到。一年365天、一天24点白天可用时段可能只有几千个样本用核密度估计去拟合会出现明显的“尖峰毛刺”体现在场景里就是某些时段的极值被反复抽中。我在项目里的处理是先把历史时段做聚类比如把日升、日落、平谷段分成3到4类在同一类时段内共享分布形状再乘一个逐时段的尺度和偏移量。这样既保留逐时段差异又避免分布形状被噪声支配。样本量少于1000天时这种聚类共享分布的做法几乎是必须的。5.4 坑四相似度度量只用欧氏距离经典削减算法几乎都默认欧氏距离但它对“时间轴上的小错位”不敏感。两条光伏曲线一条在12:00到达峰值、一条在12:15到达峰值本质上很接近但欧氏距离会判成完全不同。遇到这种情况可以用动态时间规整DTW距离替代欧氏距离或者对一阶差分后的序列做削减。后者有一个额外好处直接维护相邻时段变化率的分布能有效缓解削减后自相关结构退化。我自己常做的一个变通是在欧氏距离基础上加10%到20%的一阶差分距离权重既能保持大部分熟悉的行为又能起到“过程相似性”的引导作用。5.5 一套我实测靠谱的参数基线整理一套可以直接当启动配置的参数方便快速复现参数建议值备注MC场景数500~2000视计算资源越多越稳t-copula自由度nu3~8用极值频率反推边缘分布拟合非参数核密度数据量不足时用时序聚类共享削减方法快速前向选择大比例削减优选相似度度量欧氏距离自相关退化时改用差分距离削减目标数量10~30看概率距离拐点权重验证权重和1接口集成时强制校验最后分享两个落地经验。第一我在实际工程版本里不会“先削减、后使用”就完事而是先生成4000条MC场景削减出20条典型场景形成基础场景库再根据项目关注的尾部风险手工追加5到8条“极端场景”并调整权重。比如连续48小时低出力、正午前后剧烈先降后升、设备降额导致的出力折减。这样既保住了随机规划的计算速度又不会丢掉长尾风险比单纯加大场景数量划算得多。第二场景库交付后一定要留“版本号”——分布参数、相关性矩阵、削减随机种子都记录下来否则下游模型每一次跑出不同结果时你很难判断是场景变了还是调度模型本身的问题。这套方法论在我参与的模拟光伏与储能容量配置项目里实测下来很稳也算是我做场景生成与削减这几年最值钱的一套经验。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑