☰
风电光伏随机性建模:Weibull与Beta分布的Matlab组合实现
2026/9/29 17:02:47 网站建设 项目流程

做风电和光伏出力的随机性建模时,绕不开两个经典分布:表征风速随机性的Weibull分布,以及描述光伏出力占比特征的Beta分布。很多论文里都有“风速服从Weibull分布、光伏功率服从Beta分布”这句话,但真正想在Matlab里把两套模型拟合出来、组合起来、再评估效果,并没那么顺手。这篇博文我从实际项目角度出发,把从数据生成、参数估计、组合建模到结果可视化的完整流程拆开讲清楚,代码直接可跑。

适合正在写新能源方向论文、做微电网容量配置或者搞功率预测的读者。不需要你有多深的数学功底,但最好用过Matlab基础语法,至少知道histogram和plot的区别。看完之后你能复现风电和光电概率分布的组合分析,也能根据自己场站的数据替换出结果。

1. 组合建模思路:为什么是Weibull与Beta

1.1 风电随机性:风速Weibull模型的来龙去脉

风电的随机性本质上来自风速的随机性。风速不是一个稳定值,它受气压、地形、温度等多种因素影响,实测数据通常表现为右偏、厚尾的形态。两参数Weibull分布的概率密度函数是:

f(v) = (k/λ) * (v/λ)^(k-1) * exp(-(v/λ)^k)

其中v是风速,k是形状参数,λ是尺度参数。k控制密度曲线的形状:k小于1时曲线在零点附近陡峭上升,风速大多集中在极小区间;k等于2附近时曲线接近瑞利分布,这是很多风资源报告里默认的情况;k大于3时峰形变得尖锐,风速集中在某个值附近。λ则大致决定风速的数值级别,直接和平均风速挂钩。

我见过很多初学者纠结要不要用三参数Weibull,就是多一个位置参数μ,把分布起点从0平移到某个风速。工程上两参数基本够用,三参数虽然拟合偏差小一些,但参数辨识的稳定性变差,数据量不够时经常出现不收敛或者拟合参数明显不合理。除非你手上风速数据存在很明显的“零风速时段较多”且地点特殊,否则优先用两参数。

不过这里有个关键点需要说清楚:标题里说的是“风电的Weibull分布”。实际建模有两种做法,一种是直接对风速样本做Weibull拟合,然后用功率曲线把风速分布映射为风电功率分布;另一种是干脆把风电功率样本当随机变量,直接拟合成Weibull。我个人更推荐第一种,因为风速的Weibull分布物理意义清晰,参数稳定,而功率样本里大量0值和满发值会让Weibull拟合变得很难看。

1.2 光伏随机性:Beta分布为什么刚好合适

光伏出力的随机性来自光照辐照度、温度、云层遮挡等因素。与风速不同,光伏出力有一个天然边界:功率只能从0到额定容量。用标幺值表示就是0到1之间的数。Beta分布恰好定义在[0, 1]区间内,概率密度函数是:

f(x) = x^(α-1) * (1-x)^(β-1) / B(α, β)

其中B(α, β)是Beta函数,α和β都是大于0的形状参数。α和β的取值直接影响分布形态:α=β=1时是均匀分布;α和β都大于1时分布呈单峰形态,且峰值位置由两者比值决定;α小于β时密度曲线偏向左侧,表示光伏出力偏小的时间更多,这对很多多云地区很符合。

从数学上看,Beta分布几乎是描述光伏出力的“天选之子”——有界、单峰、左右偏态灵活可调。实际处理时,光伏出力数据经常包含夜间零出力时段,如果全年逐小时数据直接送进拟合,会把分布拉向0.1以下的极端区间。所以工程上常规做法是:分离零出力和正出力,对正出力部分做归一化,然后拟合Beta分布;或者使用零膨胀Beta模型。后面对这个坑会有详细说明。

1.3 两条组合路线怎么选

“组合研究”这四个字在不同论文里含义差别挺大。我归纳为两条主流路线:

