ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

光伏功率预测机器学习实战:Python源码包与特征工程全流程解析

光伏功率预测机器学习实战:Python源码包与特征工程全流程解析 简介这是一份面向计算机相关专业学生与项目实战学习者的光伏功率预测完整项目包基于Python与机器学习实现可作为毕业设计、课程设计或期末大作业的高分参考方案。资源共16个文件以8个csv训练与测试数据集、4个py源码脚本为主另含1个ipynb实验笔记、1个md说明文档、1个docx任务说明及gitignore配置压缩包约4.64MB目录结构清晰涵盖数据加载、数据处理、模型训练与预测等完整流程模块。项目经导师指导并认可评审分99分代码完整可运行对新手友好。读者可据此掌握光伏功率预测的建模思路、数据划分方式与训练预测脚本组织方法并借助任务说明与实验笔记快速理解各模块职责完成从数据到结果的复现与二次开发。目前已有56人学习下载适合需要完整项目案例与排错参考的学习者。1. 光伏功率预测项目拆包一份能跑通的机器学习实战资源光伏电站最怕的不是阴天而是功率预测偏差过大导致并网调度被罚。我手上这份 Python 基于机器学习的光伏功率预测源码包就是冲着这个痛点去的——它把 2018 年某直流光伏电站的实测数据、特征工程脚本、训练预测流程和 Notebook 演示全部打包在一起解压后直接能看到main.py、Train_Predict.py、Data_Process.py三个核心文件外加DC_Data目录下 4 组 train/test 的 CSV 对。适合正在做机器学习课程设计、毕业设计或者想拿真实光伏数据练一遍完整回归流程的人。它不是玩具数据集时间粒度和功率量纲都是电站真实采集口径跑通一遍对理解「气象特征→功率映射」这件事帮助很大。2. 数据管线拆解从 DC_Data 到模型输入的四步处理2.1 先看清 DC_Data 里到底有什么解压后DC_Data目录下是 4 组配对文件train_1.csv/test_1.csv一直到train_4.csv/test_4.csv。这种按编号分组的方式常见做法是不同季节或不同月份切分避免用未来数据预测过去。每组 CSV 的列结构一致通常包含时间戳、辐照度、温度、湿度、风速、历史功率等字段。Task_Info.docx里应该写了字段含义和任务要求动手前先翻一遍比盲目读代码快得多。我一般会先跑一段探查脚本确认列名、缺失率、时间跨度再决定后续处理策略import pandas as pd for i in range(1, 5): train pd.read_csv(fDC_Data/train_{i}.csv) test pd.read_csv(fDC_Data/test_{i}.csv) print(f--- 第{i}组 ---) print(train shape:, train.shape, | test shape:, test.shape) print(train 缺失率:\n, train.isnull().mean().round(4)) print(train 时间范围:, train.iloc[0, 0], →, train.iloc[-1, 0])这段代码做三件事打印每组数据的行列数确认 train/test 比例是否合理统计每列缺失率缺失超过 30% 的列要考虑丢弃或插补查看时间范围判断是否存在时间断层。参数上range(1, 5)对应 4 组数据如果你的包只有 3 组就改成range(1, 4)。跑完这一步心里对数据质量就有底了。2.2 Data_Process.py 里的特征工程逻辑Data_Process.py是整个管线的入口负责把原始 CSV 转成模型能吃的特征矩阵。光伏功率预测的特征工程有几个固定动作时间特征拆解小时、月份、辐照度与功率的物理关系构造、滑动窗口统计量。这个脚本大概率做了以下几类处理时间戳解析与周期性编码把「小时」转成 sin/cos 两列避免 23 点和 0 点在数值上距离过远对辐照度做归一化或标准化因为它的量级和温度、湿度差很多构造滞后特征比如前一时刻的功率作为当前时刻的输入处理夜间功率为 0 的样本这部分数据对模型训练是噪声如果你要改特征重点看这个文件里fit_transform和transform的调用顺序。常见翻车点是先对全量数据做了标准化再切 train/test导致测试集信息泄漏。正确做法是只在 train 上 fit然后 transform test。2.3 Load_Save_Data.py 的读写封装Load_Save_Data.py是个工具模块封装了数据加载和模型保存。它的存在意义是让Train_Predict.py不用重复写pd.read_csv和joblib.dump。我一般会检查两个地方一是保存模型时有没有同时存下标准化参数否则预测时输入尺度对不上二是加载函数有没有做列顺序校验CSV 列顺序变了但代码按位置取值结果会静默出错。import joblib from sklearn.preprocessing import StandardScaler # 保存时把 scaler 和模型一起打包 joblib.dump({model: model, scaler: scaler}, pv_model.pkl) # 加载时解包保证预测管线一致 bundle joblib.load(pv_model.pkl) model, scaler bundle[model], bundle[scaler]这种打包保存的方式比单独存模型文件稳妥预测阶段不会因为忘了标准化而得到离谱结果。参数上pv_model.pkl是输出文件名你可以按日期或版本改名方便回溯。2.4 训练集与测试集的切分边界4 组 train/test 已经预先切好但你要理解它的切分逻辑。光伏数据是时间序列不能随机打乱切分否则用中午的数据预测早晨指标会虚高。这组数据按编号分组大概率是按时段顺序切的。如果你要自己重新切用train_test_split时务必设shuffleFalse或者直接按时间索引切片。提示拿到任何时间序列数据先画一条功率随时间变化的曲线肉眼确认 train 和 test 的时间段不重叠比看代码更可靠。3. 模型训练与预测Train_Predict.py 的实操路径3.1 main.py 与 Train_Predict.py 的分工main.py是总调度入口通常只做参数配置和函数调用不写具体逻辑。Train_Predict.py才是核心里面定义了模型类、训练循环、评估指标。我拆这类项目的习惯是先读main.py看清它调了哪些函数、传了什么参数再顺着调用链进Train_Predict.py。这样比从头读代码快也不会漏掉关键配置。main.py里一般会有数据路径、模型类型、学习率、迭代次数这些参数。如果你想换模型改这里比改Train_Predict.py更安全因为训练逻辑是通用的换模型只需要替换模型类。3.2 模型选型为什么是机器学习而不是深度学习这个项目定位是机器学习大概率用了随机森林、梯度提升树如 XGBoost/LightGBM或支持向量回归。光伏功率预测在中小规模数据上树模型往往比深度学习更稳原因是特征维度不高气象时间约 10-20 维样本量有限几千到几万条树模型对缺失值和异常值更鲁棒调参成本也低。如果你要换成 LSTM 或 Transformer不是不行但需要更多数据做支撑而且训练时间会成倍增加。对于课程设计或毕业设计场景树模型能在保证精度的同时让代码可读性更好答辩时也容易解释清楚。from sklearn.ensemble import RandomForestRegressor from sklearn.metrics import mean_absolute_error, r2_score rf RandomForestRegressor( n_estimators200, # 树的数量越多越稳但越慢 max_depth12, # 限制深度防过拟合 min_samples_leaf5, # 叶子最小样本数控制噪声 random_state42 ) rf.fit(X_train, y_train) pred rf.predict(X_test) print(MAE:, mean_absolute_error(y_test, pred)) print(R2:, r2_score(y_test, pred))n_estimators从 100 起步到 300 左右收益递减max_depth不设限制容易过拟合光伏数据我一般从 8-15 之间试min_samples_leaf设 3-10 能平滑预测曲线。评估指标里 MAE 看平均偏差R2 看拟合优度两个一起看才全面。3.3 训练过程中的参数调整与日志观察训练时重点盯 loss 曲线和验证集指标。如果训练集 MAE 持续下降但验证集 MAE 反弹就是过拟合该降max_depth或加min_samples_leaf。如果两者都高是欠拟合加树的数量或换更复杂的模型。Train_Predict.py里如果有早停逻辑确认early_stopping_rounds设了多少。树模型用早停能省不少时间但要注意早停的验证集不能和最终测试集是同一份否则测试指标会偏乐观。3.4 预测结果的反归一化与输出模型训练时如果对目标列做了归一化预测完必须反归一化才能得到真实功率值。这一步在Train_Predict.py末尾通常有但容易被忽略。检查方法是看预测输出的数值范围是否和原始功率量纲一致。如果预测值都在 0-1 之间而实际功率是 0-1000 kW那就是忘了反归一化。# 假设训练时对 y 做了 MinMax 归一化 pred_real pred_scaled * (y_max - y_min) y_min # 输出结果到 CSV方便后续分析 result pd.DataFrame({真实功率: y_test, 预测功率: pred_real}) result.to_csv(predict_result.csv, indexFalse)反归一化的参数y_max和y_min必须来自训练集不能用测试集的极值否则又是信息泄漏。输出 CSV 时保留真实值和预测值两列画对比图或算误差都方便。4. 避坑与排查跑通这份源码的五个血泪经验4.1 现象运行 main.py 报 FileNotFoundError原因代码里的数据路径是相对路径但你的工作目录不在项目根目录。常见于用 VSCode 直接打开子文件夹或者终端 cd 到了错误位置。解决在main.py开头加import os; os.chdir(os.path.dirname(os.path.abspath(__file__)))强制把工作目录切到脚本所在目录。或者手动确认终端路径用pwdLinux/Mac或cdWindows检查。4.2 现象训练集 R2 很高但测试集 R2 为负原因典型过拟合或者特征里混入了未来信息。光伏数据里最常见的泄漏是用了当天全天的统计量去预测当天某个时刻的功率。解决检查Data_Process.py里有没有用df.mean()或df.max()对全量数据做统计再拼回特征。改成只用训练集统计量或者改用滚动窗口统计。同时降低模型复杂度max_depth砍到 8 以下试试。4.3 现象预测曲线在夜间出现负值原因模型是纯数据驱动的没有加物理约束。夜间功率应该为 0但回归模型可能输出 -5 或 -10。解决在预测后加一个clip操作把负值截断为 0pred np.clip(pred, 0, None)。更严谨的做法是在训练时给夜间样本更高权重或者单独训练一个白天/夜间分类器。4.4 现象换了组数据后列名对不上代码报 KeyError原因4 组 CSV 的列名可能有细微差异比如Power和power、Irradiance和Radiation。代码里硬编码了列名换组就崩。解决在Load_Save_Data.py里加一层列名标准化统一转小写并去空格。或者先跑一遍print(df.columns.tolist())把实际列名抄进代码。4.5 现象Notebook 里能跑命令行跑 main.py 报错原因Notebook 的变量是全局的前面单元格定义的变量后面直接用了。main.py是独立脚本缺少中间变量定义。解决把 Notebook 里的逻辑按函数封装确保每个函数只依赖传入参数不依赖全局变量。DC_PV_Power_Predict_2018.ipynb适合用来理解流程但最终交付应该以main.py为准。5. 从跑通到跑好三个让结果更可信的进阶技巧5.1 用时间序列交叉验证替代单次切分单次 train/test 切分的结果波动很大换一组数据指标可能差很多。更稳的做法是滚动交叉验证每次用前 N 天训练预测第 N1 天然后窗口后移。这样能看出模型在不同时间段的稳定性。from sklearn.model_selection import TimeSeriesSplit tscv TimeSeriesSplit(n_splits5) scores [] for train_idx, val_idx in tscv.split(X): X_tr, X_val X[train_idx], X[val_idx] y_tr, y_val y[train_idx], y[val_idx] model.fit(X_tr, y_tr) scores.append(r2_score(y_val, model.predict(X_val))) print(各折 R2:, scores, | 均值:, sum(scores)/len(scores))n_splits5表示切 5 折每折的训练集都比上一折大。光伏数据有季节性5 折能覆盖不同天气模式。如果各折 R2 方差很大说明模型对某些天气类型预测能力弱需要针对性补特征。5.2 特征重要性分析知道模型在看什么树模型自带feature_importances_跑完训练后打印出来能看出哪些特征贡献大。如果辐照度的重要性排第一符合物理直觉如果某个时间戳列排第一可能是数据泄漏。import matplotlib.pyplot as plt importances rf.feature_importances_ feat_names X_train.columns idx importances.argsort()[::-1] plt.barh(range(len(idx)), importances[idx]) plt.yticks(range(len(idx)), [feat_names[i] for i in idx]) plt.xlabel(Importance) plt.tight_layout() plt.savefig(feature_importance.png, dpi150)这张图放进论文或答辩 PPT 里比单纯报 R2 更有说服力。如果发现某个特征重要性异常高但物理上说不通回去查它的构造逻辑。5.3 误差分时段分析找出模型的盲区整体 MAE 达标不代表每个时段都准。把测试集按小时分组算每个小时的平均绝对误差能看出模型在早晨爬坡和傍晚下降阶段是不是偏差更大。test_df[hour] pd.to_datetime(test_df[时间列]).dt.hour test_df[abs_err] abs(test_df[真实功率] - test_df[预测功率]) hourly_err test_df.groupby(hour)[abs_err].mean() print(hourly_err)如果早晨 6-8 点的误差明显高于中午说明模型对功率爬坡阶段的动态特性捕捉不够。改进方向是加滞后特征或改用能建模时序依赖的模型。我每次做完预测都会跑一遍分时段误差这个习惯帮我发现过好几次特征工程的盲区。希望这份拆解能帮你少走弯路顺利跑通自己的光伏功率预测流程。本文还有配套的精品资源点击获取
返回列表