0


【比赛记录】国电投-光伏电站人工智能运维大数据处理分析比赛

前言

1-1 简介

  1. DataFountain平台举办的比赛,赛题:光伏电站人工智能运维大数据处理分析。以下是比赛链接:光伏电站人工智能运维大数据处理分析 Competitions - DataFountain

1-2 任务背景

  1. 在分析光伏发电原理的基础上,论证了辐照度、光伏板工作温度等影响光伏输出功率的因素,通过实时监测的光伏板运行状态参数和气象参数建立预测模型,预估光伏电站瞬时发电量。其中光伏板运行状态参数包括太阳能电池板背板温度、其组成的光伏阵列的电压和电流;气象参数包括太阳能辐照度、环境温湿度、风速、风向等。本质为回归任务,通过多个维度的X去预测发电量Y

1-3 数据介绍

其中比赛官网给出了各个字段的详细介绍;

  1. 表格字段及含义如下:
  2. ID:当前记录条数;
  3. 板温:光伏电池板背测温度;
  4. 现场温度:光伏电站现场温度;
  5. 转换效率:为计算得到的平均转换效率;
  6. 转换效率A:数据采集点A处的光伏板转换效率;
  7. 转换效率B:数据采集点B处的光伏板转换效率;
  8. 转换效率C:数据采集点C处的光伏板转换效率;
  9. 转换效率D:数据采集点D处的光伏板转换效率;
  10. 电压A:为数据采集点A处汇流箱电压值;
  11. 电压B:为数据采集点B处汇流箱电压值;
  12. 电压C:为数据采集点C处汇流箱电压值;
  13. 电压D:为数据采集点D处汇流箱电压值;
  14. 电流A:为采集点A处汇流箱电流值;
  15. 电流B:为采集点B处汇流箱电流值;
  16. 电流C:为采集点C处汇流箱电流值;
  17. 电流D:为采集点D处汇流箱电流值;
  18. 功率A:为采集点A处的功率PaP=UI
  19. 功率B:为采集点B处的功率PbP=UI
  20. 功率C:为采集点C处的功率PcP=UI
  21. 功率D:为采集点D处的功率PdP=UI
  22. 平均功率:为ABC三点功率的平均值:(Pa+Pb+Pc)/3;
  23. 风速:为光伏电厂现场风速测量值;
  24. 风向:为光伏电厂现场风的来向;
  25. 预估发电量为:需经过参赛者分析计算得到的预测功率值;

2 任务实现

