使用神经网络预测光伏电站功率


1 前言

接了个机器学习的课题。初次尝试,花了一些时间,现在做完了打算简单总结一下。
先说一下做的课题,内容主要是使用神经网络模型预测光伏电站发电功率。输入数据是采用多个特征的多维度输入,之前看到很多人是做单个特征预测,也就是直接用先前的序列预测本身的下一个序列,这种就不太一样了。

用到的神经网络模型:BPNN、RNN、LSTM、Bi-LSTM。

以下给出的代码既不完整也不一定按顺序,仅供参考。
本篇主要是提供简单的思路。

 

2 准备工作

语言:Python

用的软件:Pycharm专业版+Anaconda,或者用Vscode自己搭环境也可以做。

神经网络框架:Pytorch。(顺带一提,自己用的轻薄本只有集显,所以Torch用的是无GPU加速的版本。)

其他用到的库:pandas, numpy, sklearn, matplotlib。

数据集来源:DKA太阳能中心,Desert Knowledge Australia Solar Centre,在数据下载里面有很多电站的数据,随便挑一个。([注] 该网站数据下载时会要求进行谷歌机器人验证,国内网络需要翻墙。)

 

3 流程

在这里插入图片描述

 

4 导入数据集

数据文件一般是csv或者xlsx格式,用pandas库直接导入,导入进来的数据这时是dataframe格式,有可能需要设置行列排序准则的参数,稍微注意一下。

按前面提供的那个数据,数据量比较多,就自己分割了一下,我还改了下样本名称之类的,其他可能还需要的一些小改动可参考这篇博文:从一份发电数据看组件Pr值衰减

import pandas as pd

file_path = './91-Site_1A-Trina_5W.csv'
data = pd.read_csv(file_path, header=0, low_memory=False, index_col=0)
data = data.rename(columns={
    u'1A Trina - Active Energy Delivered-Received (kWh)': 'AE_Power',
    u'1A Trina - Current Phase Average (A)': 'Current', #电流
    u'1A Trina - Wind Speed (m/s)': 'Wind_speed',   #风速
    u'1A Trina - Active Power (kW)': 'Power',   #功率
    u'1A Trina - Weather Relative Humidity (%)': 'Humidity',    #湿度
    u'1A Trina - Weather Temperature Celsius (\xb0C)': 'Temp',    #气温
    u'1A Trina - Global Horizontal Radiation (W/m\xb2)': 'GHI',   #全球水平辐照度
    u'1A Trina - Diffuse Horizontal Radiation (W/m\xb2)': 'DHI',   #扩散水平辐照度
    u'1A Trina - Wind Direction (Degrees)': 'Wind_dir',  #风向
    u'1A Trina - Weather Daily Rainfall (mm)': 'Rainfall'   #降雨
})

 

5 相关性分析

原始数据提供的样本有很多,需要筛选出影响比较大的特征作为输入变量。

分析方法不只一种。

个人是直接用了.corr()函数来分析

print(data.corr()['Power'])

 

6 数据预处理

这个步骤看自己的需求和数据的情况,主要的工作量也体现在这。

对于缺失值,如果是null值的,一般是补零,否则后面处理时会报错。

异常值,用正态分布或者箱形图识别剔除。

我处理输入集时还把所有功率为0的样本都删了,不过这样似乎会影响时序关系,这个涉及模型特性问题,就不深入讨论了。

# 删除功率为空的数据组
data = data.dropna(subset=['Power'])
# NAN值赋0
data = data.fillna(0)
data[data < 0] = 0

标准化处理,必不可少,否则训练时的loss值降不下来。

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
data[feature] = scaler.fit_transform(data[feature].to_numpy())

另外,就是数据的格式,整个流程中需要经历dataframe → \rightarrow numpy → \rightarrow tensor的转换。

这里也给出我数据集输入前的最后转换,参考代码:

# 数据集调整,X转tensor,y转一维序列
def create_dataset(data, target_features, input_features):
    data_x = data[input_features]
    data_y = data[target_features]
    data_x = torch.from_numpy(data_x.to_numpy()).float()
    data_x = data_x.reshape(data_x.shape[0], 1, data_x.shape[1])
    data_y = torch.squeeze(torch.from_numpy(data_y.to_numpy()).float())
    return data_x, data_y

 

7 神经网络模型

Pytorch框架下,做时间序列的普通模型基本上就是调一些参数。

参考代码:

import torch
import torch.nn as nn
import torch.nn.functional as F