第一条是加权混合分布。把风电功率分布和光伏功率分布按权重叠在一起,形成总出力的概率密度函数。设风电装机容量占比为w,则组合密度函数是f_total(x) = w * f_wind(x) + (1-w) * f_solar(x)。这个形式简单,适合做解析推导,但它的物理含义不是“风电和光伏同时出力的总和”,而是“随机抽取一个时刻,该时刻出力来自风电或光伏的概率密度”。换句话说,它描述的是整体电力出力的分布特征,适合宏观分析。

第二条是联合抽样或卷积。利用风电、光伏各自的分布抽样,然后把两者出力相加(可按装机容量比例缩放),得到总出力样本,再估计总出力分布。这个方法更贴近工程实际,微电网容量配置、可靠性评估、储能容量优化都是基于这种“两个随机源叠加”的逻辑。

要做选择,关键看你的目标。如果论文方向偏概率建模、解析表达式,走混合模型路线;如果偏规划运行、需要模拟总出力序列,走联合抽样路线。本文两种都会给出实现,你按需取用。

2. 数据准备与分布参数估计

2.1 数据准备:没有场站数据怎么验证算法

很多人卡在第一步不是因为没有方法,而是没有数据。手上有真实风电站和光伏电站的历史数据自然没问题,直接读进来用。如果没有,可以用Matlab自带随机数函数合成一套带已知真值的数据,用来验证拟合程序是否写对。

% 固定随机种子,保证结果可复现 rng(42); % 一年小时级数据,共8760个点 n = 8760; % 用已知参数的Weibull分布生成风速样本 v_true_k = 2.1; % 真实形状参数 v_true_lambda = 6.5; % 真实尺度参数 (m/s) v_sample = wblrnd(v_true_lambda, v_true_k, n, 1); % 用已知参数Beta分布生成光伏出力样本(标幺值) pv_true_a = 2.2; % 真实alpha pv_true_b = 3.8; % 真实beta pv_sample = betarnd(pv_true_a, pv_true_b, n, 1);

这里用wblrnd生成Weibull样本,用betarnd生成Beta样本,两个函数都是Matlab Statistics and Machine Learning Toolbox里的。注意wblrnd的前两个参数顺序是(scale, shape),也就是(λ, k),和很多论文里的书写习惯不一致,我当年第一次用就因为这个顺序搞反,拟合出的参数完全对不上。后面所有用到的地方都要留意这个顺序。

合成数据的最大好处是:你在拟合后可以把估计值和真值对比,直接判断算法实现是否正确。比如上面生成的v_sample,用wblfit拟合后得到的λ应该接近6.5,k接近2.1;对pv_sample用betafit拟合后得到的α接近2.2,β接近3.8。如果对不上,就要回头检查代码了。

2.2 Weibull参数估计的Matlab实现细节

Matlab里做Weibull参数估计最简单的办法是直接用wblfit,它基于极大似然估计。一行代码就能得到参数结果:

% 对风速样本拟合Weibull分布 phat = wblfit(v_sample); lambda_fit = phat(1); % 尺度参数 k_fit = phat(2); % 形状参数

跑完以后对照一下:lambda_fit约6.52,k_fit约2.08左右,与真值接近。之所以不完全相等,是因为有限样本估计本身就存在抽样误差,这很正常。如果你想让结果更稳定,可以加大样本量到87600甚至更多,误差会进一步缩小。

除了极大似然,工程上还有矩估计和经验公式。矩估计的思路是利用Weibull分布的均值和方差与参数的解析关系反解参数。Weibull分布的均值μ与λ、k的关系是μ = λ * Γ(1 + 1/k),其中Γ是伽马函数。如果已知样本均值和标准差σ,可以用一个近似公式估算k:

k ≈ (σ/μ)^(-1.086)

然后通过λ = μ / Γ(1+1/k)反算λ。这个公式在风速资源评估中很流行,手算或者在没有统计工具箱的环境下都能用。在Matlab里也可以直接用gamrnd配合迭代去解,但既然有wblfit,我建议你直接用内置函数,把重点放在后续组合分析上,不要在基础拟合上重复造轮子。

有一点必须提醒:wblfit对输入数据的范围很敏感。如果风速向量里有NaN、0或者负值,拟合结果可能异常。风速为0时,Weibull分布的概率密度在某些k值下趋近无穷,极大似然迭代可能会出问题。后面专门讲零值处理。

