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

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

1. 加载数据

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

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:时间序列数据可视化

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

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之间的值,以提高训练效率。

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层的神经网络模型。

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优化器来训练模型。

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个月的数据进行预测,并与测试集进行对比。

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个月的销售数据。

# 训练整个数据集并预测未来
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网络有了更深入的理解,并能将其应用到更多实际问题中。

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

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

谢谢大家的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会飞的Anthony

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值