# LSTM模型
class LSTMNet(nn.Module):

    def __init__(self, input_size):
        super(LSTMNet, self).__init__()
        self.rnn = nn.LSTM(
            input_size=input_size,
            hidden_size=64,
            num_layers=1,
            batch_first=True,
        )
        self.out = nn.Sequential(
            nn.Linear(64, 1)
        )

    def forward(self, x):
        r_out, (h_n, h_c) = self.rnn(x, None)  # None 表示 hidden state 会用全0的 state
        out = self.out(r_out[:, -1, :])
        # print(out.shape)
        return out


# Bi-LSTM模型
class BiLSTMNet(nn.Module):

    def __init__(self, input_size):
        super(BiLSTMNet, self).__init__()
        self.rnn = nn.LSTM(
            input_size=input_size,
            hidden_size=50,
            num_layers=2,
            batch_first=True,
            bidirectional=True
        )
        self.out = nn.Sequential(
            nn.Linear(100, 1)
        )

    def forward(self, x):
        r_out, (h_n, h_c) = self.rnn(x, None)  # None 表示 hidden state 会用全0的 state
        out = self.out(r_out[:, -1, :])
        # print(out.shape)
        return out

# BP神经网络
class Net_BP(nn.Module):
    def __init__(self, n_features, n_hidden=50, n_output=1):
        # n_features输入层神经元数量,也就是特征数量
        # n_hidden隐层神经元数量
        # n_output输出层神经元数量
        super(Net_BP, self).__init__()
        self.hidden = torch.nn.Linear(n_features, n_hidden)
        self.predict = torch.nn.Linear(n_hidden, n_output)

    def forward(self, x):
        x = F.relu(self.hidden(x))
        x = self.predict(x)
        return x


# RNN神经网络
class RNN(nn.Module):
    def __init__(self, input_size, hidden_size=50, output_size=1, num_layers=1):
        super(RNN, self).__init__()
        self.rnn = nn.RNN(input_size, hidden_size, num_layers)
        self.reg = nn.Linear(hidden_size, output_size)

    def forward(self, x):
        x, _ = self.rnn(x) # 未在不同序列中传递hidden_state
        return self.reg(x)

 

8 模型训练

这里以RNN模型为例子。

参考代码:

rnn = RNN(input_size=input_feature_num)
optimizer = torch.optim.Adam(rnn.parameters(), lr=0.01)
loss_func = nn.MSELoss()
epochs = 100
print(rnn)

for e in range(epochs):
    # 前向传播
    y_pred = rnn(train_x)
    y_pred = torch.squeeze(y_pred)
    loss = loss_func(y_pred, train_y)
    # 反向传播
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    if e % 20 == 0:
        print('Epoch:{}, Loss:{:.5f}'.format(e, loss.item()))

plt.plot(y_pred.detach().numpy(), 'r', label='y_pred')
plt.plot(train_y.detach().numpy(), 'b', label='y_train')
plt.legend()
plt.show()

训练完没问题的话还要记得保存模型。

参考代码:

MODEL_PATH = 'model_rnn.pth'
torch.save(rnn, MODEL_PATH)

这里我是直接保存了整个模型,有人说保存模型参数的方法会更好,这个就看个人需求了。

 

9 模型测试

测试用的数据集同样是经过之前的方式处理,然后要注意训练集与测试集的样本数量比例。一般是设为10:1左右。

模型性能使用几个评价指标来评定,我选用了MSE、RMSE、MAE R 2 R^2 R2,这四个指标,因为考虑到一些零值保留的问题,就没有使用MAPE

参考代码:

from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score
from sklearn.metrics import  mean_absolute_error

def prediction(model, series_x, series_y, name):
    model = model.eval()
    pred = model(series_x)
    pred[pred < 0] = 0
    length = len(series_y)
    for i in range(length):
        if series_y[i] == 0:
            pred[i] = 0
    pred = pred.view(-1).data.numpy()
    pred = y_scaler.inverse_transform(pred.reshape(-1, 1))
    series_y = y_scaler.inverse_transform(series_y.reshape(-1, 1))
    MSE = mean_squared_error(series_y, pred)
    RMSE = sqrt(MSE)
    R2 = r2_score(series_y, pred)
    MAE = mean_absolute_error(series_y, pred)
    # MAPE = method.MAPE_value(series_y, pred)
    print(name, ' :')
    print(' MSE: {:.3f}'.format(MSE))
    print(' RMSE: {:.3f}'.format(RMSE))
    print(' MAE: {:.3f}'.format(MAE))
    print(' R2: {:.3f}'.format(R2))
    # print(' MAPE: {:.5f}%'.format(MAPE))
    return pred