2.3 Beta参数估计的Matlab实现细节

Beta分布的参数估计同样可以直接用Matlab的内置函数:

% 对光伏出力样本拟合Beta分布 abhat = betafit(pv_sample); alpha_fit = abhat(1); beta_fit = abhat(2);

betafit同样是极大似然估计,内部用迭代算法求解。跑完以后alpha_fit差不多在2.2附近,beta_fit在3.8附近。这个函数用起来很简单,但有几个坑是文档里不会写的:

第一,输入数据必须严格处于[0, 1]区间。如果你用光伏出力(kW) / 装机容量(kW)得到标幺值,理论上是0到1,但因为测量误差或者被四舍五入,可能出现1.000000001这样的值,betafit直接报错或者警告。处理办法是把数据做一次clip:x = min(max(x, eps), 1-eps)。

第二,数据中的0和1会让Beta分布的边界出现奇异。光伏出力为0的夜间时段如果全扔进去,Beta拟合会试图用一个极端的参数组合去匹配这个零质量,结果就是α被压到很小,曲线变得特别难看。建议做法是:先用逻辑索引把pv_sample拆成pv_zero(等于0的部分)和pv_pos(大于0的部分),只对pv_pos做归一化后拟合Beta。后面评估总体分布时,再带上零出力的概率质量。

第三,betafit在数据量太少时可能不收敛。如果你只有几十个点,拟合结果可能出现NaN。一般样本量最好在100以上,做新能源出力分析时,最少也得一个月逐小时数据,也就是720个点,通常没问题。

3. 完整Matlab实现:拟合、组合与可视化

3.1 从风速Weibull到风电功率分布的转换

现在进入核心实操。对风速做Weibull拟合拿到参数以后,下一步是把风速分布转换为风电功率分布。这需要一条功率曲线。常规风机的功率曲线近似如下:切入风速v_ci,额定风速v_r,切出风速v_co。低于切入风速或者高于切出风速时出力为0,切入到额定之间近似线性爬升,额定到切出之间保持满发。

% 典型风机功率曲线参数 v_ci = 3; % 切入风速 (m/s) v_r = 12; % 额定风速 (m/s) v_co = 25; % 切出风速 (m/s) p_rated = 1; % 额定功率标幺化 % 将风速样本映射为风电功率样本 function p = windPowerCurve(v) p = zeros(size(v)); idx_ramp = (v >= v_ci) & (v < v_r); idx_full = (v >= v_r) & (v < v_co); p(idx_ramp) = (v(idx_ramp) - v_ci) / (v_r - v_ci); p(idx_full) = p_rated; end p_wind_sample = windPowerCurve(v_sample);

这段代码把风速样本映射成了风电功率样本,量纲已经统一到标幺值。接下来你可以把p_wind_sample的分布画出来,大概率会看到两个尖峰:一个在0附近,对应风速低于切入风速;一个在1附近,对应满发时段。中间爬升段的分布比较平坦。这种现象在实际风电功率数据里非常常见,所以直接对功率样本强行做Weibull拟合时效果普遍不好,这也印证了我前面说的“先拟合风速,再映射功率”的思路。

如果你想从风速Weibull分布解析推导风电功率的密度函数,也不是不行,但涉及到分段变换和雅可比行列式,公式比较繁琐。工程上直接用Monte Carlo抽样加核密度估计(ksdensity)就能得到功率分布曲线,简单又够用。后面组合阶段也是基于抽样样本,所以这里不需要强行写出解析表达式。

3.2 加权混合模型与蒙特卡洛联合抽样的实现

到了最核心的组合环节。我按两条路线分别给代码。

先看加权混合模型。假设风电装机占比为w,光伏装机占比为1-w,组合分布密度为两者概率密度的加权和。风电功率密度用ksdensity从p_wind_sample估计,光伏功率密度直接用Beta拟合后的理论密度函数。

