【数学建模学习笔记】时间序列分析:LSTM

零基础小白入门:LSTM 时间序列预测

如果你是刚接触机器学习的 "小白",不用怕!这篇总结会用最通俗的语言,把 LSTM 模型、时间序列预测的核心逻辑,以及完整实战流程拆解开,让你能一步步看懂、甚至跟着做。

一、先搞懂:LSTM 到底是什么?

你可以把 LSTM 想象成一个 "有记忆的智能计算器",专门处理和 "时间相关" 的数据(比如每年的销量、每天的气温、每小时的股票价格)。

1. 为什么需要 LSTM?

普通的 "计算器"(比如传统神经网络)处理时间数据时会 "忘事"------ 比如用前 10 年的销量预测第 11 年时,它会慢慢忘记前 1 年、前 2 年的数据,这就是 "梯度消失" 问题。

而 LSTM 通过 "门控机制"(像家里的大门、储物间门),能 "记住重要的旧数据,忘记没用的",比如它能记住 "每年春节前销量会涨" 这个长期规律,不会中途忘记。

2. LSTM 的核心:3 个 "门"+1 个 "记忆箱"

不用记复杂公式,用 "家庭管理" 类比就能懂:

  • 遗忘门:像 "清理旧物"------ 决定哪些过去的记忆(比如 5 年前的异常低销量)该丢掉,哪些该留下。
  • 输入门:像 "收纳新物"------ 决定今天的新数据(比如今年的促销活动数据)哪些值得放进 "记忆箱"。
  • 输出门:像 "拿东西用"------ 需要预测时,从 "记忆箱" 里拿出有用的记忆,结合新数据算出结果。
  • 记忆箱(细胞状态):就是家里的 "储物间",专门存有用的长期记忆,是 LSTM "不健忘" 的关键。

二、我们要做什么?实战目标

这次实战的任务很简单:用 1985 年到 2020 年的 "年度销量数据",训练 LSTM 模型,让它学会 "用前 3 年的销量预测第 4 年的销量",最后对比模型预测值和真实销量,看它准不准。

三、零基础也能跟的实战步骤(Python)

所有代码都有 "小白版解释",你跟着复制运行就行,不用懂复杂语法。

步骤 1:准备工具(导入库)

就像做饭前要准备锅碗瓢盆,这里要导入处理数据、画图、建模型的 "工具包":

python 复制代码
# 处理数值和表格数据的工具
import numpy as np
import pandas as pd
# 画图的工具
import matplotlib.pyplot as plt
# 数据缩放的工具(让数据变规整,模型好训练)
from sklearn.preprocessing import MinMaxScaler
# 建LSTM模型的工具
from keras.models import Sequential
from keras.layers import LSTM, Dense

步骤 2:加载并整理数据

我们用的是 "1985-2020 年年度销量表",先把数据拿到手,再整理成模型能看懂的格式。

2.1 导入数据
python 复制代码
# 从网上直接下载销量数据(不用自己找文件)
df = pd.read_excel('https://labfile.oss.aliyuncs.com/courses/40611/%E6%97%B6%E9%97%B4%E5%BA%8F%E5%88%97%E5%88%86%E6%9E%90%28ARIMA%29.xlsx')
# 看前5行数据长什么样(确认数据没问题)
df.head()

运行后会看到这样的表格:

年份 年度销量
1985 100.0
1986 101.6
1987 103.3
1988 111.5
1989 116.5
2.2 给数据 "改名 + 换格式"
  • 中文列名(年份、年度销量)改成英文(Year、Annual_Sales),避免模型出错;
  • 把 "年份" 设为 "索引"(相当于给数据按时间排序,方便后续分析);
  • 把年份格式改成 "日期型"(比如 1985→1985-01-01),符合时间序列的标准格式。
python 复制代码
# 1. 中文列名转英文
column_mapping = {'年份': 'Year', '年度销量': 'Annual_Sales'}
df.rename(columns=column_mapping, inplace=True)

# 2. 把Year设为索引(按时间排序)
df.set_index('Year', inplace=True)

# 3. 年份转成日期格式
df.index = pd.to_datetime(df.index, format='%Y')

