基于Python的人工智能应用案例系列(15):LSTM酒类销售预测

在本篇文章中,我们将使用时间序列数据分析技术,基于美国联邦储备经济数据库(FRED)中的酒类销售数据,使用LSTM(长短期记忆网络)进行未来销售量的预测。本案例展示了如何构建LSTM模型,训练模型进行时间序列预测,并使用历史数据进行模型的评估与未来预测。

1. 加载数据

首先,我们加载酒类销售数据,该数据集包含了从1992年到2019年的月度销售记录。

python 复制代码
import pandas as pd

# 加载数据集
df = pd.read_csv('../data/Alcohol_Sales.csv', index_col=0, parse_dates=True)

# 查看数据长度
len(df)

# 清理数据,移除空值
df.dropna(inplace=True)
len(df)

# 查看前5行数据
df.head()

# 查看最后5行数据
df.tail()

2. EDA:时间序列数据可视化

接下来,我们将数据进行可视化,以便更好地理解时间序列趋势。

python 复制代码
import matplotlib.pyplot as plt

plt.figure(figsize=(12,4))
plt.title('Beer, Wine, and Alcohol Sales')
plt.ylabel('Sales (millions of dollars)')
plt.grid(True)
plt.autoscale(axis='x',tight=True)
plt.plot(df['S4248SM144NCEN'])
plt.show()

3. 特征提取与数据准备

我们将数据分为训练集和测试集,分别用于模型训练和评估。训练集将被归一化为-1到1之间的值,以提高训练效率。

python 复制代码
import numpy as np
from sklearn.preprocessing import MinMaxScaler

# 提取数据
y = df['S4248SM144NCEN'].values.astype(float)

# 定义测试集大小
test_size = 12

# 划分训练集和测试集
train_set = y[:-test_size]
test_set  = y[-test_size:]

# 实例化归一化工具
scaler = MinMaxScaler(feature_range=(-1, 1))

# 归一化训练集
train_norm = scaler.fit_transform(train_set.reshape(-1, 1))

# 转换为张量
import torch
train_norm = torch.FloatTensor(train_norm).view(-1)

# 定义窗口大小
window_size = 12

# 创建输入数据
def input_data(seq,ws):
    out = []
    L = len(seq)
    for i in range(L-ws):
        window = seq[i:i+ws]
        label = seq[i+ws:i+ws+1]
        out.append((window,label))
    return out

train_data = input_data(train_norm, window_size)

4. 构建LSTM模型

接下来,我们定义一个包含LSTM层的神经网络模型。

python 复制代码
import torch.nn as nn

class LSTMnetwork(nn.Module):
    def __init__(self, input_size=1, hidden_size=100, output_size=1):
        super().__init__()
        self.hidden_size = hidden_size
        self.lstm = nn.LSTM(input_size, hidden_size)
        self.linear = nn.Linear(hidden_size, output_size)
        self.hidden = (torch.zeros(1, 1, self.hidden_size),
                       torch.zeros(1, 1, self.hidden_size))

    def forward(self, seq):
        lstm_out, self.hidden = self.lstm(seq.view(len(seq), 1, -1), self.hidden)
        pred = self.linear(lstm_out.view(len(seq), -1))
        return pred[-1]  # 我们只需要最后一个预测值

5. 训练模型

我们将使用均方误差损失函数(MSE)和Adam优化器来训练模型。

python 复制代码
torch.manual_seed(101)
model = LSTMnetwork()

criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 训练模型
epochs = 100

for epoch in range(epochs):
    for seq, y_train in train_data:
        optimizer.zero_grad()
        model.hidden = (torch.zeros(1, 1, model.hidden_size),
                        torch.zeros(1, 1, model.hidden_size))
        y_pred = model(seq)
        loss = criterion(y_pred, y_train)
        loss.backward()
        optimizer.step()

    print(f'Epoch: {epoch+1:2} Loss: {loss.item():10.8f}')

6. 进行预测并与测试集比较

模型训练完毕后,我们使用模型对未来12个月的数据进行预测,并与测试集进行对比。

python 复制代码
future = 12

# 使用最后一个训练窗口的值进行预测
preds = train_norm[-window_size:].tolist()

model.eval()
for i in range(future):
    seq = torch.FloatTensor(preds[-window_size:])
    with torch.no_grad():
        model.hidden = (torch.zeros(1, 1, model.hidden_size),
                        torch.zeros(1, 1, model.hidden_size))
        preds.append(model(seq).item())

# 反归一化预测结果
true_predictions = scaler.inverse_transform(np.array(preds[window_size:]).reshape(-1, 1))