2-1 深度学习-多元线性回归

  1. 赛题任务是根据多个自变量X(板温、温度等) 来确定唯一的因变量Y(光伏发电量),非常典型的多元线性回归任务。多元回归任务的公式如下:
  2. ![y = {k_{1}} x_{1}+ {k_{2}} x_{2}+ {k_{3}} x_{3}+ ...+{k_{n}} x_{n}+ b](https://latex.codecogs.com/gif.latex?y%20%3D%20%7Bk_%7B1%7D%7D%20x_%7B1%7D+%20%7Bk_%7B2%7D%7D%20x_%7B2%7D+%20%7Bk_%7B3%7D%7D%20x_%7B3%7D+%20...+%7Bk_%7Bn%7D%7D%20x_%7Bn%7D+%20b)

2-1-1 导入工具库

  1. import pandas as pd
  2. import numpy as np
  3. import torch
  4. import torch.nn
  5. from sklearn.preprocessing import scale
  6. from sklearn.model_selection import train_test_split
  7. import matplotlib.pyplot as plt
  8. from matplotlib.font_manager import FontProperties

2-1-2 查看数据

  1. train_data_path = '/home/zhenhengdong/WORk/Relation_Extraction/Jupyter_files/Codes/Untitled Folder/public.train.csv'
  2. Train_data = pd.read_csv(train_data_path)
  3. test_data_path = '/home/zhenhengdong/WORk/Relation_Extraction/Jupyter_files/Codes/Untitled Folder/test_data.csv'
  4. Test_data = pd.read_csv(test_data_path)

2-1-3 读入数据

  1. 采用np.loadtxt()方法读入数据。原始数据中每一行包含20个维度的X与一个Y,将XY进行分割。
  1. #跳过表头,并且设置数据格式
  2. train_XY = np.loadtxt(train_data_path, delimiter=',', skiprows = 1,dtype=np.float32)
  3. test_XY = np.loadtxt(test_data_path, delimiter=',', skiprows = 1,dtype=np.float32)
  4. #分割多维度X和Y,取出前19列作为特征X,最后一列作为Y。
  5. TrainX_data = torch.from_numpy(train_XY[:, 1:-1])# 除去id 取前19
  6. TrainY_data = torch.from_numpy(train_XY[:, [-1]])# 取最后1
  7. TestX_data = torch.from_numpy(test_XY[:, 1:-1])# 除去id 取前19
  8. TestY_data = torch.from_numpy(test_XY[:, [-1]])# 取最后1

2-1-4 数据归一化

  1. #训练数据归一化
  2. TrainX_data, TrainY_data = torch.FloatTensor(scale(TrainX_data)), torch.unsqueeze(torch.FloatTensor(TrainY_data), dim=1)
  3. #测试数据归一化
  4. TestX_data, TestY_data = torch.FloatTensor(scale(TestX_data)), torch.unsqueeze(torch.FloatTensor(TestY_data), dim=1)

2-1-5 定义模型结构

  1. 由于是多元线性回归任务,在模型定义中采用线性层和激活函数搭配的方式进行构建。通过两个线性层进行变换,两个线性层之间设定激活函数,模型设计时采用Relu()函数(也可以替换为其他激活函数,比如RRelu()、Tanh()等)作为激活函数。
  1. class Net(torch.nn.Module):
  2. def __init__(self, input_num, hidden_num, output_num):
  3. super(Net, self).__init__()
  4. self.net = torch.nn.Sequential(
  5. torch.nn.Linear(input_num, hidden_num),
  6. torch.nn.ReLU(),
  7. torch.nn.Linear(hidden_num, output_num),
  8. torch.nn.ReLU()
  9. )
  10. def forward(self, input):
  11. return self.net(input)

2-1-6 实例化模型

  1. 模型实例化中,将模型的输入维度设定为19,采用了数据中的19个维度(除去设备id),并借助中间层进行过渡,将19个维度的信息转换为10维度,之间采用激活函数进行变换,最后将10维度的数据转换为1维,得到最终的预测结果。

  1. net = Net(input_num=19, hidden_num=10, output_num=1)

2-1-7 设置超参数

  1. 将训练轮次、学习率、batch_size和每次训练的step进行设置。
  1. epochs = 500
  2. learning_rate = 0.001
  3. batch_size = 10
  4. total_step = int(TrainX_data.shape[0] / batch_size)

2-1-8 定义优化器与损失函数

  1. 采用Adam优化器,Adam优化器结合了AdaGradRMSProp两种优化算法的优点。对梯度的一阶矩估计(First Moment Estimation,即梯度的均值)和二阶矩估计(Second Moment Estimation,即梯度的未中心化的方差)进行综合考虑,计算出更新步长。
  2. 损失函数测量输入x和目标y中每个元素之间的均方误差。
  1. optimizer = torch.optim.Adam(net.parameters(), lr=learning_rate)
  2. loss_func = torch.nn.MSELoss()

2-1-9 定义参数重置函数

  1. 保证每次重新执行
  1. for循环

时从

开始训练。

  1. def weight_reset(m):
  2. if isinstance(m, torch.nn.Conv2d) or isinstance(m, torch.nn.Linear):
  3. m.reset_parameters()

2-1-10 开始训练

  1. %%time
  2. net.apply(weight_reset)
  3. epoch_train_loss_value = []
  4. step_train_loss_value = []
  5. epoch_valid_loss_value = []
  6. for i in range(epochs):
  7. for step in range(total_step):
  8. xs = TrainX_data[step * batch_size:(step + 1) * batch_size, :]
  9. ys = TrainY_data[step * batch_size:(step + 1) * batch_size]
  10. prediction = net(xs)
  11. loss = loss_func(prediction, ys)
  12. optimizer.zero_grad()
  13. loss.backward()
  14. optimizer.step()
  15. step_train_loss_value.append(loss.cpu().detach().numpy())
  16. valid_loss = loss_func(net(TestX_data), TestY_data)
  17. epoch_valid_loss_value.append(valid_loss)
  18. epoch_train_loss_value.append(np.mean(step_train_loss_value))
  19. if i%50==0:
  20. print('epoch={:3d}/{:3d}, train_loss={:.4f}, valid_loss={:.4f}'.format(i + 1,
  21. epochs,
  22. np.mean(step_train_loss_value),
  23. valid_loss))

2-1-11 损失值可视化

  1. new_epoch_valid_loss_value = []
  2. for valid_loss_item in epoch_valid_loss_value:
  3. new_epoch_valid_loss_value.append(valid_loss_item.detach().numpy().tolist())
  4. #画图
  5. fig = plt.gcf()
  6. fig.set_size_inches(10, 5)
  7. plt.xlabel('Epochs', fontsize=15)
  8. plt.ylabel('Loss', fontsize=15)
  9. plt.plot(epoch_train_loss_value, 'blue', label='Train loss')
  10. plt.plot(new_epoch_valid_loss_value, 'red', label='Valid loss')
  11. plt.legend(loc='best')
  12. plt.title('Training and Validation loss', fontsize=15)
  13. plt.show()

2-1-12 模型预测可视化

  1. #生成预测值
  2. prediction = []
  3. for i in range(TestX_data.shape[0]):
  4. prediction.append(net(TestX_data[i, :]).item())
  5. #对真实值处理,由Tensor转化为list
  6. new_TestY_data = []
  7. for TestY_data_item in TestY_data:
  8. new_TestY_data.append(TestY_data_item.detach().numpy().tolist()[0][0][0])
  9. #画图
  10. fig = plt.gcf()
  11. fig.set_size_inches(10, 5)
  12. myfont = FontProperties('SimSun')
  13. plt.title('Prediction and GroundTruth', fontproperties=myfont, fontsize=15)
  14. plt.scatter(np.arange(len(prediction)), prediction, label='Prediction', s=20)
  15. plt.scatter(np.arange(len(prediction)), new_TestY_data, label='GroundTruth', s=20)
  16. plt.xlabel('', fontproperties=myfont, fontsize=15)
  17. plt.ylabel('Power generation', fontproperties=myfont, fontsize=15)
  18. plt.legend()
  19. plt.show()

2-1-13 计算方差得分

  1. 采用方差得分作为评价指标。explained_variance_score()方法解释回归模型的方差得分,其值取值范围是[0,1],越接近于1说明自变量越能解释因变量的方差变化,值越小则说明效果越差。
  1. from sklearn.metrics import explained_variance_score
  2. score = explained_variance_score(prediction, new_TestY_data)

2-2 机器学习-xgboost

  1. XGBoost(eXtreme Gradient Boosting)又叫极度梯度提升树,是boosting算法的一种实现方式。针对分类或回归问题,有非常好的效果。

2-2-1 导入工具库

  1. import xgboost as xgb
  2. from sklearn.metrics import explained_variance_score

2-2-2 导入数据

  1. train_XY = np.loadtxt(train_data_path, delimiter=',', skiprows = 1,dtype=np.float32)
  2. test_XY = np.loadtxt(test_data_path, delimiter=',', skiprows = 1,dtype=np.float32)
  3. TrainX_data = torch.from_numpy(train_XY[:, 1:-1])# 除去id 取前19
  4. TrainY_data = torch.from_numpy(train_XY[:, [-1]])# 取最后1
  5. TestX_data = torch.from_numpy(test_XY[:, 1:-1])# 除去id 取前19
  6. TestY_data = torch.from_numpy(test_XY[:, [-1]])# 取最后1

2-2-3 构建模型

  1. 参数详解

max_depth=3每一棵树最大深度,默认6;learning_rate=0.1学习率,每棵树的预测结果都要乘以这个学习率,默认0.3;n_estimators=100使用多少棵树来拟合,也可以理解为多少次迭代。默认100;objective='reg:linear'此默认参数与 XGBClassifier 不同;booster='gbtree'有两种模型可以选择gbtree和gblinear。gbtree使用基于树的模型进行提升计算,gblinear使用线性模型进行提升计算。默认为gbtree;gamma=0叶节点上进行进一步分裂所需的最小"损失减少"。默认0;min_child_weight=1可以理解为叶子节点最小样本数,默认1;subsample=1 训练集抽样比例,每次拟合一棵树之前,都会进行该抽样步骤。默认1,取值范围(0, 1];subsample=1训练集抽样比例,每次拟合一棵树之前,都会进行该抽样步骤。默认1,取值范围(0, 1];colsample_bytree=1每次拟合一棵树之前,决定使用多少个特征,参数默认1,取值范围(0, 1];reg_alpha=0默认为0,控制模型复杂程度的权重值的 L1 正则项参数,参数值越大,模型越不容易过拟合;reg_lambda=1 默认为1,控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合;random_state=0) 随机种子;

  1. model = xgb.XGBRegressor(max_depth=3, # 每一棵树最大深度,默认6;
  2. learning_rate=0.1, # 学习率,每棵树的预测结果都要乘以这个学习率,默认0.3;
  3. n_estimators=100, # 使用多少棵树来拟合,也可以理解为多少次迭代。默认100;
  4. objective='reg:linear', # 此默认参数与 XGBClassifier 不同
  5. booster='gbtree', # 有两种模型可以选择gbtree和gblinear。gbtree使用基于树的模型进行提升计算,gblinear使用线性模型进行提升计算。默认为gbtree
  6. gamma=0, # 叶节点上进行进一步分裂所需的最小"损失减少"。默认0;
  7. min_child_weight=1, # 可以理解为叶子节点最小样本数,默认1;
  8. subsample=1, # 训练集抽样比例,每次拟合一棵树之前,都会进行该抽样步骤。默认1,取值范围(0, 1]
  9. colsample_bytree=1, # 每次拟合一棵树之前,决定使用多少个特征,参数默认1,取值范围(0, 1]。
  10. reg_alpha=0, # 默认为0,控制模型复杂程度的权重值的 L1 正则项参数,参数值越大,模型越不容易过拟合。
  11. reg_lambda=1, # 默认为1,控制模型复杂度的权重值的L2正则化项参数,参数越大,模型越不容易过拟合。
  12. random_state=0) # 设定随机种子
  13. model.fit(TrainX_data,TrainY_data)
  14. test_predict=model.predict(TestX_data)
  15. train_predict = model.predict(TrainX_data)

