理论部分
在参加Datawhale AI夏令营的机器学习方向期间,我有幸参与了一个电力预测项目。
本项目的主要目标是利用机器学习技术,特别是LSTM(长短期记忆)网络,对电力消耗进行预测。通过分析历史数据,模型能够预测未来的电力需求,从而为电网运营商提供决策支持。
-
导入库:代码开始处导入了所需的库,包括数据处理库NumPy和Pandas,以及用于构建LSTM模型的Keras库。
import numpy as np
import pandas as pd
from keras.models import Sequential
from keras.layers import LSTM, RepeatVector, Dense
from keras.optimizers import Adam
-
读取数据:使用Pandas的
read_csv
函数读取训练数据集train.csv
和测试数据集test.csv
。
train_data = pd.read_csv('train.csv')
test_data = pd.read_csv('test.csv')
-
定义数据预处理函数:
-
preprocess_data
函数用于准备训练和测试数据。 -
数据按
id
列进行分组。 -
对于每个
id
,提取特定列(索引为3的列)的数据作为时间序列。 -
创建多个序列,每个序列长度为
look_back
,默认为100。 -
序列被反转,并且如果序列长度不足100,则用0填充。
-
训练数据集的标签
Y
是序列的一部分,同样进行反转。 -
测试数据集(OOT,Out-Of-Time)也被反转并用0填充以满足序列长度要求。
-
def preprocess_data(data, look_back=100):
data = data.groupby('id').apply(lambda x: x.iloc[:, 3].values)
data = np.array(data.tolist())
sequences = []
labels = []
for i in range(len(data)):
X, y = data[i][look_back:], data[i][look_back]
sequences.append(X[::-1])
labels.append(y[::-1])
sequences = np.array(sequences)
labels = np.array(labels)
sequences = np.pad(sequences, ((0, 0), (0, look_back - sequences.shape[1]), (0, 0)), mode='constant', constant_values=0)
labels = np.pad(labels, (0, look_back - labels.shape[1]), mode='constant', constant_values=0)
return sequences, labels
train_X, train_y = preprocess_data(train_data)
test_X = preprocess_data(test_data)[0]
-
定义模型构建函数:
-
build_model
函数用于构建LSTM模型。 -
模型包括一个LSTM层,用于学习时间序列数据的特征,以及一个重复向量层
RepeatVector
,用于复制上一个LSTM层的输出以供下一个LSTM层使用。 -
再次使用LSTM层和时间分布的密集层来预测序列的下一个值。
-
模型使用均方误差作为损失函数,并使用Adam优化器。
-
def build_model(look_back, n_features, n_output):
model = Sequential()
model.add(LSTM(50, activation='relu', input_shape=(look_back, n_features)))
model.add(RepeatVector(1))
model.add(LSTM(50, activation='relu'))
model.add(Dense(n_output))
model.compile(optimizer=Adam(0.001), loss='mse')
return model
-
构建和训练模型:
-
设置序列长度
look_back
、特征数n_features
和输出时间单位数n_output
。 -
调用
preprocess_data
函数预处理训练数据。 -
使用
build_model
函数构建模型。 -
使用模型的
fit
方法训练模型,指定迭代次数(epochs)和批量大小(batch_size)。
-
look_back = 100
n_features = 1
n_output = 1
train_X = train_X.reshape((-1, look_back, n_features))
model = build_model(look_back, n_features, n_output)
model.fit(train_X, train_y, epochs=50, batch_size=32)
-
进行预测:
-
使用训练好的模型对测试数据集进行预测
-
test_X = test_X.reshape((-1, look_back, n_features))
predictions = model.predict(test_X)
代码部分
# 假设predicted_values已经是模型预测的结果,并且是一个二维数组 (num_samples, n_output)
# 并且test DataFrame中有一个'id'列
# 确保predicted_values是浮点数类型,如果不是,进行转换
predicted_values = predicted_values.astype('float64')
# 将predicted_values转换为一维数组,以便于作为列添加到DataFrame中
predicted_values_1d = predicted_values.flatten()
# 将预测结果作为新列添加到test DataFrame中
test['predictions'] = predicted_values_1d
# 对每个id进行操作,为每个id生成1到10的日期占位符
def assign_dt(group):
return np.tile(np.arange(1, 11), len(group) // 10)[:len(group)]
# 应用函数为每个id生成日期占位符
test['dt'] = test.groupby('id').apply(assign_dt)
# 现在test DataFrame包含了id, dt (1-10), 和predictions列
# 保存每个id的预测结果到单独的CSV文件
test.groupby('id').apply(lambda x:
x[['id', 'dt', 'predictions']].to_csv(f'predictions_id_{x.name}.csv', index=False)
).reset_index(drop=True)
# 或者,将所有预测结果保存到一个CSV文件中
test[['id', 'dt', 'predictions']].to_csv('all_predictions_with_dt.csv', index=False)
通过这次项目,我深刻体会到了机器学习在实际问题中的应用潜力,我感受到了LSTM网络在处理时间序列数据方面表现出色,但同时也需要合理的数据预处理和模型调优,以后再接再厉。