来自哔哩哔哩课程LSTM共享单车使用量预测
,属于多变量预测案例
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import os
import datetime
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import r2_score
import tensorflow as tf
from tensorflow.keras import Sequential, layers, utils, losses
from tensorflow.keras.callbacks import ModelCheckpoint, TensorBoard
import warnings
warnings.filterwarnings('ignore')
# 加载数据集
dataset = pd.read_csv("BikeShares.csv", parse_dates=['timestamp'], index_col=['timestamp'])
dataset.shape #数据集大小
dataset.head() #默认显示前5行
dataset.tail() #默认显示后5行
dataset.info() #数据集信息:总结的信息
dataset.describe() #数据集描述:描述最大值最小值等信息
通过可视化处理能直观地展现不同变量之间的关系
# 字段t1(气温)与字段cnt(单车使用量)之间的关系
plt.figure(figsize=(16,8))
sns.pointplot(x='t1', y='cnt', data=dataset) #使用'pointplot()'是'点-线'图
plt.show()
# 字段t2(体感温度)与字段cnt(单车使用量)之间的关系
plt.figure(figsize=(16,8))
sns.lineplot(x='t2', y='cnt', data=dataset) #使用'lineplot()'
plt.show()
|
|
# 特征数据集
X = dataset.drop(columns=['cnt'], axis=1)
# 标签数据集
y = dataset['cnt']
# 1 数据集分离: X_train, X_test
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False, random_state=666)
# 使用'train_test_split'函数进行数据集切分,切分比例为80%训练集,'shuffle=False'表示切分后不打乱顺序,'random_state'规定了数据的顺序
# 2 构造特征数据集
def create_dataset(X, y, seq_len=10):
features = []
targets = []
for i in range(0, len(X) - seq_len, 1):
data = X.iloc[i:i+seq_len] # 序列数据 利用'iloc'函数,取行
label = y.iloc[i+seq_len] # 标签数据
# 保存到features和labels
features.append(data)
targets.append(label)
# 返回
return np.array(features), np.array(targets)
# ① 构造训练特征数据集
train_dataset, train_labels = create_dataset(X_train, y_train, seq_len=10)
# ② 构造测试特征数据集
test_dataset, test_labels = create_dataset(X_test, y_test, seq_len=10)
# 3 构造批数据
def create_batch_dataset(X, y, train=True, buffer_size=1000, batch_size=128):
batch_data = tf.data.Dataset.from_tensor_slices((tf.constant(X), tf.constant(y))) # 数据封装,tensor类型
if train: # 训练集
return batch_data.cache().shuffle(buffer_size).batch(batch_size)
else: # 测试集
return batch_data.batch(batch_size)
# 训练批数据
train_batch_dataset = create_batch_dataset(train_dataset, train_labels)
# 测试批数据
test_batch_dataset = create_batch_dataset(test_dataset, test_labels, train=False)
# 模型搭建--版本1
model = Sequential([
layers.LSTM(units=256, input_shape=train_dataset.shape[-2:], return_sequences=True),# 这里input_shape可以直接写(10,8)
layers.Dropout(0.4), #舍去一部分神经元,保留一部分,符合LSTM定义
layers.LSTM(units=256, return_sequences=True),
layers.Dropout(0.3),
layers.LSTM(units=128, return_sequences=True),
layers.LSTM(units=32),
layers.Dense(1)
])
# 模型编译
model.compile(optimizer='adam',loss='mse')
checkpoint_file = "best_model.hdf5" #实际报错了,可以改为.ckpt
checkpoint_callback = ModelCheckpoint(filepath=checkpoint_file,
monitor='loss',
mode='min',
save_best_only=True,
save_weights_only=True)
# 模型训练
history = model.fit(train_batch_dataset,
epochs=30,
validation_data=test_batch_dataset,
callbacks=[tensorboard_callback, checkpoint_callback])
# 显示训练结果
plt.figure(figsize=(16,8))
plt.plot(history.history['loss'], label='train loss')
plt.plot(history.history['val_loss'], label='val loss')
plt.legend(loc='best')
plt.show()
test_preds = model.predict(test_dataset, verbose=1)
test_preds = test_preds[:, 0] # 获取列值
# 计算r2值
score = r2_score(test_labels, test_preds)
print("r^2 值为: ", score)
# 绘制 预测与真值结果
plt.figure(figsize=(16,8))
plt.plot(test_labels[:300], label="True value") #取前300个绘制曲线图
plt.plot(test_preds[:300], label="Pred value")
plt.legend(loc='best')
plt.show()