# 可视化预测结果
import numpy as np

x = np.arange('2018-02-01', '2019-02-01', dtype='datetime64[M]').astype('datetime64[D]')

plt.figure(figsize=(12,4))
plt.title('Beer, Wine, and Alcohol Sales')
plt.ylabel('Sales (millions of dollars)')
plt.grid(True)
plt.plot(df['S4248SM144NCEN'])
plt.plot(x,true_predictions)
plt.show()

7. 预测未来数据

我们将模型应用于整个数据集,并预测未来12个月的销售数据。

python 复制代码
# 训练整个数据集并预测未来
epochs = 100

# 归一化整个数据集
y_norm = scaler.fit_transform(y.reshape(-1, 1))
y_norm = torch.FloatTensor(y_norm).view(-1)
all_data = input_data(y_norm, window_size)

for epoch in range(epochs):
    for seq, y_train in all_data:
        optimizer.zero_grad()
        model.hidden = (torch.zeros(1, 1, model.hidden_size),
                        torch.zeros(1, 1, model.hidden_size))
        y_pred = model(seq)
        loss = criterion(y_pred, y_train)
        loss.backward()
        optimizer.step()

# 预测未来12个月数据
future = 12
preds = y_norm[-window_size:].tolist()

model.eval()
for i in range(future):
    seq = torch.FloatTensor(preds[-window_size:])
    with torch.no_grad():
        model.hidden = (torch.zeros(1, 1, model.hidden_size),
                        torch.zeros(1, 1, model.hidden_size))
        preds.append(model(seq).item())

# 反归一化预测值并可视化
true_predictions = scaler.inverse_transform(np.array(preds).reshape(-1, 1))

x = np.arange('2019-02-01', '2020-02-01', dtype='datetime64[M]').astype('datetime64[D]')

plt.figure(figsize=(12,4))
plt.title('Beer, Wine, and Alcohol Sales')
plt.ylabel('Sales (millions of dollars)')
plt.grid(True)
plt.plot(df['S4248SM144NCEN'])
plt.plot(x,true_predictions[window_size:])
plt.show()

结语

在本篇案例中,我们通过LSTM模型对美国酒类销售的时间序列数据进行了分析和预测。通过归一化处理、模型训练、测试集验证以及未来趋势预测,我们可以看到LSTM模型能够有效捕捉数据的时间依赖性,进而在一定程度上准确预测未来的销售趋势。虽然我们的模型表现较好,但仍有一些误差,可以通过调整模型参数、增加训练数据或采用其他高级算法进一步优化。

本案例展示了LSTM在时间序列预测中的应用,证明了其在捕捉长期依赖性和模式识别中的强大能力。对于需要预测趋势、销售额、库存等的商业决策场景,LSTM提供了可靠的解决方案。未来的工作中,我们可以探索更多模型的改进和应用场景,以提升预测的准确性和实用性。

通过本案例的学习,希望您对时间序列预测和LSTM网络有了更深入的理解,并能将其应用到更多实际问题中。

如果你觉得这篇博文对你有帮助,请点赞、收藏、关注我,并且可以打赏支持我!

欢迎关注我的后续博文,我将分享更多关于人工智能、自然语言处理和计算机视觉的精彩内容。

谢谢大家的支持!

相关推荐
肖遥Janic21 分钟前
Stable Diffusion绘画 | 如何做到不同动作表情,人物角色保持一致性(上篇)
人工智能·ai·ai作画·stable diffusion
SEU-WYL37 分钟前
基于深度学习的3D人体姿态预测
人工智能·深度学习·3d
红米煮粥41 分钟前
OpenCV-OCR
人工智能·opencv·ocr
xuehaisj41 分钟前
地图箭头方向检测系统源码分享
人工智能·计算机视觉·目标跟踪
William_Edmund1 小时前
Python 语言学习——应用1.2 数字图像处理(第二节,变换)
人工智能·学习·计算机视觉
我爱学Python!1 小时前
面试问我LLM中的RAG,秒过!!!
人工智能·面试·llm·prompt·ai大模型·rag·大模型应用
weixin_514548892 小时前
机器学习课程学习周报十五
人工智能·学习·机器学习
慢成长2 小时前
如何创建虚拟环境并实现目标检测及验证能否GPU加速
人工智能
AIGC破防黑吗喽2 小时前
Midjourney零基础学习
人工智能·gpt·学习·ai·stable diffusion·midjourney·ai绘画
AI大模型-王哥2 小时前
微软GraphRAG实战解析:全局理解力如何超越传统RAG
人工智能·microsoft·大模型·ai大模型·大模型学习·大模型入门·大模型教程