长沙做网站设计的公司,建立百度网站,上海环球金融中心大厦图片,开封市做网站的公司Hi#xff0c;大家好#xff0c;我是半亩花海。本实验基于汽车销量时序数据#xff0c;使用LSTM网络#xff08;长短期记忆网络#xff09;构建时间序列预测模型。通过数据预处理、模型训练与评估等完整流程#xff0c;验证LSTM在短期时序预测中的有效性。 目录
一、实验… Hi大家好我是半亩花海。本实验基于汽车销量时序数据使用LSTM网络长短期记忆网络构建时间序列预测模型。通过数据预处理、模型训练与评估等完整流程验证LSTM在短期时序预测中的有效性。 目录
一、实验目标
二、实验原理
三、实验环境
四、实验步骤
1. 数据预处理
2. 构建时间序列数据集
3. 模型构建与训练
4. 预测与反归一化
5. 结果可视化
6. 模型评估
五、实验分析
1. 评估指标解读
2. 可能的原因分析
3. 改进方法
六、完整代码 一、实验目标
本实验基于汽车销量时序数据构建LSTM神经网络模型实现对时间序列数据的预测并通过可视化和评估指标验证模型性能。实验目标包括
掌握时间序列数据的预处理方法理解LSTM网络的工作原理构建端到端的时序预测模型评估模型预测性能 二、实验原理
1. 核心算法LSTM网络
长短期记忆 (Long Short-Term Memory, LSTM) 是一种时间递归神经网络(RNN)它是一种基于机器学习理论的循环网络时间序列预测方法。该模型可有效处理并解决RNN中人为很难实现的延长时间任务的问题并预测时间序列中间隔和延迟非常长的重要事件同时削减了RNN中梯度消失问题对预测研究的影响总的来说LSTM模型是一种特殊的RNN循环神经网络。
RNN循环神经网络结构如图所示。 LSTM的网络结构大概为单层LSTM5个神经元 全连接层输入形状为(时间步长1, 特征数1)。LSTM网络结构如图所示。 1输入门(Input gate)的计算 2遗忘门(Forget gate)的计算 3候选记忆单元的计算 4记忆单元状态更新的计算 5输出门的计算 6隐藏状态(output)的计算 2. 关键技术实现
数据归一化使用MinMaxScaler将数据缩放到[0,1]区间加速模型收敛。时间序列建模通过滑动窗口法look_back1将数据转换为监督学习格式每个样本包含1个时间步的历史数据。模型训练采用Adam优化器和均方误差损失函数训练150轮批量大小为2。 三、实验环境
项目配置/版本Python3.83.8.20TensorFlow2.10.0主要库numpy1.21.6, matplotlib3.6.3, pandas1.4.4, scikit-learn1.1.3, pillow10.4.0硬件环境CPU/GPU 四、实验步骤
1. 数据预处理
1数据加载与清洗
# 加载数据取第2列跳过末尾3行
dataframe pd.read_csv(D:\Python_demo\Time Series\LSTM\car.csv, usecols[1], skipfooter3)
选取CSV文件第2列数据销量数据跳过末尾3行异常数据转换为float32类型保证数值精度
2数据归一化
dataset scaler.fit_transform(dataframe.values.astype(float32))
使用MinMaxScaler进行0-1归一化消除量纲影响加速模型收敛公式
3数据集划分
# 划分训练集与测试集8:2
train_size int(len(dataset) * 0.80)
trainlist, testlist dataset[:train_size], dataset[train_size:]
按8:2比例划分训练/测试集保持时序连续性避免随机划分
2. 构建时间序列数据集
def create_dataset(dataset, look_back):dataX, dataY [], []for i in range(len(dataset) - look_back - 1):a dataset[i:(i look_back)] # 取look_back长度的历史数据dataX.append(a)dataY.append(dataset[i look_back]) # 预测下一个时间点的值return np.array(dataX), np.array(dataY)# 设置时间步长这里使用1步预测
look_back 1
trainX, trainY create_dataset(trainlist, look_back)
testX, testY create_dataset(testlist, look_back)# 调整输入格式LSTM需要[样本数, 时间步, 特征数]的3D张量
trainX np.reshape(trainX, (trainX.shape[0], look_back, 1))
testX np.reshape(testX, (testX.shape[0], look_back, 1))滑动窗口法 look_back1表示用当前时刻数据预测下一时刻值。输入维度 LSTM要求输入为3D张量此处形状为(样本数, 1, 1)。
3. 模型构建与训练
# 构建LSTM模型
model Sequential() # 创建序列模型
model.add(LSTM(5, input_shape(look_back, 1))) # 添加LSTM层5个神经元输入形状为(时间步1, 特征数1)
model.add(Dense(1)) # 添加全连接输出层
model.compile(lossmean_squared_error, optimizeradam) # 编译模型均方误差损失Adam优化器
model.fit(trainX, trainY, epochs150, batch_size2, verbose2) # 训练模型100轮批量大小2损失函数 均方误差MSE适用于回归任务。优化器 Adam动态调整学习率平衡收敛速度与精度。超参数选择 小批量batch_size2训练适合小数据集。
4. 预测与反归一化
# 对训练集和测试集进行预测
trainPredict model.predict(trainX)
testPredict model.predict(testX)# 反归一化将预测结果还原到原始数据范围
trainPredict scaler.inverse_transform(trainPredict)
trainY scaler.inverse_transform(trainY)
testPredict scaler.inverse_transform(testPredict)
testY scaler.inverse_transform(testY)
反归一化 将预测结果还原到原始数据范围便于计算真实误差。
5. 结果可视化
# 绘制训练集结果
plt.figure(figsize(10, 6))
plt.plot(trainY, label训练实际数据, color#FF3B1D, marker*, linestyle--)
plt.plot(trainPredict[1:], label训练预测数据, color#F9A602, marker*, linestyle--)
plt.title(训练集预测效果)
plt.xlabel(时间步)
plt.ylabel(数值)
plt.legend()
plt.show()# 绘制测试集结果
plt.figure(figsize(10, 6))
xx np.linspace(0, len(testY), len(testY))
plt.plot(testY, label测试实际数据, color#FF3B1D, marker*, linestyle--)
plt.plot(testPredict, label测试预测数据, color#F9A602, marker*, linestyle--)
plt.title(测试集预测效果)
plt.xlabel(时间步)
plt.ylabel(数值)
plt.xlim(0, 18.5)
plt.ylim(0, 100)
plt.legend()# 添加数据标签
for x, y in zip(xx, testY):plt.text(x, y 0.3, int(y), hacenter, vabottom, fontsize10.5)
for x, y in zip(xx, testPredict):plt.text(x, y 0.3, int(y), hacenter, vabottom, fontsize10.5)plt.show()坐标轴限制 根据测试集数据范围手动设置避免自动缩放失真。数据标签 通过plt.text()标注具体数值增强可读性。 6. 模型评估
指标公式MAEMean Absolute Error平均绝对误差RMSERoot Mean Squared Error均方根误差R²Coefficient of Determination决定系数
# 计算评估指标
mae mean_absolute_error(testPredict, testY)
rmse np.sqrt(mean_squared_error(testPredict, testY))
r2 r2_score(testPredict, testY)print(测试集评估指标:)
print(MAE: %.3f % mae)
print(RMSE: %.3f % rmse)
print(R²: %.3f % r2)指标 计算结果 意义 MAE 6.397 预测值与真实值的平均绝对误差表明平均预测误差约4.85个单位 RMSE 6.818 对较大误差更敏感的均方根误差 R² -25.777 模型解释了一定的数据方差说明模型的解释力 五、实验分析
1. 评估指标解读
1MAEMean Absolute Error平均绝对误差
值6.397解释平均绝对误差表示预测值与真实值之间的平均差距为6.397。评价MAE值本身并不算特别大但需要结合数据的实际范围来判断。如果汽车销量数据的范围是几十到几百则6.397的误差可能偏高。
2RMSERoot Mean Squared Error均方根误差
值6.818解释均方根误差对较大的误差更敏感其值比MAE稍高说明可能存在一些较大的预测偏差。评价RMSE略高于MAE说明误差分布中存在一些较大的异常值。
3R²Coefficient of Determination决定系数
值-25.777解释R²衡量模型对数据方差的解释能力理想值为1负值表示模型的预测效果比直接用均值预测还要差。评价 R²为负数是一个严重的警告信号说明模型几乎完全无法捕捉数据的趋势甚至可能在某些情况下“反向预测”。
2. 可能的原因分析
1数据质量问题
①数据量不足如果训练数据太少模型可能无法学习到有效的模式。
②数据噪声过多汽车销量数据可能存在大量随机波动或异常值导致模型难以拟合。
③非平稳性时间序列数据可能存在趋势或季节性成分而模型未对其进行处理。
2模型设计问题
①LSTM结构过于简单
单层LSTM仅5个神经元可能不足以捕捉复杂的时序关系。时间步长look_back1限制了模型利用历史信息的能力。
②超参数设置不当
训练轮次epochs150可能过多或过少。批量大小batch_size2可能导致梯度更新不稳定。
3数据预处理问题
①归一化范围不合适虽然使用了MinMaxScaler但如果数据分布不均匀归一化可能放大噪声。
②滑动窗口法不足look_back1仅使用最近一个时间点的数据进行预测可能忽略长期依赖关系。
4测试集划分问题
①训练集和测试集分布不一致如果测试集包含了训练集中未见过的模式如突然的销量激增或下降模型可能表现不佳。
②数据泄露确保测试集数据没有被意外用于训练。
3. 改进方法
1数据质量优化
①检查数据完整性 确认数据无缺失值或异常值并剔除明显的噪声点。
②平滑处理 对原始数据进行移动平均或其他平滑操作减少短期波动的影响。
③分解时间序列 使用STL分解等方法提取趋势和季节性成分分别建模。
2模型结构调整
①增加LSTM层数和神经元数量
model.add(LSTM(50, return_sequencesTrue, input_shape(look_back, 1))) # 第一层LSTM
model.add(LSTM(50)) # 第二层LSTM
model.add(Dense(1)) # 输出层 我后续只修改了这一项得出结果如下感觉只有训练集效果稍微好了一些。 ②调整时间步长 尝试look_back3或更高值以利用更多历史信息。
③添加Dropout层 防止过拟合例如
from tensorflow.keras.layers import Dropout
model.add(Dropout(0.2))
3超参数调优
①学习率调整 尝试不同的学习率如0.001或0.01。
②批量大小优化 将batch_size调整为更大的值如16或32。
③早停机制 避免过拟合使用EarlyStopping回调函数
from tensorflow.keras.callbacks import EarlyStopping
early_stopping EarlyStopping(monitorval_loss, patience10)
model.fit(trainX, trainY, epochs200, batch_size16, validation_split0.2, callbacks[early_stopping])
4数据预处理改进
①标准化代替归一化 如果数据分布较广可以尝试StandardScaler均值为0标准差为1。
②特征工程 引入额外特征如节假日、促销活动等增强模型输入。
5测试集验证
①交叉验证 使用时间序列交叉验证TimeSeriesSplit评估模型性能。
②重新划分数据集 确保训练集和测试集分布一致避免数据泄露。 六、完整代码
#!/usr/bin/env python
# -*- coding:utf-8 -*-Project : Time Series/LSTM/LSTM_car
File : LSTM_car.py
IDE : PyCharm
Author : 半亩花海
Date : 2025/03/10 17:36#
# 导入必要库
#
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.layers import Dense, LSTM
from tensorflow.keras.models import Sequential, load_model
import tensorflow as tf# 禁用eager模式兼容旧版本TensorFlow
tf.compat.v1.disable_eager_execution()# 设置中文字体显示
matplotlib.rcParams[font.sans-serif] [Microsoft YaHei]
matplotlib.rcParams[font.serif] [Microsoft YaHei]
matplotlib.rcParams[axes.unicode_minus] False#
# 数据预处理
#
# 加载数据取第2列数据跳过末尾3行
dataframe pd.read_csv(rD:\Python_demo\Time Series\LSTM\car.csv, usecols[1], enginepython, skipfooter3)
dataset dataframe.values# 数据类型转换
dataset dataset.astype(float32)# 数据归一化0-1范围
scaler MinMaxScaler(feature_range(0, 1))
dataset scaler.fit_transform(dataset)# 划分训练集和测试集8:2比例
train_size int(len(dataset) * 0.80)
trainlist dataset[:train_size]
testlist dataset[train_size:]#
# 构建时间序列数据集
#
def create_dataset(dataset, look_back):将时间序列数据转换为监督学习格式:param dataset: 原始数据集:param look_back: 时间步长使用多少历史数据预测:return: 输入特征X和目标值YdataX, dataY [], []for i in range(len(dataset) - look_back - 1):a dataset[i:(i look_back)] # 取look_back长度的历史数据dataX.append(a)dataY.append(dataset[i look_back]) # 预测下一个时间点的值return np.array(dataX), np.array(dataY)# 设置时间步长这里使用1步预测
look_back 1
trainX, trainY create_dataset(trainlist, look_back)
testX, testY create_dataset(testlist, look_back)# 调整输入格式LSTM需要[样本数, 时间步, 特征数]的3D张量
trainX np.reshape(trainX, (trainX.shape[0], look_back, 1))
testX np.reshape(testX, (testX.shape[0], look_back, 1))#
# 构建和训练LSTM模型
#
# 构建LSTM模型
model Sequential() # 创建序列模型
model.add(LSTM(5, input_shape(look_back, 1))) # 添加LSTM层5个神经元输入形状为(时间步1, 特征数1)
model.add(Dense(1)) # 添加全连接输出层
model.compile(lossmean_squared_error, optimizeradam) # 编译模型均方误差损失Adam优化器
model.fit(trainX, trainY, epochs150, batch_size2, verbose2) # 训练模型100轮批量大小2# 保存并加载模型
model_path rD:\Python_demo\Time Series\LSTM\lstm_model.h5
model.save(model_path)
model load_model(model_path)#
# 预测与反归一化
#
# 对训练集和测试集进行预测
trainPredict model.predict(trainX)
testPredict model.predict(testX)# 反归一化将预测结果还原到原始数据范围
trainPredict scaler.inverse_transform(trainPredict)
trainY scaler.inverse_transform(trainY)
testPredict scaler.inverse_transform(testPredict)
testY scaler.inverse_transform(testY)#
# 可视化结果
#
# 绘制训练集结果
plt.figure(figsize(10, 6))
plt.plot(trainY, label训练实际数据, color#FF3B1D, marker*, linestyle--)
plt.plot(trainPredict[1:], label训练预测数据, color#F9A602, marker*, linestyle--)
plt.title(训练集预测效果)
plt.xlabel(时间步)
plt.ylabel(数值)
plt.legend()
plt.show()# 绘制测试集结果
plt.figure(figsize(10, 6))
xx np.linspace(0, len(testY), len(testY))
plt.plot(testY, label测试实际数据, color#FF3B1D, marker*, linestyle--)
plt.plot(testPredict, label测试预测数据, color#F9A602, marker*, linestyle--)
plt.title(测试集预测效果)
plt.xlabel(时间步)
plt.ylabel(数值)
plt.xlim(0, 18.5)
plt.ylim(0, 100)
plt.legend()# 添加数据标签
for x, y in zip(xx, testY):plt.text(x, y 0.3, int(y), hacenter, vabottom, fontsize10.5)
for x, y in zip(xx, testPredict):plt.text(x, y 0.3, int(y), hacenter, vabottom, fontsize10.5)plt.show()#
# 模型评估
#
# 计算评估指标
mae mean_absolute_error(testPredict, testY)
rmse np.sqrt(mean_squared_error(testPredict, testY))
r2 r2_score(testPredict, testY)print(测试集评估指标:)
print(MAE: %.3f % mae)
print(RMSE: %.3f % rmse)
print(R²: %.3f % r2)