【数学建模学习笔记】时间序列分析: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:准备工具(导入库)
就像做饭前要准备锅碗瓢盆,这里要导入处理数据、画图、建模型的 “工具包”:
# 处理数值和表格数据的工具
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 导入数据
# 从网上直接下载销量数据(不用自己找文件)
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),符合时间序列的标准格式。
# 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 之间”,这样模型训练时会更稳定、更快。
# 初始化缩放工具,设定缩放范围是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 年的销量)。
我们写一个函数自动生成这样的样本:
# 定义函数:把数据切成“输入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”的数据作为输入Xa = data[i:(i+time_step), 0]X.append(a)# 取“当前+time_step”的数据作为输出YY.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 + 一层输出” 的简单模型(足够应对基础预测任务):
# 初始化一个“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 年销量的关系”。
# 开始训练: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 这样的数值)。
# 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:画图对比(看模型准不准)
最直观的方式就是画图:把 “真实销量” 和 “模型预测的销量” 画在同一张图上,看两条线有多接近。
# 设置图的大小(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()
如果两条线几乎重合,说明模型预测得很准;如果有小差距也正常(入门模型能做到 “趋势一致” 就合格了)。
四、小白必懂总结
- LSTM 核心价值:处理时间数据时 “不健忘”,能记住长期规律(比如每年销量增长趋势)。
- 实战关键步骤:数据整理→缩放→做样本→搭模型→训练→预测→对比,一步都不能少。
- 不用纠结的点:公式、记忆单元数量、优化器细节,入门阶段先 “跟着做”,熟悉后再深究。
- 应用场景:除了销量预测,LSTM 还能做股价预测、气温预测、语言翻译(比如把中文句子翻译成英文,也是 “时间序列”)。