光伏功率预测机器学习完整实现:数据处理、特征工程到模型评估
简介面向毕业设计、课程设计与期末大作业场景这份Python光伏功率预测项目提供了基于机器学习的完整可运行代码并配有训练集与测试集。项目注释清晰即便是机器学习新手也能较快理解数据加载、处理、训练与预测等环节简单部署即可直接使用。资源包共16个文件、4.64MB包含8个CSV数据文件、4个Python脚本以及Jupyter Notebook、说明文档与任务书等辅助材料便于对照阅读和二次开发。目前已有316人学习浏览适合作为毕业设计或课程作业的参考。实际交付内容涵盖数据加载保存、数据预处理、模型训练与预测等核心模块并保留README与任务文档可帮助用户快速还原项目思路便于在毕业设计或课程作业中借鉴和扩展。1. 用机器学习做光伏功率预测这套源码为什么值得你下载如果你正在做新能源方向的毕业设计或课程设计大概率会遇到一个绕不开的题目光伏功率预测。电网调度要看它电站收益要看它论文加分也要看它。我自己接过几个类似的模拟项目X最头疼的不是模型选型而是从零开始整理数据、写预处理、调训练流程一套下来少说两周。所以当我看到这份DC_PV_Power_Predict_2018-master源码包时第一反应是终于有人把完整链路打包好了。这套资源包含完整的 Python 源码、训练数据和测试数据核心文件是main.py入口脚本、Data_Process.py数据预处理、Train_Predict.py训练与预测以及一个DC_PV_Power_Predict_2018.ipynb的 Notebook 交互版本。它解决的是“从 CSV 原始数据到功率预测结果”的完整闭环适合正在做毕业设计、期末大作业、课程设计的学生也适合想快速上手机器学习回归流程的从业者——你不用从环境搭建开始踩坑拿到手跑通再改参数做自己的实验即可。值得强调的是这份代码带有注释结构清晰不是那种跑起来一堆报错的半成品。我的建议是先按默认参数跑一遍再读代码理解每一步在干什么最后下手改数据路径和模型参数。2. 拆解数据链路四组训练集与测试集的设计逻辑2.1 CSV 文件命名背后的数据划分思路打开压缩包DC_Data文件夹下躺着 8 个 CSV 文件train_1.csv到train_4.csvtest_1.csv到test_4.csv。初次看可能觉得命名随意但仔细想这是非常典型的按时间段切分的数据集划分方式。每组 train 和 test 对应一个时间窗口比如用前几天的数据训练预测后一天或后几小时的功率输出。这种划分方式在光伏预测里很常见。光伏功率受天气影响大不同季节、不同云量条件下数据分布差异明显。如果只做一组训练测试切分模型的评估结果会很碰运气分成四组交叉验证式地跑能更客观地判断模型的稳定性。我在做类似项目时一般会查看每组的日期范围和统计特征import pandas as pd for i in range(1, 5): train_path fDC_Data/train_{i}.csv test_path fDC_Data/test_{i}.csv df_train pd.read_csv(train_path) df_test pd.read_csv(test_path) print(f第 {i} 组训练集 {df_train.shape[0]} 行测试集 {df_test.shape[0]} 行) print(f训练集时间范围{df_train[time].min()} 到 {df_train[time].max()}) print(f测试集时间范围{df_test[time].min()} 到 {df_test[time].max()})这段代码的作用是先摸清数据底细。输出结果会告诉你每组数据的时间覆盖范围。逻辑说明通过pd.read_csv读取训练与测试文件shape[0]获取行数min()和max()查看时间字段边界目的是确认四组数据是否存在时间重叠或顺序倒置。参数说明time字段名需要根据实际 CSV 列名调整有些文件的列名可能是date或timestamp。如果列名不对会报 KeyError这时候用df_train.columns先打印所有列名。2.2 数据预处理脚本的输入输出约定Data_Process.py是这套代码里承上启下的模块。它负责把原始 CSV 转成模型能直接吃的特征矩阵。光伏预测的特征工程有几个固定套路历史功率滞后值lag features、时间特征小时、星期几、月份、天气相关特征辐照度、温度、湿度。这套代码的预处理逻辑大概率围绕这几个维度展开。一个标准的处理流程是读取 CSV → 解析时间列 → 生成时间特征 → 构建滞后特征 → 处理缺失值 → 标准化/归一化 → 输出训练矩阵。其中滞后特征是光伏预测的关键——当前时刻的功率与过去 1 小时、 2 小时、 24 小时前的功率高度相关把这些历史值作为特征模型才能学到时间序列的动态规律。# Data_Process.py 核心片段逻辑示意 def build_features(df, lag_hours[1, 2, 3, 24]): df df.sort_values(time) for lag in lag_hours: df[flag_{lag}h] df[power].shift(lag) df[hour] df[time].dt.hour df[month] df[time].dt.month df df.dropna() return df这段函数示意代码展示了滞后特征和时间特征的构建方式。sort_values(time)先按时间排序保证时序正确shift(lag)取前 N 小时的功率值作为新特征dt.hour和dt.month提取时间分量dropna()删掉因滞后产生的空行。参数说明lag_hours列表决定了用哪些历史时间点做特征可调大或调小。光伏场景下 1 小时、 3 小时、 24 小时是比较常用的滞后窗口短了模型看不到周期性长了引入噪声。power是功率列名需要匹配实际数据。2.3 为什么预处理直接决定预测上限很多新手把精力全放在调模型上忽略了预处理。但实际上在光伏功率预测这个场景数据质量对结果的影响往往大于模型选择。同一份数据特征工程做好了线性回归也能出不错的分数特征没做好换成深度网络也白搭。这套代码在预处理上做了基本的规范化处理。运行前我建议检查两点一是数据里有没有明显的异常值比如辐照度超过物理上限二是功率列是否有负值或空值。如果发现这些问题需要在Data_Process.py里加上清洗逻辑否则模型会被个别极端值带偏。# 异常值清洗示例功率不可能为负 df df[df[power] 0] # 辐照度超过 1200 W/m² 的视为传感器异常 df df[df[irradiance] 1200]这段清洗代码的逻辑是过滤掉功率为负的异常记录再过滤掉辐照度超过物理上限的记录。光伏板的辐照度上限一般在 1000 到 1200 W/㎡ 之间。参数说明阈值可以根据实际电站位置调整高海拔地区辐照度可能更高但超过 1200 基本可以判定为数据采集异常。3. 训练与预测从 Train_Predict.py 到 main.py 的执行流程3.1 模型选择与训练入口Train_Predict.py是核心训练脚本。光伏功率预测常用的机器学习模型包括随机森林、梯度提升树如 XGBoost、LightGBM、支持向量回归SVR和 BP 神经网络。这套代码在设计上保留了切换模型的灵活性常见做法是在脚本里定义多个模型的训练函数通过配置参数选择使用哪一个。在训练之前数据需要从 DataFrame 转为 NumPy 矩阵再传入模型。特征列和目标列需要严格对齐。我一般会在训练前打印数据的形状确认X_train和y_train的维度匹配这个习惯能省掉很多莫名其妙的报错。# Train_Predict.py 训练流程示意 from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score X_train train_df.drop(power, axis1).values y_train train_df[power].values X_test test_df.drop(power, axis1).values y_test test_df[power].values model RandomForestRegressor( n_estimators300, max_depth15, random_state42 ) model.fit(X_train, y_train) y_pred model.predict(X_test) print(fMAE: {mean_absolute_error(y_test, y_pred):.3f}) print(fRMSE: {mean_squared_error(y_test, y_pred, squaredFalse):.3f}) print(fR2: {r2_score(y_test, y_pred):.3f})这段代码展示了训练和评估的标准流程。drop(power, axis1)去掉目标列.values转成 NumPy 数组随机森林的n_estimators300是树的数量max_depth15限制单棵树的深度防止过拟合random_state42固定随机种子保证实验可复现。参数说明n_estimators越大模型越稳但训练越慢max_depth过大容易过拟合过小则欠拟合。评估指标中 MAE 看平均误差绝对值RMSE 放大大误差的权重R2 最直观越接近 1 越好。光伏预测场景 R2 在 0.85 以上算不错的基线。3.2 main.py 如何串联全流程main.py是整套代码的调度中心。它的作用是把数据读取、预处理、训练、评估这几个模块按顺序串起来。按我的经验这种入口文件的设计要点是支持命令行参数传入让不同场景的切换不用改代码——通过--data_dir指定数据路径通过--model指定模型类型通过--group指定跑哪一组训练测试数据。python main.py --data_dir DC_Data --model rf --group 1这条命令的含义是使用DC_Data目录下的数据选择rf随机森林模型跑第一组训练测试。参数说明--model可选值取决于Train_Predict.py里注册了哪些模型常见的有rf随机森林、gbdt梯度提升、svr支持向量回归--group决定读取train_1.csv还是其他组。这种命令行模式的优点是不用打开 IDE 改代码跑完一组接着跑下一组。在main.py的内部实现上通常会先解析参数然后用Data_Process里的函数加载数据再调用Train_Predict里的训练函数最后把评估结果输出。提示如果命令行执行时提示找不到模块检查是不是没有在项目根目录下运行或者需要先在main.py里加上sys.path.append(os.getcwd())。3.3 Jupyter Notebook 版本的适用场景压缩包里还有一个.ipynb文件这对课程设计来说非常友好。Notebook 的优势在于可以按单元格一步步执行中间结果可视化直观数据分布、特征相关性、预测曲线都能直接画出来。如果你的导师要求交报告或答辩演示用 Notebook 跑一遍截图放进文档里比贴黑乎乎的终端输出要漂亮得多。Notebook 和main.py干的是同一件事只是交互形式不同。我会建议平时调试和分析数据在 Notebook 里做最后批量跑实验结果用命令行脚本做。两者配合效率最高。4. 评估指标与可视化怎么证明你的模型真的有效4.1 三个核心回归指标怎么解读光伏功率预测本质是时间序列回归问题评估指标就是回归问题的那一套。但在实际答辩和写报告时不能光贴数字你得能解释每个指标在这个场景里的物理含义。R2决定系数反映模型对功率波动的解释能力。0.9 意味着模型能解释 90% 的功率变化剩余 10% 是模型看不到的随机因素——云层突变、传感器噪声等。RMSE均方根误差因为对误差做了平方所以对大偏差的惩罚更重而光伏功率预测最怕的就是大偏差——直接等于多报或少报了一台逆变器的出力。MAE比较直观就是平均差了多少钱千瓦。这三个指标要一起看。如果 MAE 很小但 RMSE 很大说明大部分预测很准但有少数点偏差大得离谱这是典型的个别异常值拉高的现象。4.2 误差分布的可视化分析模型不只要跑出指标还要能直观地看到预测效果。最常见的可视化是画出测试集的真实功率曲线和预测功率曲线的对比图以及在散点图上以真实值为横轴、预测值为纵轴描点点越靠近 45 度对角线说明效果越好。import matplotlib.pyplot as plt plt.figure(figsize(12, 5)) plt.plot(y_test, label实际功率, alpha0.7) plt.plot(y_pred, label预测功率, alpha0.7) plt.legend() plt.xlabel(时间点) plt.ylabel(功率 (kW)) plt.title(测试集预测对比) plt.show() plt.figure(figsize(6, 6)) plt.scatter(y_test, y_pred, s10, alpha0.5) plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], r--) plt.xlabel(实际功率) plt.ylabel(预测功率) plt.show()这段代码生成两张核心图时间序列对比图和散点图。逻辑说明第一张图用于直观判断预测曲线是否跟随真实曲线的大趋势第二张图用于判断是否存在系统性偏差——如果点整体偏上说明模型系统性高估偏下则是低估。参数说明alpha0.7和alpha0.5设置透明度数据点密集时适当降低透明度能更清楚看到分布密度。s10是散点大小。如果样本量很大可以间隔采样画图避免图形糊成一团。5. 避坑指南跑这套代码最常见的五个翻车现场5.1 现象FileNotFoundError文件路径报错原因直接双击运行脚本或从 IDE 默认目录启动工作路径不在项目根目录下相对路径DC_Data/train_1.csv找不着文件。解决统一在项目根目录下打开终端运行python main.py。或者在代码开头加上路径锚定import os os.chdir(os.path.dirname(os.path.abspath(__file__)))这段话做了两件事获取当前脚本所在目录的绝对路径然后把工作目录切换过去。这样不管从哪里启动脚本都能以项目根目录为基准定位 DC_Data 文件夹。5.2 现象时间列解析报错或时区偏移原因CSV 里的时间列是字符串格式可能包含T或时区信息直接pd.to_datetime有时会产生NaT后续构建小时特征时全部变成空值。解决读取时显式指定解析格式并做有效性校验df[time] pd.to_datetime(df[time], format%Y-%m-%d %H:%M:%S) df df.dropna(subset[time])参数说明format要严格匹配实际文件里的时间字符串格式否则会报错或解析失败。dropna(subset[time])删除解析失败的行避免脏数据污染下游。5.3 现象滞后特征导致大量 NaN训练集行数骤减原因用shift(24)生成滞后 24 小时特征时前 24 行数据没有历史值可填被dropna()删掉了。如果数据集本身不大删掉 24 行可能是可观的损失。解决对滞后特征列用前向填充而不是直接删除df[lag_24h] df[power].shift(24).fillna(methodbfill)bfill是用后续的有效值反向填充缺失的滞后特征。参数说明在时间序列里bfill会引入未来信息严格来说属于数据泄漏如果追求学术严谨性更推荐减小滞后窗口或直接删除首段数据。5.4 现象模型训练完预测结果全部是常数或接近均值原因特征顺序在训练和预测阶段不一致或者特征列没有全部传入测试集。模型实际只学到了一个偏置项输出自然接近均值。解决在训练前固定特征列的顺序列表训练和预测都按这个顺序取特征feature_cols [col for col in train_df.columns if col ! power] X_train train_df[feature_cols].values X_test test_df[feature_cols].values这样做能保证特征对齐。参数说明feature_cols通过排除目标列生成避免手动拼列表出错如果测试集缺少某个特征列执行时会直接报错而不是静默出错。5.5 现象训练集和测试集数据分布差异巨大指标虚高或虚低原因光伏数据有强周期性某组数据的天气条件极端训练集和测试集恰好落在不同天气类型上。解决不要只看一组的指标把四组训练测试全部跑一遍看指标均值和方差。如果方差很大说明模型稳定性欠佳需要加入更多的天气特征或使用集成模型来平滑波动。注意在课程设计答辩中导师最爱问的问题就是“你如何证明模型的泛化能力”。把四组结果都摆出来比只挑最好的一组讲要有说服力得多。6. 进阶改造成多模型对比与网格搜索的实用技巧当你用默认参数跑通了整套流程课程设计的基础分已经拿到。但如果想让分数再上一个台阶最有效的操作是把单模型改成多模型对比并加上网格搜索找最优超参数。这不是加分项几乎是拿高分和拿普通分的分水岭。具体做法是写一个run_experiment.py把随机森林、梯度提升、SVR 统一封装成可对比的实验流程。每种模型在四组数据上都跑一遍输出指标到表格最后画一个指标对比条形图。这样导师一眼就能看出你做了系统性实验而不仅仅是调了一个脚本。from sklearn.ensemble import RandomForestRegressor from sklearn.ensemble import GradientBoostingRegressor from sklearn.svm import SVR from sklearn.model_selection import GridSearchCV models { 随机森林: RandomForestRegressor(random_state42), 梯度提升: GradientBoostingRegressor(random_state42), SVR: SVR() } param_grids { 随机森林: {n_estimators: [100, 300], max_depth: [10, 15]}, 梯度提升: {learning_rate: [0.05, 0.1], max_depth: [3, 5]}, SVR: {C: [0.1, 1, 10], epsilon: [0.01, 0.1]} } for name, model in models.items(): gs GridSearchCV(model, param_grids[name], cv3, scoringneg_mean_squared_error) gs.fit(X_train, y_train) print(f{name} 最优参数: {gs.best_params_}, 最优分数: {gs.best_score_:.4f})这段代码演示了多模型网格搜索的标准写法。GridSearchCV会在参数网格里穷举组合用 3 折交叉验证评估每组参数的效果。scoringneg_mean_squared_error因为交叉验证框架默认更高分更好MSE 越小越好所以取负值。参数说明cv3是交叉验证折数数据量大可以增加到 5。SVR 的C是正则化参数越大越容易过拟合epsilon是误差管道的宽度越小要求越严格。网格搜索跑完你手里就握有每个模型的最优参数和性能对比。在四组数据集上做完整对比实验之后我还习惯加一个维度用测试集前几个小时的功率作为特征预测未来 1 小时、 3 小时、 6 小时的功率评估预测时效对误差的影响。这个分析在答辩时非常能展示你对问题的理解深度。资源包里已经搭好了编码、训练、预测的完整骨架在这个基础上做扩展思路是清晰的你的心思可以全花在自己的实验设计上。说实话我第一次拿到这套代码时也有一种“怎么不早点遇到”的感觉。从那以后我每次做新能源预测类的课程任务都强制自己走一遍“查看数据分布 → 构建滞后特征 → 多模型对比 → 四组交叉评估”的流程踩坑少了拿分也稳了。希望帮到你。本文还有配套的精品资源点击获取