测试运行和画图部分就不说了,值得一提的是反归一化这步也要有,不然测试出来的误差明显是小得有问题的。

参考代码:

test_y = y_scaler.inverse_transform(test_y.reshape(-1, 1))

直接调用库很方便,但是要注意这里的反归一化是对应前面的归一化,要在同一文件里。

 

10 结果

没做样本分类等优化,所以结果不算很好,仅供参考。

预测时间跨度大概72小时:

附录

该实验初版完整代码已在github开源:https://github.com/tappat225/PV_prediction

  • 63
    点赞
  • 441
    收藏
    觉得还不错? 一键收藏
  • 45
    评论
### 回答1: 我们可以使用MATLAB中的神经网络工具箱来编写一个使用BP神经网络预测光伏发电功率的MATLAB代码。下面是一个示例代码: % 创建神经网络 net = newff(minmax(inputs),[1],{'tansig'},'trainlm'); % 设置训练参数 net.trainParam.epochs = 1000; net.trainParam.goal = 0.001; % 训练神经网络 net = train(net,inputs,targets); % 预测结果 outputs = sim(net,inputs); ### 回答2: 使用bp神经网络预测光伏发电功率的MATLAB代码如下: ```matlab % 数据准备 X = [2 3 4 5 6]; % 光照强度 Y = [10 15 20 25 30]; % 实际发电功率 % 归一化数据 X_min = min(X); X_max = max(X); Y_min = min(Y); Y_max = max(Y); X_normalized = (X - X_min) / (X_max - X_min); Y_normalized = (Y - Y_min) / (Y_max - Y_min); % 构建神经网络 net = fitnet([10 5]); % 2个隐藏层,第一个隐藏层有10个神经元,第二个隐藏层有5个神经元 net.trainParam.epochs = 1000; % 迭代次数 net.trainParam.goal = 0.001; % 训练目标误差 net.trainParam.max_fail = 20; % 最大连续迭代失败次数 % 训练网络 net = train(net, X_normalized, Y_normalized); % 用训练好的网络预测 X_test = [3.5 4.5 5.5]; % 测试数据 X_test_normalized = (X_test - X_min) / (X_max - X_min); Y_test_normalized = net(X_test_normalized); % 还原预测结果 Y_test = Y_test_normalized * (Y_max - Y_min) + Y_min; % 输出预测结果 disp('预测结果:'); disp(Y_test); ``` 该代码首先给出了训练数据的光照强度X和实际发电功率Y。然后对数据进行归一化处理,再使用MATLAB的神经网络工具箱构建一个bp神经网络模型。设置训练参数,包括迭代次数、训练目标误差和最大连续迭代失败次数。接下来使用训练集对网络进行训练。然后给出测试数据X_test,并对其进行归一化处理。最后使用训练好的网络模型对归一化后的测试数据进行预测,并将预测结果还原为实际发电功率。最后输出预测结果。 ### 回答3: 使用bp神经网络预测光伏发电功率的MATLAB代码如下: 首先,导入数据集,并将数据集划分为训练集和测试集。 ```matlab % 导入数据集 data = load('data.csv'); X = data(:, 1:end-1); % 特征矩阵,最后一列为输出 Y = data(:, end); % 输出向量 % 划分数据集为训练集和测试集 train_ratio = 0.8; train_size = floor(train_ratio * size(X, 1)); X_train = X(1:train_size, :); Y_train = Y(1:train_size, :); X_test = X(train_size+1:end, :); Y_test = Y(train_size+1:end, :); ``` 接下来,创建并训练bp神经网络模型。 ```matlab % 创建bp神经网络模型 hidden_layer_size = 10; % 隐含层神经元数量 net = feedforwardnet(hidden_layer_size, 'trainlm'); % 创建网络 net.trainParam.showWindow = false; % 关闭训练过程窗口 net.trainParam.epochs = 1000; % 训练次数 % 训练bp神经网络模型 net = train(net, X_train', Y_train'); % 注意需要输入转置 ``` 最后,使用训练好的bp神经网络模型进行预测,并计算预测结果的均方误差。 ```matlab % 使用训练好的bp神经网络模型进行功率预测 Y_pred = net(X_test'); % 注意需要输入转置 % 计算预测结果均方误差 mse = mean((Y_pred' - Y_test).^2); ``` 以上代码演示了使用bp神经网络预测光伏发电功率的MATLAB代码。需要注意的是,根据实际情况可能需要调整神经网络的超参数以获得更好的预测效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 45
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值