#AI夏令营 #Datawhale夏令营
一种基于LSTM的电力暴力预测
1.赛事简介
随着全球经济的快速发展和城市化进程的加速,电力系统面临着越来越大的挑战。电力需求的准确预测对于电网的稳定运行、能源的有效管理以及可再生能源的整合至关重要。
然而,电力需求受到多种因素的影响,为了提高电力需求预测的准确性和可靠性,推动智能电网和可持续能源系统的发展,本场以“电力需求预测”为赛题的数据算法挑战赛。选手需要根据历史数据构建有效的模型,能够准确的预测未来电力需求。
2.赛题任务
给定多个房屋对应电力消耗历史N天的相关序列数据等信息,预测房屋对应电力的消耗。
3.数据展示
赛题数据由训练集和测试集组成,为了保证比赛的公平性,将每日日期进行脱敏,用1-N进行标识,即1为数据集最近一天,其中1-10为测试集数据。数据集由字段id(房屋id)、 dt(日标识)、type(房屋类型)、target(实际电力消耗)组成,如下图所示。
每个房间给出其从第11-506天的电力消耗,共2877305行,5832个房间,19种房间类型,下图为train.csv的数据展示。
4.模型构建
(1)导入模块
import pandas as pd
import numpy as np
from sklearn.metrics import mean_squared_error
from sklearn.metrics import mean_absolute_error
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense
(2)数据集详细可视化
房间类型与电力消耗关系
import matplotlib.pyplot as plt
import pandas as pd
import matplotlib.cm as cm
plt.rcParams['font.family'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
target = train.groupby('type')['target'].mean().reset_index()
plt.figure(figsize=(6, 4))
norm = plt.Normalize(vmin=0, vmax=len(target['type'].unique())-1)
colors = cm.viridis(norm(range(len(target['type'].unique()))))
plt.bar(target['type'], target['target'], color=colors)
plt.xlabel('房间类型')
plt.ylabel('平均消耗电力')
plt.title('房间类型与电力消耗关系')
plt.show()
以第一个房间编号为例,展示其随时间的电力变化
id_all = train[train['id'] == '00037f39cf']
plt.figure(figsize=(8, 4))
plt.plot(id_all['dt'], id_all['target'], linestyle='-')
plt.xlabel('日期')
plt.ylabel('电力消耗')
plt.title('电力消耗随日期变化')
plt.show()
(3)LSTM模型
LSTM(Long Short-Term Memory,长短期记忆网络)是一种特殊的循环神经网络(RNN)架构,用于处理序列数据中的长期依赖问题。传统的RNN在处理长序列时往往会遇到梯度消失或梯度爆炸的问题,导致网络无法有效捕获到长距离的依赖关系。LSTM通过引入三个“门”控制结构(遗忘门、输入门、输出门)来改进这个问题,从而允许网络更有效地学习和存储长期依赖信息。
LSTM单元内部主要包括以下几个部分:
-
遗忘门(Forget Gate):遗忘门决定哪些信息应该从单元状态中丢弃。它通过查看当前输入
h_t-1
(上一个时间步的输出)和x_t
(当前时间步的输入),输出一个0到1之间的值,这个值会与上一个时间步的单元状态C_t-1
相乘,决定哪些信息需要保留或遗忘。 -
输入门(Input Gate):输入门决定哪些新信息应该被存储在单元状态中。它首先通过一个sigmoid层决定哪些值需要更新,然后通过一个tanh层生成一个候选值向量
C_hat_t
。最后,将sigmoid层的输出与C_hat_t
相乘,得到需要添加到单元状态的新信息。 -
单元状态(Cell State):单元状态是LSTM网络中的关键,它记录着历史信息。新的单元状态是通过将旧的单元状态与遗忘门的输出相乘,再加上输入门决定的新信息来得到的。
-
输出门(Output Gate):输出门决定哪些信息应该被输出到LSTM单元的当前输出值
h_t
。它首先通过sigmoid层决定单元状态的哪些部分将被输出,然后将单元状态通过tanh层(将其值规范化到-1到1之间),最后将tanh层的输出与sigmoid层的输出相乘,得到最终的输出值h_t
。
(4)训练并生成结果
train = pd.read_csv('./train.csv')
test = pd.read_csv('./test.csv')
products = train['id'].unique()
predicted_df = pd.DataFrame()
for product in products:
print(train[train['id'] == product].index.tolist()[0])
product_df = train[train['id'] == product].copy()
sales = product_df['target'].values[::-1]
sales=sales.reshape(-1,1)
scaler = MinMaxScaler(feature_range=(0, 1))
sales_scaled = scaler.fit_transform(sales)
# 将数据拆分为输入序列和目标值
X, y = [], []
for i in range(len(sales_scaled) - 10):
X.append(sales_scaled[i:i+10, 0])
y.append(sales_scaled[i+10, 0])
X, y = np.array(X), np.array(y)
# 将数据重塑为LSTM模型所需的形状 (samples, time steps, features)
X = np.reshape(X, (X.shape[0], X.shape[1], 1))
# 构建LSTM模型
model = Sequential()
model.add(LSTM(units=50, return_sequences=True, input_shape=(X.shape[1], 1)))
model.add(LSTM(units=50))
model.add(Dense(units=1))
# 编译模型
model.compile(optimizer='adam', loss='mean_squared_error')
# 训练模型
model.fit(X, y, epochs=50, batch_size=32)
# 预测未来10天电力
future_dates = pd.date_range(start=1, periods=10, freq='W')
future_sales = []
for i in range(10):
input_data = sales_scaled[-10:].reshape(1, 10, 1)
predicted_sales = model.predict(input_data)
future_sales.append(predicted_sales[0, 0])
# 更新输入数据,加入新的预测值
sales_scaled = np.concatenate([sales_scaled, predicted_sales], axis=0)
# 反归一化
future_sales = scaler.inverse_transform(np.array(future_sales).reshape(-1, 1))
# 计算模型的性能指标
true_sales = product_df['target'].values[-10:]
mse = mean_squared_error(true_sales, future_sales)
mae = mean_absolute_error(true_sales, future_sales)
print(f"Product: {product}")
print(f"Mean Squared Error: {mse}")
print(f"Mean Absolute Error: {mae}")
dt_values = range(1, 11)
# # 创建预测数据的DataFrame
future_df = pd.DataFrame({'id': product, 'dt':dt_values ,'target': future_sales.flatten()})
print(future_df)
# # 将预测数据追加到原始数据框中
predicted_df = pd.concat([predicted_df, future_df], ignore_index=True)
predicted_df.to_csv('test.csv', index=False)
注:本模型将每个房间都构建了一个LSTM模型,属于最为暴力的解法,并没有使用房间类型这一关键元素,且属于神经网路模型,极其消耗时间,预计可能运行时间超过10个小时(用GPU可能会快一点,本篇未使用),结果在本篇文章提交时仍未跑完,可能结果惨不忍睹,仅起抛砖引玉的作用,欢迎各位大佬进行改进。
模型参考文章:https://blog.csdn.net/MacWx/article/details/134548578
标签:10,plt,target,AI,需求预测,sales,Datawhale,train,LSTM From: https://blog.csdn.net/weixin_61149295/article/details/140420305