LSTM模型实现光伏发电功率的预测

news2024/11/17 5:20:22

关于深度实战社区

我们是一个深度学习领域的独立工作室。团队成员有:中科大硕士、纽约大学硕士、浙江大学硕士、华东理工博士等,曾在腾讯、百度、德勤等担任算法工程师/产品经理。全网20多万+粉丝,拥有2篇国家级人工智能发明专利。

社区特色:深度实战算法创新

获取全部完整项目数据集、代码、视频教程,请进入官网:zzgcz.com。竞赛/论文/毕设项目辅导答疑,v:zzgcz_com


1. 项目简介

本项目旨在通过构建一个基于LSTM(长短期记忆网络)的深度学习模型来预测某个站点的光伏发电功率。背景数据包括站点的风速、温度、湿度、辐射强度等气象因素,以及电力传递的历史数据。通过对这些时间序列特征的学习,模型能够在给定时间窗口内对目标变量“有效功率(kW)”进行精确预测。

本项目主要分为以下几个部分:首先对数据进行预处理和特征工程,包括填补缺失值、标准化处理和序列数据构建。然后,设计一个自定义的Dataset类,并使用PyTorch的DataLoader模块实现数据加载。模型方面,选用了具有多层LSTM结构的模型架构,配合全连接层来捕捉复杂的时间序列关系。通过PyTorch的Adam优化器对均方误差(MSE)损失函数进行最小化,并使用交叉验证来评估模型的表现。在训练过程中,对模型参数进行优化,最后通过测试集对模型进行验证,并绘制预测结果与实际值的对比图。此项目适用于预测时间序列数据中的连续值,并能够为未来的光伏发电预测或其他类似场景提供借鉴。

在这里插入图片描述

2.技术创新点摘要

  1. 数据预处理策略创新:代码中使用了多种数据预处理方法,例如对原始数据进行缺失值填补、数据标准化及序列数据构造。在处理缺失值时,模型区分了不同列的处理方式:部分特征列采用零填充,而其他列使用最近邻插值法来填补缺失数据。此方法充分考虑了各列特征的实际含义和数据分布特征,保证了数据完整性和模型的学习效果。同时,针对时间序列数据特性,采用滑动窗口的方法生成特征序列(SEQ_LENGTH = 24),即利用过去24小时的特征数据来预测未来的有效功率。这种序列数据生成策略能够更好地捕捉时间序列数据中的周期性与趋势性,为模型提供更具时效性的输入。
  2. 模型设计上的改进:本项目采用了多层LSTM(Long Short-Term Memory)网络结构,结合全连接层来构建预测模型。LSTM能够有效捕捉长时间序列中的依赖关系,同时通过多层堆叠提升模型的表达能力。模型中的LSTM层设置了2层结构,并且利用了隐藏层维度(hidden_size=64)来增强模型对时间序列模式的记忆与捕捉能力。这种设置能够更好地学习复杂时间序列数据的特征,使模型在应对长时间依赖性时具有更好的性能。
  3. 多元时间序列特征融合:项目引入了多种气象因素和电力相关特征,包含了风速、温度、湿度、辐射强度等,并且在输入层采用了标准化方法,以减小不同特征量纲之间的影响。这种多元特征的结合能够帮助模型更全面地理解影响光伏发电功率的多种因素,从而提升预测精度。
  4. 自定义数据集与优化训练流程:代码中自定义了数据集(PowerDataset类)以及使用PyTorch的DataLoader模块进行批量数据加载,实现了模型的高效训练与验证。此外,模型采用了Adam优化器,并在每轮训练后进行了验证集评估,以实现最佳模型参数的选择,从而提升整体模型的收敛效果与泛化能力。

