做光伏功率预测这几年我最大的感受是单点预测做得再准到了电网调度和储能策略层面真正能拍板用的往往不是那条预测曲线本身而是它附带的不确定性信息。尤其超短期预测面对云团遮挡的剧烈波动你给调度一个中午11点出力50MW的点值远不如给一个11点出力大概率落在45到58MW之间的区间更让人踏实。这一行卷到后期拼的不是谁的RMSE又降了几个千分点而是谁能在概率意义上把光伏出力的时空关联讲清楚。这篇文章我想完整复盘一套我自己在Matlab里搭起来的方案基于单调广义学习系统MBLS和Copula理论的时空概率预测模型。它会覆盖从理论动机到公式推导再到可跑的Matlab代码拆解、评价指标、踩坑记录整体更偏能落地的项目笔记而不是教科书式的概念罗列。文章内容会尽量贴近实际工程习惯代码细节也会按模块拆开讲方便你直接拿去改场景。1. 光伏预测的痛点点预测为什么不够用时空概率预测到底解决什么问题先说一个我入行前两年经常被问的问题光伏功率预测意义是什么答案其实很朴素——电网需要提前知道未来几个小时甚至几分钟内分布式光伏会产生多少功率才能安排备用容量、储能充放电和旋转备用。当前做预测的方法已经很多物理模型、统计学习方法、深度学习方法都能给出不错的点预测值。但这几年实际做下来我发现一个绕不开的瓶颈光伏出力的不确定性根本不是点预测能表达清楚的。1.1 超短期预测的业务场景与不确定性来源光伏功率预测按时间尺度通常分成中长期、短期、超短期。中长期以天或周为单位主要用于发电计划安排和检修计划短期以小时为单位主要用于日前调度超短期则是未来0到4小时粒度可以细到15分钟甚至5分钟主要服务于实时调度、AGC调频和储能充放电策略。超短期的难点在于它面对的不确定性最尖锐。云团遮挡是最大的随机源——一块云飘过来可能30秒内让电站出力从80%掉到20%再飘走又快速恢复。温度变化、气溶胶、空气湿度、风速风向都会叠加影响。这种高频的物理过程靠确定性模型很难完整刻画。所以超短期预测的实际需求并不是中午12点出力是多少而是中午12点出力在某个区间内的概率是多少、未来4小时的出力轨迹最有可能怎样波动。这正是概率预测的用武之地。1.2 从点预测走向概率预测P50、P90和风险量化概率预测和点预测最核心的差别是它输出的是一个概率分布或分位数而不只是一个期望值。比如我预测某时刻光伏出力是50MWP50同时还可以给出P90是42MW、P10是58MW这表示出力有80%的概率落在42到58MW区间。对调度人员来说这个信息非常直接好用。调备用容量时做保守策略可以按P10或P90来留裕度储能充放电策略可以依据概率区间来划分风险等级考核时点预测误差也不再是一个孤立数字而是可以落在概率框架内做综合评分。现在常用的CRPS、Pinball Loss等指标本质上就是在量化这个概率预测的质量好不好。1.3 时空维度为什么单站点预测不够还需联合多个电站的信息单站点概率预测只是解决了时间维度上的不确定性表达。但实际业务里一个区域往往有成片的分布式光伏它们在地理上相邻、共享大尺度天气系统出力曲线有明显的空间相关性。举个例子某区域分布着A、B、C三个电站A站被云遮挡导致出力骤降B和C站大概率也会在一段时间后出现类似波动只是幅度和滞后时间不同。如果只做单站预测A站突变对B站的影响是完全丢失的。如果能把这种空间关联建模进来预测的鲁棒性会明显提升。这就是时空概率预测的核心思想在时间维度上每个站点先建立自身的概率预测模型在空间维度上通过Copula把多个站点的边缘分布拼接成联合分布从而捕捉站间相关结构并在此基础上生成多站点一致的预测场景。1.4 MBLS和Copula方案的整体逻辑整套方案可以概括成三步逐站点建立时序特征用MBLS输出每个站点未来时刻的边缘概率分布。用Copula拟合站点间出力的相关结构得到联合分布。从联合分布中采样生成多站点一致的预测场景再汇总到区域功率预测。为什么用MBLS而不是更花哨的Transformer或LSTM这个我后面会专门讲。核心原因有两个一是物理一致性——光伏功率对辐照度有天然单调关系MBLS可以把这个先验约束嵌进模型结构二是工程友好——MBLS训练快、参数少在Matlab里实现非常顺滑不需要搭自动求导图。Copula的引入则解决了每个站点单独输出分布、但无法整合成联合分布的问题。它是连接边缘分布和联合分布的桥梁也是这套方案的时空部分。2. Copula理论到底是什么光伏时空联合分布建模的实用路径很多做光伏预测的朋友一听Copula就觉得是数学大山其实它做的事情可以打一个很直接的比方。2.1 用相亲网站理解Copula边缘分布与相关性结构解耦假设你要给两个人做匹配度评估。每个人都有自己的性格分数分布相当于光伏电站各自的功率边缘分布但两个人合不合得来并不完全取决于个人分数还取决于他们性格之间的互动模式相当于站点之间的相关性。Copula要做的就是先把各自的分数分布和互动模式分开建模最后再合成一个完整的联合图景。Sklar定理是这个理论的地基任何一个多维联合分布都可以拆成一个Copula函数加上各自的边缘分布。反过来把Copula和边缘分布组合起来也一定能得到合法的联合分布。这意味着在光伏场景里我可以自由地为每个站点选择一个拟合效果最好的边缘分布同时用Copula独立地建模站间相关结构两个环节互不干扰。2.2 常用Copula函数的选型哪些适合光伏出力常用Copula大致分椭圆族和阿基米德族。椭圆族里Gaussian Copula和t Copula是最常见的。Gaussian Copula实现简单参数由一个相关矩阵完全确定适合做快速建模t Copula有更厚的尾部能刻画极端波动同时爆发的场景。阿基米德族里Clayton Copula对下尾相关敏感适合描述多个电站同时大幅下跌的极端事件Gumbel Copula对上尾相关敏感适合描述同时高涨Frank Copula则是对称结构适合平稳时段的相关性。光伏出力有一个明显的物理特征夜里出力都是0白天出力随辐照波动多站点之间的相关性在大出力时段和低出力时段表现截然不同。实际使用中我通常不会固定用某一种Copula而是按时间段滚动筛选在每一轮预测里比较Gaussian、Clayton、Gumbel、Frank的拟合效果选出最优的来采样。2.3 从边缘分布到联合分布一个简单可操作的建模流程用Copula建模站点相关性步骤大致是对每个站点的功率序列做边缘分布拟合得到各自的CDF。把功率观测值通过各自CDF变换成均匀分布变量U。用U序列估计Copula参数。推导出条件Copula或在联合Copula上直接采样。把采样结果通过各自边缘分布的逆CDF还原成功率值。这套流放在Matlab里跑很顺手主要是Statistics and Machine Learning Toolbox里已经内置了copulafit、copularnd、kdedensity这些现成函数不需要重复造轮子。2.4 条件Copula与滚动预测的配合方式光有静态联合分布还不够。光伏站点的相关结构会随天气类型、时段切换而变化——晴天时所有站点都跟着辐照走相关性强多云天时局部遮挡导致相关性忽高忽低雨天则整体低出力相关性又回到另一个水平。所以我在方案里用的是滚动联合建模以一定步长更新Copula参数每一轮预测只使用最近一段时间窗口内的观测数据来重新估计相关结构。这样既保留Copula表达联合分布的能力又确保相关性参数不会因为数据跨度过长而失效。2.5 Copula在光伏功率预测中的边界在哪有一点必须说清楚Copula本身解决的是相关结构建模问题它不会替你创造预测精度。如果你的站点边缘分布本身拟合得很差再好的Copula也救不回来——因为Copula拿到的是边缘CDF变换后的均匀序列边缘分布的偏差会传导进整个联合模型。另外站点数量增加时Copula参数维度会迅速膨胀。Gaussian Copula的相关矩阵需要估计k(k-1)/2个自由参数站点数量超过十多座时就需要做正则化或改用vine copula。实际项目里我通常会把站点按区域聚类每类只选代表站参与联合建模降低维度压力。3. MBLS单调广义学习系统宽学习框架下的单调性约束现在来说说模型主体。MBLS这个名字里有三个关键信息单调性、广义、学习系统。3.1 广义学习系统BLS的核心结构特征节点与增强节点BLS是澳门大学陈俊龙老师团队提出的一种神经网络结构不同于深度网络的逐层堆叠它追求的是够用就好——一次性生成足够多的特征节点和增强节点然后通过岭回归直接求解输出权重。这样做的好处非常明显训练过程不需要反向传播不需要迭代调参速度和稳定性都好。对光伏预测这类需要频繁滚动训练的场景BLS比深度网络实用得多。BLS的构造大致分几步对输入数据做特征映射生成一组特征节点。把特征节点再做非线性变换生成增强节点。把特征节点和增强节点拼接在一起形成最终的输入矩阵。用岭回归求解输出权重W。代码层面核心就是矩阵的横向拼接和一次伪逆运算。Matlab里可以用 \ 运算或者pinv函数便捷实现。3.2 单调性约束的动机物理规律如何嵌入模型结构光伏功率有一个非常明确的物理规律在相同环境条件下辐照度越强输出功率越大。这是一个单调递增关系。常规神经网络不会内置这个规律它可能需要大量数据才能学到这种单调趋势而且在小样本、数据稀疏的区域还可能学歪。MBLS的思路是直接把单调性作为约束写入优化目标或网络结构让模型在结构上就保证预测值随关键特征单调变化。这个思路在实践中非常有用。比如某光伏电站在清晨和傍晚辐照较低某些神经网络模型可能因为温度、风速等其他特征干扰在辐照升高时反而预测功率下降——这种明显违反物理规律的结果在工程上是很难被调度侧接受的。MBLS的单调约束可以从源头避免这类情况。3.3 MBLS的数学模型与求解细节MBLS和标准BLS的差别主要是在目标函数里增加了一个单调性惩罚项。设输入为X输出权重为W模型预测值为Y_hat A * WA是特征节点与增强节点的拼接矩阵。标准BLS目标是最小化预测误差与正则项之和min_W ||A W - Y||^2 λ ||W||^2MBLS会把单调性约束以惩罚项形式加入min_W ||A W - Y||^2 λ1 ||W||^2 λ2 * monotonic_penalty(W, X, sensitivity_dir)其中monotonic_penalty衡量的是当关键特征比如辐照度沿某一指定方向变化时模型输出是否同向变化。实际操作中可以对X做微小扰动求输出对扰动方向的偏导或差分再把反向变化的部分作为惩罚。这里要注意惩罚项并不是让模型对每个样本都满足单调关系而是从整体分布上迫使模型结构符合单调趋势。全部强制单调反而可能过度约束牺牲预测精度。λ2的取值需要调参我通常会在验证集上做小范围网格搜索。MBLS的优势在于整个目标函数仍然是凸优化问题当单调惩罚项设计为对W的凸函数时可以用闭合解或快速迭代求解不会陷入局部极小。3.4 为什么选MBLS而不是LSTM、Transformer我理解很多朋友看到时序预测第一反应是LSTM或者Transformer。它们确实在很多场景表现好但在光伏超短期概率预测这个任务上有几个现实问题一是数据量。单个电站超短期预测往往只有几个月到一年的高质量数据深度模型容易过拟合。二是训练效率。概率预测需要滚动训练、反复实验LSTM调一次参的时间MBLS早就完成一轮批量滚动测试了。三是可解释性和物理一致性。深度模型输出任意、结构黑箱想加单调约束很困难。MBLS在这三点上恰好都有优势。当然MBLS不是万能的它在复杂非线性动态特征的建模能力上不如LSTM强劲所以通常会用特征工程来补充把辐照度、温度、湿度、风速、云量、历史功率等特征尽量构造好。3.5 MBLS的概率化改造从点输出到分布输出概率预测要求模型输出分布而标准BLS输出的是点值。需要做一层概率化改造。我用的方法是分位数回归改造对多个目标分位数τ分别训练MBLS模型每个模型优化的是加权绝对误差而不是均方误差min_W sum( ρτ (Y - A W) )其中ρτ是分位数损失函数。这样每个站点就可以同时得到P5、P25、P50、P75、P95等多个分位数预测构成该时刻的经验分布。分位数的好处是不需要对预测误差做正态假设对光伏出力这种有界、偏斜的序列更稳妥。得到分位数后可以用线性插值或核平滑的办法构造出边缘CDF为Copula建模做准备。4. 时空概率预测模型整体框架与预测流程把MBLS和Copula串在一起就构成了完整的时空概率预测框架。这个框架不是一个固定不变的模板而是按业务需求可以灵活调整的管线。4.1 数据准备与预处理时间对齐是第一个坑多站点时空建模第一件事就是把各站点数据对齐到同一时间轴。光伏电站数据最常见的问题是数据缺失、时间戳错位、以及不同站点采样粒度不一致。我的处理流程是统一时间分辨率为15分钟超出范围的数据做插值。对功率值做线性插值补齐缺失点但插值区间超过2小时的直接标记为缺失不硬补。对辐照度、温度等气象变量做同一处理。所有特征按训练集统计量做归一化避免数据泄露。归一化这一步很容易踩坑如果用全量数据的统计量做归一化相当于让模型偷看了未来信息。正确做法是只用训练集的均值方差验证集、测试集都沿用训练集的参数。4.2 特征构造哪些特征对光伏功率影响最大我常用的特征分为三类历史出力特征目标站点过去1、3、6、12个时间点的功率值。气象特征辐照度、温度、风速、湿度、云量其中辐照度是最关键的单调特征。空间特征邻近站点过去几帧的功率值。把空间特征纳入MBLS输入就是时空预测的第一层体现——模型输入里已经带有邻近站点的信息。到了Copula环节则是第二层体现——站点之间的联合分布和相关结构。特征窗口的选择需要根据预测时效来定。做15分钟前向预测过去6个点1.5小时的窗口通常就够了做4小时预测则需要把窗口放大到24个点以上。4.3 模型训练逐站点MBLS分位数模型的滚动训练整体流程是对每个站点分别训练5个分位数模型P5、P25、P50、P75、P95。训练窗口采用滚动方式用过去30天数据训练向后预测未来4小时。每15分钟滚动一次即每产生一个新的观测值就重新训练一次模型。滚动训练听起来计算量很大但MBLS好在训练快单次训练通常在秒级完成。五站五分类也就25个模型在Matlab里用parfor并行训练整体开销完全可以接受。4.4 Copula参数估计连接多个站点的边缘分布当各站点的分位数模型都预测完毕会得到每个站点在预测时段内的边缘CDF和分位数曲线。这个时候需要对历史观测值做概率积分变换得到各站点的均匀序列U再用U来估计Copula参数。Matlab里直接调用copulafit函数即可。需要特别注意copulafit对输入的要求它要求输入是均匀分布的数据列范围在(0,1)。如果数据有0或1的极值很容易报错或得到无穷大参数需要先做极值压缩比如把边界值替换为1e-6和1-1e-6。4.5 场景生成从联合分布到多站点一致预测完成Copula参数估计后就可以在联合分布上采样生成多站点一致的预测场景。具体来说从已拟合的Copula中生成N个多维均匀随机数copularnd。把每个均匀随机数通过对应站点的边缘逆CDF变换成功率值。每个采样结果就是一组多站点的联合出力场景。这个做法的价值在于如果只对各站点独立预测后直接拼接生成的场景会丢掉站点间相关性——A站暴跌和B站暴涨可能同时出现而这种组合在物理上几乎不可能。Copula采样则保证了场景内部的空间一致性。比如预测未来1小时采样500条场景调度侧想要区域总功率风险就把每个场景里各站点出力求和得到500个区域总功率值再统计分位数给调度做参考。4.6 评价指标CRPS、Pinball Loss、区间覆盖率模型做好后质量怎么评估我常看这几个指标Pinball Loss分位数回归的自然评估指标越小越好。CRPS连续排名概率分数衡量概率分布和真实观测的差距越小越好。区间覆盖率例如P90区间实际观测落在区间内的比例是否接近90%。区间平均宽度覆盖率达标的前提下区间越窄越好。覆盖率与区间宽度是一对矛盾。模型如果只追求覆盖率把区间拉得很宽很容易做到但没有实用价值。好的概率预测应当是覆盖率准确且区间尽量窄。5. Matlab代码实现关键模块与实操细节下面进入代码层面。这里会按照跑通整套流程的顺序拆开讲解每个模块的实现思路和Matlab代码要点。5.1 主程序结构设计整个项目我会分成几个文件main_time_space_probabilistic_forecast.m主脚本。data_preprocess.m数据读取与预处理函数。train_mbls_quantile.mMBLS分位数模型训练函数。fit_copula_multi_site.mCopula拟合函数。generate_scenarios.m联合场景生成函数。evaluate_prob_forecast.m评价指标计算函数。Matlab工程化的好处是调试方便命令行直接看变量断点检查很直观。5.2 MBLS分位数模型训练代码MBLS训练的核心代码如下function [W, Parameters] train_mbls_quantile(X, Y, tau, s, c, lambda1, lambda2) % X: 输入特征矩阵N x D % Y: 目标值N x 1 % tau: 目标分位数如0.5 % s: 特征节点窗口数量 % c: 增强节点数量 % lambda1: 正则化系数 % lambda2: 单调惩罚系数 [N, D] size(X); % Step 1: 生成特征节点 Z zeros(N, s); W_init cell(s, 1); for i 1:s We randn(D, 1) * 0.1; W_init{i} We; Z(:, i) tanh(X * We randn * 0.1); end % Step 2: 生成增强节点 H zeros(N, c); Wh_init randn(s, c) * 0.1; Bh randn(1, c) * 0.1; for j 1:c H(:, j) tanh(Z * Wh_init(:, j) Bh(j)); end % Step 3: 拼接特征节点和增强节点 A [Z, H]; % Step 4: 分位数损失权重 % 分位数回归使用非对称绝对损失可改写为加权最小二乘迭代逼近 W zeros(size(A, 2), 1); Y_hat A * W; for iter 1:20 resid Y - A * W; weight tau * (resid 0) (1 - tau) * (resid 0); WeightMat diag(weight); % 单调惩罚项选择关键特征列如辐照度计算对关键特征的有限差分 sens zeros(N, 1); delta 0.01; for i 1:N X_perturb X(i, :); X_perturb(1) X_perturb(1) delta; % 假设第1列为辐照度 a_perturb A(i, :) (tanh(X_perturb * W_init{1}) - Z(i, 1)) * W_out_partial_hack; sens(i) (a_perturb * W - A(i, :) * W) / delta; end % 惩罚反向单调的样本 mono_penalty max(0, -sens); % 加权目标分位数损失 L2正则 单调惩罚 W (A * WeightMat * A lambda1 * eye(size(A, 2)) lambda2 * (A * diag(mono_penalty) * A)) \ ... (A * WeightMat * Y); end Parameters.W_init W_init; Parameters.Wh_init Wh_init; end上面的代码为了便于阅读我把单调惩罚的细节做了简化处理。实际工程代码里我不会在每次加权最小二乘迭代里都算一遍敏感性而是会预先计算关键特征的梯度方向矩阵用矩阵运算一次性完成。5.3 Copula拟合与场景生成代码Copula部分Matlab自带函数可以省掉大量手写工作function [copula_params, U] fit_copula_multi_site(Y_sites) % Y_sites: T x M 矩阵M个站点在T个时刻的观测功率 % 返回Copula参数和概率积分变换后的均匀序列 [T, M] size(Y_sites); U zeros(T, M); for m 1:M % 使用核密度估计边缘CDF [f, xi] ksdensity(Y_sites(:, m), Function, cdf); U(:, m) interp1(xi, f, Y_sites(:, m), linear, extrap); U(:, m) min(max(U(:, m), 1e-6), 1 - 1e-6); end % 选择Copula类型这里以Gaussian Copula为例 rho copulafit(Gaussian, U); copula_params.rho rho; copula_params.type Gaussian; end场景生成代码function scenarios generate_scenarios(copula_params, edge_params, N_scenarios) % 从Copula联合分布采样并还原为功率场景 U_sim copularnd(Gaussian, copula_params.rho, N_scenarios); % U_sim: N_scenarios x M scenarios zeros(N_scenarios, length(edge_params)); for m 1:length(edge_params) % 逆CDF变换边缘分布参数存储在edge_params{m} scenarios(:, m) icdf(edge_params{m}.dist, U_sim(:, m), edge_params{m}.params); end end这里edge_params是每个站点边缘分布拟合结果。你可以用正态、t或核密度分布具体选哪个要用历史数据做拟合优度检验。5.4 概率评价指标计算代码评价指标这块代码不复杂但很关键function [crps, pinball, coverage, width] evaluate_prob_forecast(obs, quantiles, tau_list, lower, upper) % obs: 观测值 % quantiles: 预测分位数矩阵N x length(tau_list) % tau_list: 分位数列表如[0.05, 0.25, 0.5, 0.75, 0.95] % lower, upper: 预测区间上下界 % Pinball Loss pinball zeros(1, length(tau_list)); for t 1:length(tau_list) tau tau_list(t); err obs - quantiles(:, t); pinball(t) mean(max(tau * err, (tau - 1) * err)); end % CRPS近似计算 crps mean(sum((quantiles - obs) .* ((quantiles obs) - tau_list), 2)); % 区间覆盖率 coverage mean((obs lower) (obs upper)); % 区间平均宽度 width mean(upper - lower); endCRPS严格定义是概率分布与真值之间的积分误差上面用的是分位数近似叫Quantile CRPS近似在工程上已经足够用。如果想要更精确的CRPS可以对多分位数插值模拟CDF后再算积分。6. 实测中的经验与避坑建议代码能跑起来只是第一步真正让预测结果稳定可靠需要处理很多工程细节。下面这些坑都是我自己踩过的。6.1 数据泄露归一化和滚动窗口的隐性陷阱前面提过归一化只能用训练集统计量。但滚动训练还有一个更隐蔽的坑滚动窗口如果和数据标签之间存在重叠模型会偷看到未来信息。比如你预测t4时刻的功率特征里却包含了t5时刻的观测值可能因为数据对齐失误那预测误差会极其漂亮一上真实环境就崩。我的习惯是在构造数据集时严格遵守特征时间必须早于标签时间的原则并用代码做一次时间戳检查。6.2 Copula拟合失败边界值、时间窗口、维数灾难copulafit报错是我遇到过最多的问题。常见原因是U序列里出现0或1前面提到用1e-6压缩边界可以解决。另一个问题是时间窗口太短导致相关矩阵非正定。Gaussian Copula要求相关矩阵正定如果观测天数太少可能出现非正定矩阵。解法是窗口至少要有30天以上的日观测数据如果是15分钟粒度则需要至少连续两周的数据。站点数量特别多时Copula参数估计会变得不稳定。我不会把二十个站点全部塞进一个Copula而是先做区域聚类每个聚类用一个代表站该区域内所有站点的平均出力再对代表站集合做联合建模。6.3 单调约束强度λ2的调参逻辑单调惩罚项设置太强模型对辐照度变化会变得过于机械——比如清晨辐照度从100升到120模型强制出力必须上升但实际因为云层遮挡出力反而是下降的。我自己调参的经验是λ2并不是越大越好。初始可以设成0先跑一版纯BLS作为基线然后逐步增大λ2观察验证集上Pinball Loss是否下降、单调性违规比例是否下降。当选到某个λ2让Pinball Loss最低时就停住。这个值往往不大在0.01到1之间。6.4 边缘分布拟合不要迷信正态分布很多Copula教程里边缘分布一条t或正态走天下但在光伏场景下功率分布有大量零值和饱和值呈现明显的双峰甚至多峰形态。我会用混合分布来拟合一部分是离散的0值概率另一部分是连续区间上的分布。在Matlab里可以用fitdist对非零部分拟合再把零值概率单独建模。这样得到的边缘CDF更贴合实际Copula拟合的质量也会更好。6.5 可视化概率预测结果如何让调度看懂最后提一下可视化。模型输出最终要交给业务方看一堆分位数表格是没法直接用的。我习惯画一个扇形图中间是P50预测曲线上下逐渐扩展出P25到P75、P05到P95的色带。Matlab里用fill命令或者patch命令叠加半透明色带效果很直观。再配合Copula场景图——随机抽几条联合场景曲线展示多站点在不同天气模式下的联动效果。调度人员看到这种图比看一百个指标更能理解时空概率预测的价值。我自己的体会是这套CopulaMBLS方案真正厉害的地方不在于某一个指标把RMSE压到多低而在于它把光伏预测该有的样子完整地搭建出来了——每个站点有自己的概率分布站点之间有关联结构生成场景具备空间一致性评价体系与业务风险直接挂钩。工程上要落到具体电站还需要结合当地气候特点调特征和参数但这些工作都是在一个稳固的框架上做微调不会推倒重来。如果你正准备在校项目或者电站技改里引入概率预测建议先拿两三个站点、一个月数据把整条管线跑通再逐步扩大站点规模和预测时长。把基础框架踩稳后面的优化才有意义。