# 再看一眼整理后的数据
df.head()

整理后的数据会变成这样(更规整了):

Year Annual_Sales
1985-01-01 100.0
1986-01-01 101.6
1987-01-01 103.3
1988-01-01 111.5
1989-01-01 116.5

步骤 3:数据预处理(关键!让模型 "吃得舒服")

模型像个 "挑食的孩子"------ 不喜欢太大或太小的数据(比如销量 100 和销量 2000 混在一起会让它混乱),所以要先做两件事:数据缩放制作训练样本

3.1 数据缩放:把数据缩到 [0,1] 之间

用 "MinMaxScaler" 工具,把所有销量数据从 "原来的范围(比如 100-2000)" 压缩到 "0 到 1 之间",这样模型训练时会更稳定、更快。

python 复制代码
# 初始化缩放工具,设定缩放范围是0到1
scaler = MinMaxScaler(feature_range=(0, 1))
# 对销量数据进行缩放(只缩放"Annual_Sales"这一列)
scaled_data = scaler.fit_transform(df[['Annual_Sales']])

缩放后的数据会变成类似这样:100.0→0.0,101.6→0.01,103.3→0.02(具体数值不用记,知道是 "规整化" 就行)。

3.2 制作训练样本:"用前 3 年预测第 4 年"

模型需要明确的 "输入" 和 "输出":

  • 输入(X):前 3 年的销量(比如 1985、1986、1987 年的销量);
  • 输出(Y):第 4 年的销量(比如 1988 年的销量)。

我们写一个函数自动生成这样的样本:

python 复制代码
# 定义函数:把数据切成"输入X"和"输出Y"
def create_dataset(data, time_step=1):
    X, Y = [], []  # X存输入(前n年),Y存输出(第n+1年)
    # 循环切分数据(避免越界)
    for i in range(len(data)-time_step-1):
        # 取"当前位置到当前+time_step"的数据作为输入X
        a = data[i:(i+time_step), 0]
        X.append(a)
        # 取"当前+time_step"的数据作为输出Y
        Y.append(data[i + time_step, 0])
    return np.array(X), np.array(Y)

# 设定"用前3年预测第4年",所以time_step=3
time_step = 3
X, Y = create_dataset(scaled_data, time_step)

# 最后一步:把X改成LSTM要求的格式
# LSTM需要"[样本数, 时间步, 特征数]"的三维格式(固定要求,照做就行)
X = X.reshape(X.shape[0], X.shape[1], 1)

举个例子:

  • 第一个 X 样本:[1985 年销量(缩放后), 1986 年销量(缩放后), 1987 年销量(缩放后)]
  • 第一个 Y 样本:1988 年销量(缩放后)

步骤 4:搭建 LSTM 模型(像搭积木一样简单)

用 Keras 工具搭模型,这次我们搭一个 "两层 LSTM + 一层输出" 的简单模型(足够应对基础预测任务):

python 复制代码
# 初始化一个"Sequential"模型(就是"按顺序叠层"的模型)
model = Sequential()

# 第一层LSTM:50个"记忆单元",return_sequences=True表示要给下一层传数据
model.add(LSTM(50, return_sequences=True, input_shape=(time_step, 1)))

# 第二层LSTM:还是50个记忆单元,return_sequences=False表示不用给下一层传(因为下一层是输出层)
model.add(LSTM(50, return_sequences=False))

# 输出层:Dense(1)表示输出1个结果(就是预测的第4年销量)
model.add(Dense(1))

# 告诉模型"怎么学":用adam优化器(常用、好用),用均方误差(MSE)当损失函数(衡量预测值和真实值的差距)
model.compile(optimizer='adam', loss='mean_squared_error')

不用纠结 "50 个记忆单元" 是什么 ------ 可以理解为 "模型的思考能力强弱",50 是入门级的合理值,不用改。

步骤 5:训练模型(让模型 "学习规律")

训练就是让模型反复看 "输入 X→输出 Y" 的样本,慢慢学会 "前 3 年销量和第 4 年销量的关系"。