3. 数据集与预处理

  1. 数据清洗与缺失值处理:针对原始数据中的缺失值,项目采取了不同的填补策略。对于某些关键特征(如“有效功率”和“降雨量”),采用零填充方式,以表示特征值为0的情况。而其他特征(如风速、温度等)则使用最近邻插值法进行填补。这种方法能够保证数据完整性,并减少由于缺失值带来的模型性能波动。
  2. 时间序列特征处理:在预处理阶段,模型使用滑动窗口法构建了特征序列(长度为24),即每次利用过去24小时的特征数据作为模型输入,用来预测下一时间步的发电功率。这种处理方式能够帮助模型捕捉时间序列数据中的趋势、周期性以及复杂依赖关系。
  3. 特征选择与标准化:项目通过筛选,选定了多种气象特征(例如风速、湿度、辐射量等)及电力相关特征作为输入变量,排除了无关或重复的特征。在特征标准化方面,采用StandardScaler对所有特征进行标准化处理,将其转换为均值为0、标准差为1的标准正态分布。这一操作能够平衡各特征的量纲差异,有助于提升模型的收敛速度和稳定性。

4. 模型架构

模型结构:
  • 输入层:输入特征的维度为 input_size = 9(表示9个气象及电力特征)。输入张量形状为 [BatchSize,Seq_Length,Input_Size],其中 Seq_Length = 24 代表时间序列的长度。
  • LSTM层:模型包含两层LSTM层(num_layers = 2),每层的隐藏单元数量为 hidden_size = 64。每个时间步输入一个特征向量 xt,其内部运算逻辑为:
  • { f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) (遗忘门) i t = σ ( W i ⋅ [ h t − 1 , x t ] + b i ) (输入门) C ~ t = tanh ⁡ ( W c ⋅ [ h t − 1 , x t ] + b c ) (候选记忆单元) C t = f t ⋅ C t − 1 + i t ⋅ C ~ t (记忆单元更新) o t = σ ( W o ⋅ [ h t − 1 , x t ] + b o ) (输出门) h t = o t ⋅ tanh ⁡ ( C t ) (当前隐藏状态) \begin{cases} f_t = \sigma(W_f \cdot [h_{t-1}, x_t] + b_f) \quad \text{(遗忘门)} \\ i_t = \sigma(W_i \cdot [h_{t-1}, x_t] + b_i) \quad \text{(输入门)} \\ \tilde{C}_t = \tanh(W_c \cdot [h_{t-1}, x_t] + b_c) \quad \text{(候选记忆单元)} \\ C_t = f_t \cdot C_{t-1} + i_t \cdot \tilde{C}_t \quad \text{(记忆单元更新)} \\ o_t = \sigma(W_o \cdot [h_{t-1}, x_t] + b_o) \quad \text{(输出门)} \\ h_t = o_t \cdot \tanh(C_t) \quad \text{(当前隐藏状态)} \end{cases} ft=σ(Wf[ht1,xt]+bf)(遗忘门)it=σ(Wi[ht1,xt]+bi)(输入门)C~t=tanh(Wc[ht1,xt]+bc)(候选记忆单元)Ct=ftCt1+itC~t(记忆单元更新)ot=σ(Wo[ht1,xt]+bo)(输出门)ht=ottanh(Ct)(当前隐藏状态)
  • 其中:σ 表示 sigmoid 函数,tanh 表示双曲正切函数,Wf,Wi,Wc,Wo 为权重矩阵,bf,bi,bc,bo 为偏置项,ft,it,ot 分别表示遗忘门、输入门、输出门的激活值,Ct 为当前时刻的记忆单元状态,ht 为当前时刻的隐藏状态。
  • 全连接层( Fully Connected Layer :最后一层全连接层将LSTM的隐藏状态(hidden_size = 64)映射到输出空间(output_size = 1),即单一的有效功率预测值:
  • y = W ⋅ h t + b y = W \cdot h_{t} + b y=Wht+b
  • 其中,W 是全连接层的权重矩阵,ht 为最后一个时间步的隐藏状态,b 是偏置项。
  • 模型整体结构: 输入序列([Batch Size, Seq_Length, Input_Size]) -> LSTM 层 1 -> LSTM 层 2 -> 全连接层 -> 输出([Batch Size, 1])

2. 模型的整体训练流程

  1. 数据准备:首先对原始数据进行预处理,填补缺失值,并使用滑动窗口法创建时间序列特征。然后,采用 train_test_split 将数据集划分为训练集(80%)和测试集(20%)。

  2. 数据加载与处理:使用 torch.utils.data.DatasetDataLoader 将数据划分为批量(Batch Size = 64)并封装成可迭代数据集。在训练时,训练集的数据被打乱(shuffle=True),而验证集保持原有顺序(shuffle=False)。

  3. 模型初始化与配置:模型结构包括两层LSTM和一个全连接层。设备优先使用 GPU(若可用),否则使用 CPU。损失函数选用 MSELoss(均方误差),优化器选用 Adam(学习率为 0.001)。

  4. 模型训练流程

    1. 每个 epoch 内,模型遍历训练集,执行以下步骤:

      • 将当前批次的输入数据(X_batch)和目标数据(y_batch)传入模型。
      • 计算模型输出值与真实值之间的均方误差(loss = criterion(outputs, y_batch))。
      • 反向传播误差,计算每个参数的梯度(loss.backward())。
      • 使用优化器更新模型参数(optimizer.step())。
      • 累加并记录当前批次的损失。
    2. 每个 epoch 结束后,使用验证集数据进行模型评估,并记录验证集的平均损失(val_loss)。

  5. 模型评估指标

    1. 使用均方误差(MSE)和平均绝对误差(MAE)作为模型的主要评估指标。
    2. 计算公式为: M S E = 1 N ∑ i = 1 N ( y i − y ^ i ) 2 MSE = \frac{1}{N} \sum_{i=1}^{N}(y_i - \hat{y}_i)^2 MSE=N1i=1N(yiy^i)2 M A E = 1 N ∑ i = 1 N ∣ y i − y ^ i ∣ MAE = \frac{1}{N} \sum_{i=1}^{N}|y_i - \hat{y}_i| MAE=N1i=1Nyiy^i 其中,N 是样本总数,yi 为真实值,y^i 为预测值。
  6. 结果可视化与模型性能评估:在模型训练完成后,通过绘制实际值与预测值的曲线图直观展示模型性能,并打印评估指标(MSE和MAE),以判断模型的整体效果。

5. 核心代码详细讲解

  1. 数据预处理和特征工程部分
col_set_zero = ['Active Power (kW)', 'Weather Daily Rainfall (mm)']  定义需要填充为0的列名列表
data[col_set_zero] = data[col_set_zero].fillna(0)  将指定列的缺失值填充为0
  • col_set_zero:指定需要填充为0的列名列表,这些列包括Active Power (kW)(有效功率)和Weather Daily Rainfall (mm)(日降雨量)。
  • data[col_set_zero].fillna(0):将指定列(电力功率和降雨量)中所有缺失值替换为0,以表示数据记录时的“无降雨”和“无功率输出”状态。这种处理方式能够防止模型在学习时因缺失数据而引入噪声。
for col in data.columns:
    data[col].fillna(data[col].interpolate(method='nearest'), inplace=True)  对每一列进行插值填充
  • for col in data.columns:遍历数据表中的每一列。
  • data[col].interpolate(method='nearest'):采用最近邻插值法填补缺失值,即用与缺失值位置最接近的上下数据来填充。这种方法能够保持数据的连续性,并且适用于时间序列数据的填充,能够更好地维持数据在时间维度上的趋势性。
scaler = StandardScaler()  初始化标准化工具
scaled_features = scaler.fit_transform(df[feature_cols])  对特征列进行标准化
  • scaler = StandardScaler():初始化 StandardScaler 对象。StandardScaler 是一种常用的标准化工具,将特征数据转换为均值为0、标准差为1的标准正态分布。
  • scaler.fit_transform(df[feature_cols]):对 feature_cols 中指定的特征列进行标准化处理。标准化能够消除不同量纲特征之间的差异,使模型更易于训练。
X, y = create_sequences(scaled_features, targets, SEQ_LENGTH)  创建特征序列和目标值序列
  • 该行调用了 create_sequences 函数,使用滑动窗口方法构建时间序列特征:

    • scaled_features:标准化后的特征数据。
    • targets:目标值(有效功率Active Power)。
    • SEQ_LENGTH:时间序列长度(即使用过去24个时间步的数据进行预测)。
    • X, y:分别为创建好的特征序列和对应的目标值序列。

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

  • train_test_split:将创建好的特征序列和目标值按照8:2的比例分为训练集和测试集,不打乱数据顺序(shuffle=False),这在处理时间序列数据时尤为重要。
  1. 模型架构构建部分
class LSTMModel(nn.Module):def init(self, input_size, hidden_size, num_layers, output_size):super(LSTMModel, self).__init__()  调用父类的构造函数
        self.hidden_size = hidden_size  定义隐藏层大小
        self.num_layers = num_layers  定义LSTM层数
        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)  初始化LSTM层
        self.fc = nn.Linear(hidden_size, output_size)  初始化全连接层,将隐藏层输出映射到目标输出
  • super(LSTMModel, self).__init__():调用 nn.Module 的构造函数,以便在自定义模型中使用 PyTorch 提供的内置方法。

  • self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True):定义两层LSTM网络:

    • input_size:输入特征维度(9个特征)。
    • hidden_size:隐藏单元数量(64个神经元)。
    • num_layers:LSTM层数(2层)。
    • batch_first=True:指定输入数据格式为 [Batch Size, Seq Length, Input Size]
  • self.fc = nn.Linear(hidden_size, output_size):定义全连接层,将隐藏状态的输出(维度为 hidden_size = 64)映射到输出空间(output_size = 1,即单一预测值)。