2-2-4 计算方差得分

2-2-5 查看重要特征

  1. from xgboost import plot_importance
  2. plot_importance(model)
  3. plt.show()

2-2-6 模型预测可视化

  1. new_TestY_data = []
  2. for TestY_data_item in TestY_data:
  3. new_TestY_data.append(TestY_data_item.detach().numpy().tolist()[0])
  4. #画图
  5. fig = plt.gcf()
  6. fig.set_size_inches(10, 5)
  7. myfont = FontProperties('SimSun')
  8. plt.title('Prediction and GroundTruth', fontproperties=myfont, fontsize=15)
  9. plt.scatter(np.arange(len(new_TestY_data)), test_predict.tolist(), label='Prediction', s=20)
  10. plt.scatter(np.arange(len(new_TestY_data)), new_TestY_data, label='GroundTruth', s=20)
  11. plt.xlabel('', fontproperties=myfont, fontsize=15)
  12. plt.ylabel('Power generation', fontproperties=myfont, fontsize=15)
  13. plt.legend()
  14. plt.show()


本文转载自: https://blog.csdn.net/weixin_44750512/article/details/128784540
版权归原作者 DonngZH 所有, 如有侵权,请联系我们删除。

“【比赛记录】国电投-光伏电站人工智能运维大数据处理分析比赛”的评论:

还没有评论