python 复制代码
# 开始训练:X是输入,Y是输出
# epochs=100:让模型看100遍所有样本(看越多遍,学得越熟,但也可能"学偏")
# batch_size=1:每次学1个样本就调整一次(小批量,适合小数据)
# verbose=1:训练时显示进度(能看到每一遍的损失值)
model.fit(X, Y, epochs=100, batch_size=1, verbose=1)

训练过程中会看到 "loss 值"(损失值)------ 比如从 0.09 慢慢降到 0.003,loss 越小,说明模型预测得越准(像学生做题,错题越来越少)。

步骤 6:用模型预测 + 还原真实值

训练好后,让模型用之前的 "输入 X"(前 3 年销量)预测 "输出 Y"(第 4 年销量),但要注意:模型输出的是 "缩放后的预测值"(0-1 之间),需要还原成 "真实销量"(比如 100、200 这样的数值)。

python 复制代码
# 1. 用训练好的模型预测
train_predict = model.predict(X)

# 2. 把预测值从"0-1"还原成真实销量(用之前的scaler工具逆运算)
train_predict = scaler.inverse_transform(train_predict)

# 3. 把原来的输出Y(缩放后)也还原成真实销量(方便后续对比)
Y_actual = scaler.inverse_transform([Y])

步骤 7:画图对比(看模型准不准)

最直观的方式就是画图:把 "真实销量" 和 "模型预测的销量" 画在同一张图上,看两条线有多接近。

python 复制代码
# 设置图的大小(10,6),方便看
plt.figure(figsize=(10, 6))

# 画真实销量线:蓝色,标签"Real"
plt.plot(df.index[:len(Y)], Y_actual[0], label='Real Sales', color='blue')

# 画预测销量线:红色,标签"Prediction"
plt.plot(df.index[:len(Y)], train_predict[:, 0], label='Predicted Sales', color='red')

# 加图例(区分两条线)
plt.legend()

# 显示图
plt.show()

如果两条线几乎重合,说明模型预测得很准;如果有小差距也正常(入门模型能做到 "趋势一致" 就合格了)。

四、小白必懂总结

  1. LSTM 核心价值:处理时间数据时 "不健忘",能记住长期规律(比如每年销量增长趋势)。
  2. 实战关键步骤:数据整理→缩放→做样本→搭模型→训练→预测→对比,一步都不能少。
  3. 不用纠结的点:公式、记忆单元数量、优化器细节,入门阶段先 "跟着做",熟悉后再深究。
  4. 应用场景:除了销量预测,LSTM 还能做股价预测、气温预测、语言翻译(比如把中文句子翻译成英文,也是 "时间序列")。
相关推荐
Tina表姐7 小时前
(E题|AI 辅助智能体测)2025年高教杯全国大学生数学建模国赛解题思路|完整代码论文集合
人工智能·数学建模
热心网友俣先生9 小时前
2025年数学建模国赛C题超详细解题思路
c语言·开发语言·数学建模
咸甜适中9 小时前
rust语言 (1.88) egui (0.32.1) 学习笔记(逐行注释)(二十四)窗口颜色、透明度、居中显示
笔记·学习·rust·egui
北冥电磁电子智能10 小时前
江协科技STM32学习笔记补充之004 基于XC6206P332MR(Torex)的5V到3.3V的电压转换电路分析
科技·stm32·学习
DS数模10 小时前
2025高教社杯国赛数学建模选题建议+初步分析
数学建模·数学建模国赛·2025数学建模国赛·2025国赛·2025高教社杯·国赛选题建议
DS数模10 小时前
2025国赛B题保姆级教程思路分析 碳化硅外延层厚度的确定
开发语言·数学建模·2025数学建模·2025数学建模国赛·2025国赛·2025高教社杯数学建模·2025国赛b题
程序员Xu10 小时前
【LeetCode热题100道笔记】轮转数组
笔记·算法·leetcode
群联云防护小杜10 小时前
服务器异常负载排查手册 · 隐蔽进程篇
运维·服务器·前端·数据库·笔记·sql·tcp/ip
赤月幼狼11 小时前
elasticsearch学习(五)文档CRUD
学习·elasticsearch