def forward(self, x):
    h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)  初始化隐藏状态
    c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device)  初始化细胞状态
    out, _ = self.lstm(x, (h0, c0))  将输入数据通过LSTM层
    out = out[:, -1, :]  取出序列中最后一个时间步的输出
    out = self.fc(out)  通过全连接层得到预测结果return out  返回最终预测值
  • h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size).to(x.device):初始化隐藏状态为全零张量,形状为 [LSTM层数, Batch Size, 隐藏单元数量]
  • out, _ = self.lstm(x, (h0, c0)):将输入数据 x 通过LSTM层,并得到输出 out(形状为 [Batch Size, Seq Length, Hidden Size])。
  • out = out[:, -1, :]:取出最后一个时间步的隐藏状态作为当前序列的特征表示。
  • out = self.fc(out):将LSTM的输出通过全连接层,映射到单一目标值。
  1. 模型训练与评估部分
for epoch in range(num_epochs):  遍历每一个训练轮
    model.train()  设置模型为训练模式
    epoch_loss = 0  初始化本轮的损失累积for X_batch, y_batch in train_loader:  遍历训练数据加载器中的每个批次
        X_batch = X_batch.to(device)  将特征数据移动到设备
        y_batch = y_batch.to(device)  将目标数据移动到设备
        outputs = model(X_batch)  通过模型获取预测输出
        loss = criterion(outputs, y_batch)  计算预测值与真实值之间的损失
        optimizer.zero_grad()  清零优化器的梯度
        loss.backward()  反向传播计算梯度
        optimizer.step()  更新模型参数
        epoch_loss += loss.item() * X_batch.size(0)  累加损失,乘以批量大小以得到总损失
  • model.train():将模型设置为训练模式。
  • loss = criterion(outputs, y_batch):计算当前批次的均方误差(MSELoss)损失值。
  • loss.backward():通过反向传播计算当前批次的梯度。
  • optimizer.step():使用 Adam 优化器更新模型参数。

