ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

MATLAB实现光伏出力曲线模拟与K-means聚类分析

2026/8/7 14:58:09 拓冰建站 浏览量
MATLAB实现光伏出力曲线模拟与K-means聚类分析 1. 光伏曲线聚类的背景与价值光伏发电作为清洁能源的重要组成部分其出力曲线具有明显的昼夜周期性和天气依赖性。在实际应用中我们常常需要对大量光伏出力曲线进行分类分析以便识别不同天气模式下的发电特征优化电站运维策略提高功率预测精度设计更合理的储能系统充放电策略然而获取真实的光伏出力曲线往往面临数据隐私、测量误差等问题。因此使用模拟数据进行分析成为研究光伏曲线特性的重要手段。2. MATLAB生成模拟光伏曲线2.1 基础曲线建模光伏出力曲线通常呈现钟型特征我们可以用高斯函数作为基础模型% 基本参数设置 hours 0:0.1:24; % 时间轴0.1小时间隔 peak_time 12; % 峰值出现在正午 peak_power 1; % 归一化最大功率 width 4; % 曲线宽度参数 % 基础高斯曲线 base_curve peak_power * exp(-(hours-peak_time).^2/(2*width^2));2.2 添加现实噪声真实光伏曲线会受到多种因素影响我们需要添加适当的噪声% 添加随机噪声 noise_level 0.1; noisy_curve base_curve noise_level*randn(size(base_curve)); % 确保功率不为负 noisy_curve(noisy_curve0) 0; % 添加云层遮挡效应 cloud_prob 0.2; % 出现云层的概率 if rand() cloud_prob cloud_start 8 4*rand(); % 云层开始时间 cloud_duration 1 3*rand(); % 云层持续时间 cloud_effect hours cloud_start hours (cloud_startcloud_duration); noisy_curve(cloud_effect) noisy_curve(cloud_effect) .* (0.2 0.3*rand()); end2.3 生成多样本数据集为了聚类分析我们需要生成多条不同特征的曲线num_samples 100; % 生成100条曲线 dataset zeros(num_samples, length(hours)); for i 1:num_samples % 随机化参数 curr_peak 0.8 0.4*rand(); % 峰值功率变化 curr_width 3 2*rand(); % 曲线宽度变化 curr_peak_time 11 2*rand(); % 峰值时间变化 % 生成基础曲线 curve curr_peak * exp(-(hours-curr_peak_time).^2/(2*curr_width^2)); % 添加噪声 curve curve noise_level*randn(size(curve)); curve(curve0) 0; % 随机添加特殊天气效应 if rand() 0.3 % 30%概率添加特殊效应 effect_type randi(3); switch effect_type case 1 % 上午云层 start 8 2*rand(); duration 1 2*rand(); effect hours start hours (startduration); curve(effect) curve(effect) .* (0.3 0.4*rand()); case 2 % 下午云层 start 13 3*rand(); duration 1 3*rand(); effect hours start hours (startduration); curve(effect) curve(effect) .* (0.2 0.5*rand()); case 3 % 全天薄云 curve curve .* (0.6 0.2*rand(size(curve))); end end dataset(i,:) curve; end3. 光伏曲线特征提取3.1 基本统计特征% 计算每条曲线的统计特征 features zeros(num_samples, 6); % 准备特征矩阵 for i 1:num_samples curve dataset(i,:); % 1. 最大功率 features(i,1) max(curve); % 2. 平均功率 features(i,2) mean(curve); % 3. 功率标准差 features(i,3) std(curve); % 4. 日出时间(功率首次超过5%) features(i,4) hours(find(curve 0.05*features(i,1), 1)); % 5. 日落时间(功率最后超过5%) features(i,5) hours(find(curve 0.05*features(i,1), 1, last)); % 6. 不对称指数(上午/下午能量比) noon_idx find(hours 12, 1); features(i,6) sum(curve(1:noon_idx)) / sum(curve(noon_idx:end)); end3.2 形状特征提取除了统计特征我们还可以提取描述曲线形状的特征% 添加形状特征 shape_features zeros(num_samples, 3); for i 1:num_samples curve dataset(i,:); % 1. 峰值锐度(峰值附近斜率) [~, peak_idx] max(curve); left_slope (curve(peak_idx) - curve(max(1,peak_idx-5))) / 0.5; % 0.5小时间隔 right_slope (curve(peak_idx) - curve(min(length(curve),peak_idx5))) / 0.5; shape_features(i,1) (abs(left_slope) abs(right_slope))/2; % 2. 曲线峰度 shape_features(i,2) kurtosis(curve); % 3. 曲线偏度 shape_features(i,3) skewness(curve); end % 合并所有特征 all_features [features, shape_features];4. K-means聚类实现4.1 数据预处理% 特征标准化 normalized_features zscore(all_features); % 确定最佳聚类数 - 肘部法则 wcss zeros(1,10); % 假设测试1-10个聚类 for k 1:10 [~, ~, sumd] kmeans(normalized_features, k); wcss(k) sum(sumd); end % 绘制肘部曲线 figure; plot(1:10, wcss, bo-); xlabel(聚类数量); ylabel(WCSS(组内平方和)); title(肘部法则确定最佳聚类数);4.2 实施聚类% 根据肘部法则选择k3 k 3; [cluster_idx, centroids] kmeans(normalized_features, k); % 可视化聚类结果 colors [r, g, b, c, m, y]; figure; hold on; for i 1:k plot(hours, dataset(cluster_idxi,:), Color, [colors(i) 0.2]); plot(hours, mean(dataset(cluster_idxi,:)), Color, colors(i), LineWidth, 2); end xlabel(时间(小时)); ylabel(归一化功率); title(光伏曲线聚类结果); legend(类别1曲线,类别1均值,类别2曲线,类别2均值,类别3曲线,类别3均值);4.3 聚类结果分析% 分析每个聚类的特征 for i 1:k fprintf(\n类别%d特征分析:\n, i); cluster_data dataset(cluster_idxi,:); % 计算平均曲线 avg_curve mean(cluster_data); % 找出典型曲线(最接近中心点的曲线) [~, rep_idx] min(sum((normalized_features(cluster_idxi,:) - centroids(i,:)).^2, 2)); representative cluster_data(rep_idx,:); % 绘制典型曲线 figure; plot(hours, avg_curve, b-, LineWidth, 2); hold on; plot(hours, representative, r--, LineWidth, 1.5); title(sprintf(类别%d典型曲线, i)); xlabel(时间(小时)); ylabel(归一化功率); legend(平均曲线, 典型曲线); % 打印统计信息 fprintf(样本数量: %d\n, size(cluster_data,1)); fprintf(最大功率均值: %.2f\n, mean(features(cluster_idxi,1))); fprintf(日出时间均值: %.2f\n, mean(features(cluster_idxi,4))); fprintf(日落时间均值: %.2f\n, mean(features(cluster_idxi,5))); end5. 聚类应用与优化5.1 在功率预测中的应用光伏曲线聚类结果可直接用于改进功率预测模型分类建模为每个聚类建立独立的预测模型特征工程将聚类标签作为新特征加入预测模型模型集成对不同聚类采用不同的模型参数% 示例为每个聚类建立简单的预测模型 for i 1:k cluster_members find(cluster_idx i); fprintf(\n为类别%d建立预测模型...\n, i); % 这里可以使用更复杂的模型如神经网络 % 此处仅作示例使用线性回归 X normalized_features(cluster_idxi,[4,5,6]); % 使用日出、日落和不对称指数 y normalized_features(cluster_idxi,1); % 预测最大功率 % 训练线性回归模型 mdl fitlm(X, y); disp(mdl); end5.2 聚类算法比较除了K-means我们还可以尝试其他聚类算法% DBSCAN聚类 % 需要调整epsilon和minPts参数 epsilon 1.5; minPts 5; dbscan_idx dbscan(normalized_features, epsilon, minPts); % 层次聚类 distances pdist(normalized_features); linkage_tree linkage(distances, ward); dendrogram(linkage_tree); hierarchical_idx cluster(linkage_tree, maxclust, 3); % 高斯混合模型 gmm fitgmdist(normalized_features, 3); gmm_idx cluster(gmm, normalized_features); % 比较不同算法的结果 figure; subplot(2,2,1); scatter(normalized_features(:,1), normalized_features(:,2), 10, cluster_idx); title(K-means); subplot(2,2,2); scatter(normalized_features(:,1), normalized_features(:,2), 10, dbscan_idx); title(DBSCAN); subplot(2,2,3); scatter(normalized_features(:,1), normalized_features(:,2), 10, hierarchical_idx); title(层次聚类); subplot(2,2,4); scatter(normalized_features(:,1), normalized_features(:,2), 10, gmm_idx); title(GMM);5.3 实际应用中的注意事项数据标准化不同特征量纲差异大时必须进行标准化处理特征选择并非所有特征都有助于聚类可通过PCA降维或特征重要性分析噪声处理真实数据中异常值可能影响聚类效果需预先处理动态更新光伏系统特性可能随时间变化聚类模型需要定期更新% 特征重要性评估示例 % 使用随机森林评估特征重要性 tree TreeBagger(50, normalized_features, cluster_idx, Method, classification); [importance, indices] sort(tree.OOBPermutedPredictorDeltaError, descend); figure; bar(importance); set(gca, XTick, 1:size(normalized_features,2), XTickLabel, indices); title(特征重要性排序); xlabel(特征索引); ylabel(重要性得分);6. 进阶话题与扩展6.1 多天曲线聚类实际应用中我们可能需要分析多天的连续曲线% 生成多天数据 num_days 30; daily_curves zeros(num_days, length(hours)); % 模拟天气系统变化 weather_state 1; % 1晴天, 2多云, 3阴天 weather_duration 0; for day 1:num_days % 天气状态转换 if weather_duration 0 weather_state randi(3); weather_duration 1 randi(3); else weather_duration weather_duration - 1; end % 根据天气生成曲线 switch weather_state case 1 % 晴天 peak 0.9 0.2*rand(); width 3 rand(); noise 0.05; case 2 % 多云 peak 0.6 0.3*rand(); width 4 rand(); noise 0.1; % 添加随机云层效应 if rand() 0.5 cloud_start 8 4*rand(); cloud_duration 1 3*rand(); cloud_effect hours cloud_start hours (cloud_startcloud_duration); daily_curves(day, cloud_effect) daily_curves(day, cloud_effect) .* (0.3 0.4*rand()); end case 3 % 阴天 peak 0.3 0.3*rand(); width 5 rand(); noise 0.15; end % 生成基础曲线 daily_curves(day,:) peak * exp(-(hours-12).^2/(2*width^2)) noise*randn(size(hours)); daily_curves(day, daily_curves(day,:)0) 0; end % 多天曲线聚类需要考虑时间序列特性 % 可以使用动态时间规整(DTW)距离替代欧氏距离6.2 结合气象数据的聚类更精确的聚类可以结合气象数据% 模拟气象数据 temperature 15 10*rand(num_samples,1); % 温度(℃) humidity 30 50*rand(num_samples,1); % 湿度(%) cloud_cover rand(num_samples,1); % 云量(0-1) % 扩展特征矩阵 extended_features [all_features, temperature, humidity, cloud_cover]; % 标准化后重新聚类 normalized_extended zscore(extended_features); [extended_idx, extended_centroids] kmeans(normalized_extended, 3); % 分析气象特征对聚类的影响 figure; scatter3(temperature, humidity, cloud_cover, 20, extended_idx, filled); xlabel(温度); ylabel(湿度); zlabel(云量); title(气象特征空间中的聚类分布);6.3 实时聚类与更新对于实时应用可以考虑增量式聚类算法% 增量式K-means示例 % 初始化 current_centroids extended_centroids; new_data rand(5, size(extended_features,2)); % 模拟新数据 for i 1:size(new_data,1) % 计算新数据点到各中心的距离 distances sum((new_data(i,:) - current_centroids).^2, 2); [min_dist, closest] min(distances); % 更新中心点 n sum(extended_idx closest); % 原类别样本数 current_centroids(closest,:) (current_centroids(closest,:)*n new_data(i,:)) / (n1); fprintf(新数据点分配到类别%d中心已更新\n, closest); end7. 实用技巧与常见问题7.1 处理零值问题光伏曲线在夜间通常为零这会影响聚类效果% 方法1仅使用白天数据 daylight hours features(:,4) hours features(:,5); daylight_data dataset(:, daylight); % 方法2对零值进行特殊处理 % 例如将夜间功率设为NaN在计算距离时忽略 adjusted_data dataset; adjusted_data(hours features(:,4) | hours features(:,5)) NaN; % 自定义距离函数示例 function d custom_distance(x, y) valid ~isnan(x) ~isnan(y); d sqrt(sum((x(valid) - y(valid)).^2)); end7.2 评估聚类质量常用的聚类评估指标% 轮廓系数 silhouette_values silhouette(normalized_features, cluster_idx); figure; silhouette(normalized_features, cluster_idx); title(轮廓系数评估); % Davies-Bouldin指数 eva evalclusters(normalized_features, kmeans, DaviesBouldin, KList, 1:6); figure; plot(eva); title(Davies-Bouldin指数);7.3 处理不同容量的光伏系统当数据集包含不同容量的光伏系统时% 方法1按容量归一化 % capacities ...; % 各系统的容量 % normalized_by_capacity dataset ./ capacities; % 方法2使用形状特征而非绝对值 % 如使用日出日落时间、不对称指数等与容量无关的特征7.4 季节性变化处理光伏曲线随季节变化明显% 方法1按季节分别聚类 % seasons ...; % 每条曲线所属季节 % for season unique(seasons) % season_data dataset(seasonsseason, :); % % 对每个季节单独聚类 % end % 方法2将季节作为额外特征 % seasonal_features [all_features, season_indicator];在实际项目中我发现光伏曲线聚类效果很大程度上依赖于特征工程的质量。经过多次尝试以下特征组合通常效果较好归一化的日出/日落时间最大功率与平均功率的比值上午与下午的能量比曲线峰度和偏度峰值附近的平均斜率另一个实用技巧是先用PCA降维可视化数据观察其自然分布再决定使用何种聚类算法和参数。对于有明显时间序列特性的数据动态时间规整(DTW)距离通常比欧氏距离更合适。