% 路由1:加权混合模型 x = linspace(0, 1, 500)'; w = 0.6; % 风电装机占比 % 风电功率的经验密度估计 [f_wind, xi] = ksdensity(p_wind_sample, x, 'Support', [0, 1]); % 光伏功率的理论Beta密度 f_solar = betapdf(x, alpha_fit, beta_fit); % 组合密度 f_mix = w * f_wind + (1 - w) * f_solar; % 画图对比 figure; plot(x, f_wind, 'r-', 'LineWidth', 1.5); hold on; plot(x, f_solar, 'b-', 'LineWidth', 1.5); plot(x, f_mix, 'k--', 'LineWidth', 2); legend('风电功率密度', '光伏功率密度', '组合密度'); xlabel('标幺化功率'); ylabel('概率密度');

注意ksdensity的Support参数要设为[0, 1],否则风电功率分布会在0附近估算出负区间的密度,这在物理上没有意义。

另一种更贴近工程的做法是蒙特卡洛联合抽样。既然已经得到了风速Weibull分布和光伏Beta分布的参数,就可以直接从这两个分布抽取一批样本,映射到功率并叠加成总出力。

% 路由2:蒙特卡洛联合抽样 N = 10000; v_sim = wblrnd(lambda_fit, k_fit, N, 1); pv_sim = betarnd(alpha_fit, beta_fit, N, 1); % 风速模拟样本映射为风电功率 p_wind_sim = windPowerCurve(v_sim); % 总出力 = 风电出力(按容量占比) + 光伏出力(按容量占比) p_total = w * p_wind_sim + (1 - w) * pv_sim; % 估计总出力的概率密度 [f_total, x_total] = ksdensity(p_total, 'Support', [0, 1]); figure; histogram(p_total, 50, 'Normalization', 'pdf', 'FaceAlpha', 0.3); hold on; plot(x_total, f_total, 'k-', 'LineWidth', 2); xlabel('总出力(标幺值)'); ylabel('概率密度');

两条路线得到的结果在含义上略有不同。混合模型得到的是“整体出力的解析密度”,联合抽样得到的是“两个电源真正叠加后的总出力分布”。如果你做储能容量配置或可靠性评估,用后者;如果你写综述性文章、只描述分布形态,用前者。

顺带提一个参数问题:w的取值直接决定结果形态。按装机容量比取值是最常规的,比如风电场50MW、光伏电站50MW,w=0.5。但有的论文会按“保证率”或“置信度”来优化w,常见做法是让组合分布尽可能贴近历史总出力分布,用KL散度最小化来搜索w。具体方法我放到第4部分讨论。

3.3 结果可视化的输出要点

做概率分布分析,图比数字重要。审稿人和导师第一眼看的是分布曲线是否平滑、拟合是否贴合、组合形态是否合理。我的经验是多输出四类图,基本就能覆盖需求。

第一张图:风速直方图与Weibull拟合曲线叠加。用histogram的Normalization设为pdf,密度直方图才能和理论密度函数在同一个尺度上对比。

figure; histogram(v_sample, 50, 'Normalization', 'pdf', 'FaceAlpha', 0.4); hold on; v_line = linspace(min(v_sample), max(v_sample), 300); plot(v_line, wblpdf(v_line, lambda_fit, k_fit), 'r-', 'LineWidth', 2); xlabel('风速 (m/s)'); ylabel('概率密度'); legend('实测直方图', 'Weibull拟合');

第二张图:光伏出力直方图与Beta拟合曲线叠加。如果对正出力部分单独拟合,记得把零出力的概率单独标注在图上,否则看到直方图在0附近有一根很高的柱子,会让人误以为拟合失败。

第三张图:组合模型对比。把风电功率密度、光伏功率密度、组合密度画在同一张图,标出装机占比。这张图信息量很大,直接说明组合权重的影响。

第四张图:总出力样本的直方图和核密度曲线。这是联合抽样路线的结果输出,配合累计分布函数ecdf绘制CDF曲线,方便后续对比不同装机配比下的出力特性。

所有图建议统一设置坐标系范围,标幺值功率的x轴固定为0到1,风速图的坐标按实际范围调整。字体大小在出版投稿场景建议统一设12磅以上,这里不再赘述。

4. 常见问题与实战避坑指南

4.1 零值、边界值与参数不收敛的处理

这是我在实际数据处理里踩过最多的坑。风速数据经常有0值,光伏数据到了晚上几乎全是0,这两种情况如果直接塞进wblfit和betafit,结果可能完全偏离你的预期。