4o

6. 模型优缺点评价

模型优点:

  1. 时间序列特征捕捉能力强:采用了两层LSTM结构,能够有效捕捉时间序列数据中的长期依赖关系,尤其在处理具有周期性和趋势性的光伏发电数据时表现出色。
  2. 多维特征输入融合:模型整合了包括风速、温度、湿度、辐射强度等多个气象特征及电力数据,使用标准化处理消除不同特征量纲间的差异,有助于模型更好地理解不同输入变量之间的关系。
  3. 优化训练流程:使用Adam优化器配合均方误差(MSE)损失函数,有效提升了模型训练的收敛速度和稳定性。此外,采用滑动窗口方法生成序列数据,使模型能够利用更长的历史数据进行预测。

模型缺点:

  1. 长序列依赖性不足:尽管LSTM能够捕捉长时间依赖关系,但随着时间序列长度的增加(如SEQ_LENGTH较大时),模型的记忆能力会下降,从而导致捕捉长期依赖信息的效果变差。
  2. 模型复杂度高:双层LSTM的隐藏状态数量较多,参数较为复杂,导致训练时间较长,对计算资源的需求较高,尤其在处理更大规模的数据集时,可能会出现效率瓶颈。
  3. 对噪声数据敏感:该模型使用零填充和插值法处理缺失值,但这两种方法可能引入噪声,尤其在数据质量较差的情况下,可能导致模型学习到不真实的模式,影响预测性能。

可能的改进方向:

  1. 引入注意力机制:可以尝试在LSTM后添加注意力层(Attention Mechanism),让模型能够更关注不同时间步的数据,从而提升对长时间序列中重要信息的捕捉能力。
  2. 增加超参数调优:通过Grid Search或Bayesian Optimization等方法,进一步优化LSTM的隐藏单元数量、层数和学习率等超参数,以提升模型性能。
  3. 数据增强与特征选择:尝试使用更多的数据增强方法(例如增加噪声、平移、时间序列数据平滑等)以及特征选择算法,筛选出对目标值影响最大的特征,从而降低数据维度,提高模型效率。

↓↓↓更多热门推荐:
基于YOLOv4和DeepSORT的车牌识别与跟踪系统
基于人工智能的实时健身训练分析系统:深蹲姿态识别与动作评估

全部项目数据集、代码、教程进入官网zzgcz.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2184723.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

构造函数继承

构造函数继承 主要通过在子类的构造函数中调用父类的构造函数,绑定子类实例的 this,从而实现子类对父类属性的继承。这种方法避免了父类和子类共享原型链上的属性,并且可以传递参数给父类的构造函数。 构造函数继承的实现步骤: …

Windows远程Kylin系统-VNC

Windows远程Kylin系统-VNC 一. 配置 yum源 二. 清理yum缓存 三. 安装VNC并配置 nkvers yum install tigervnc tigervnc-server -ycp /lib/systemd/system/vncserver.service /etc/systemd/system/vncserver:1.service 说明:vncserver:1.service中的:1表…

Windows 环境下安装 Anaconda 并适配到 PowerShell 的保姆级教程

Anaconda Anaconda 是一个流行的 Python 数据科学和机器学习平台,它包括了 Conda 包管理器、Python 以及数百个用于科学计算的库和工具。Anaconda 旨在简化包和环境管理,使得安装、更新和管理软件包变得容易,同时也能够轻松创建和切换不同的P…

案例-百度热榜页面实现

文章目录 效果展示要求内容注意代码内容 效果展示 要求内容 整个盒子大小:536*536标题字体柜20px、加粗,纯黑,换一换字体大小20px、颜色0055db、刷新图标是本地图片内容字体18px、上下边距15px、下边框实心2px颜色f3f3f3这个需要根据页面显示…

【顺序查找】

目录 一. 顺序查找的概念二. 查找的性能计算 \quad 一. 顺序查找的概念 \quad \quad 二. 查找的性能计算 \quad

【LLM论文日更】| 通过指令调整进行零样本稠密检索的无监督文本表示学习

论文:https://arxiv.org/pdf/2409.16497代码:暂未开源机构:Amazon AGI、宾夕法尼亚州立大学领域:Dense Retrieval发表:Accepted at DCAI24 workshopCIKM2024 研究背景 研究问题:这篇文章要解决的问题是如…