先处理风速零值。两参数Weibull的支撑集理论上是[0, +∞),但概率密度在v=0处的行为取决于k:k小于1时f(0)趋向无穷,k大于1时f(0)为0。如果样本中0风速比例较高(比如静风频繁的内陆地区),单靠Weibull无法同时拟合“零值频率”和“正风速形态”。一个相对实用的办法是使用混合模型:把零风速的离散概率单独建模,对正风速部分用Weibull拟合。类似的做法在风资源领域叫“离散-连续混合分布”。如果只是为了论文分析且零值比例低于5%,直接忽略零值、只对正风速拟合通常不会有太大问题。

再看光伏的0和1边界。betafit要求输入严格在0到1之间,0和1本身会让似然函数出现退化。处理逻辑分两步:第一步,把数据拆成零出力和正出力两组,记下零出力比例p_zero;第二步,对正出力数据用pv_pos = min(max(pv_pos, eps), 1-eps)做边界收缩,再进入betafit。画总体分布时,要用“p_zero * δ(0) + (1-p_zero) * Beta密度”的叠加形式,其中δ(0)表示0点的冲激质量。

4.2 拟合优度评估:不要只信p值

参数拟合完,当然要评估做得好不好。Matlab有kstest可以做Kolmogorov-Smirnov检验,但带拟合参数的KS检验有个坑:因为参数本身是从样本里估计出来的,直接使用标准临界值会让检验变得保守,大概率拒绝原假设。尤其是样本量在几千以上时,KS检验对微小偏差非常敏感,几乎必然拒绝“样本来自该分布”的原假设。

我实际项目里的做法是多重验证。首先,眼见图:把直方图和拟合曲线叠加,肉眼判断形态是否吻合。这听起来不够“科学”,但在处理海量新能源数据时,视觉判断其实非常有效。其次,算拟合误差RMSE:在直方图密度值和理论密度值之间计算均方根误差,数值越小越好。然后,用KS距离作为参考指标,但不要只看p值,而是看统计量本身的大小。最后,可以做一个Q-Q图,横轴为理论分位数、纵轴为样本分位数,如果散点贴近y=x直线,说明拟合良好。

如果RMSE偏离明显,优先怀疑参数估计是否正确,再看数据预处理是否有问题,比如0值是否处理、边界是否收缩、样本量是否足够。我见过一个案例,某同学拟合光伏Beta分布时没有去掉夜间零出力,结果α被拟合到0.6,密度曲线在0附近翘得很高,RMSE大得离谱,去掉零值以后一切恢复正常。

4.3 组合权重的选择策略与优化思路

组合权重w的选择直接决定组合分布长什么样。最朴素的办法是按装机容量比,简单透明可复现。但如果风电和光伏的实际利用率差异很大,比如当地弃风严重、风电实际出力远低于额定容量,直接用装机比会让组合分布偏高估风电贡献。这种情况下建议按“可用容量”或“平均出力比”来设定权重。

更精细的做法是让组合分布逼近历史总出力分布。你可以取一个候选w的网格,比如0.1到0.9步长0.01,对每个w计算组合分布与历史总出力经验分布的KL散度,选择KL散度最小的w作为最优权重。KL散度计算的核心代码如下:

% 假设 f_hist 是历史总出力的核密度估计,f_mix 是当前权重下的组合密度 kl_div = sum(f_hist .* log(f_hist ./ (f_mix + 1e-12))) * mean(diff(x));

加上一个极小值1e-12是为了防止除零和出现Inf。这种基于数据驱动的权重优化思路,比拍脑袋定权重要有说服力得多,写在论文里也是一个加分项。

我最后还想多一句:以上所有方法本质上都是对随机性的“概率近似”。真实的风电光伏出力还受时间相关性、季节变化、天气过程等因素影响,单靠静态分布并不能完全刻画。分布建模更像是给你提供一把标尺,让你在做规划和调度时心里有底。如果你后续想做更精细的时序模拟,可以考虑把Weibull参数按季节分段,或者给Beta分布加上随时间变化的参数。这个方向我最近也在试,后续有结果再分享。

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

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

立即咨询