Linux学习笔记(三):文件管理、复杂操作与实用工具详解

Linux学习笔记(三):文件管理、复杂操作与实用工具详解 Linux 学习笔记(二):深入理解用户管理、运行级别与命令行操作 1.文件操作的基本操作 1.1 创建 创建目录 mkdir:创建目录 mkdir /home/d…

【MySQL】多表联合查询常见练习题

数据库表如下: teacher:老师表 course:课程表 student:学生表 class:班级表 sc:成绩表 一、根据上面5张表写sql语句 1. 查询” 01 “课程比” 02 “课程成绩高的学生的信息及课程分数 select student.…

AI智能时代的图书馆未来,你想象过吗!

AI智能时代的图书馆未来,你想象过吗! 前言AI智能时代的图书馆未来 前言 教育数字化和 AI 时代的浪潮正汹涌而来,图书馆也站在了变革的十字路口。我们看到高等教育正在发生深刻的变革,从教学模式到人才培养理念,都在经…

基于SSM+VUE的学生宿舍管理系统

文未可获取一份本项目的java源码和数据库参考。 随着社会经济的迅速发展和科学技术的全面进步,计算机事业的飞速发展,以计算机与通信技术为基础的信息系统正处于蓬勃发展的时期,当今社会正快速向数字化,信息化,网络化…

VSCode开发Vue3+TS项目中遇到各种波浪线(诊断信息)

一、问题汇总 在使用Visual Studio Code(VSCode)开发Vue3 TypeScript项目时,会遇到各种波浪线错误(诊断信息),这些问题或错误通常由以下几人原因引起的: 1.1 常见问题 1、typeScript配置问题…

【探索 GDB 和 CGDB】:强大的调试工具介绍

📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 1. 引言📃 1.1 …

Kotlin:1.8.0 的新特性

一、概述 Kotlin 1.8.0版本英语官方文档 Kotlin 1.8.0 中文官方文档 The Kotlin 1.8.0 release is out and here are some of its biggest highlights: Kotlin 1.8.0发布了,下面是它的一些亮点: JVM 平台新增实验性函数:递归复制或删除目录内容改进了 …

SpringMVC——REST

路径请求方式请求行为 查询:GET 新增:POST 修改:PUT 删除:DELETE 有重复的东西怎么办

第L6周:机器学习|支持向量机(SVM):2. 支持向量机实战

本文为365天深度学习训练营 中的学习记录博客原作者:K同学啊 这里展示一下怎么调用scikit-learn库实现线性SVM,知道怎么调用扩展一下知识面就OK了。 1.scikit-learn库实现线性可分的SVM from sklearn import datasets from sklearn.model_selection im…

聊聊光刻工序常见术语(2)

上次,我们总结了光刻工序部分的术语,见文章: 《光刻工序常见术语中英文对照(1)》 这次,我们把剩下的又总结了一些,供大家参阅。 1,Developer Mist:显影液回溅产生的水…

计算机毕业设计 基于SpringBoot和Vue的课程教学平台的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

STM32(五)GPIO输入硬件电路及C语言知识复习

本小节主要是GPIO输入模式下的硬件电路和C语言知识的回顾 C语言中的数据:定义和引用 一、GPIO输入模式下的硬件和电路 1.按键介绍 可以用延时函数消除按键抖动 2.传感器模块介绍 (1)传感器元件的电阻会随模拟量的变化而变化,通…

【算法】链表:206.反转链表(easy)

系列专栏 《分治》 《模拟》 《Linux》 目录 1、题目链接 2、题目介绍 3、解法(快慢指针) 解题步骤: 关键点: 复杂度分析: 4、代码 1、题目链接 206. 反转链表 - 力扣(LeetCode) …

通信工程学习:什么是SMTP简单邮件传输协议

SMTP:简单邮件传输协议 SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议,是用于电子邮件传输的标准协议。它定义了电子邮件在互联网上的传输方式,以及邮件服务器之间的通信方式。以下是对SMTP协议…