社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

【深度学习】基于LSTM的每日消费预测与预算管理。

机器学习初学者 • 3 天前 • 18 次点击  

今儿再来和大家聊一个关于 LSTM 的案例:基于LSTM的每日消费预测与预算管理

基于机器学习和深度学习的方法,尤其是长短期记忆网络(LSTM),在时间序列数据的预测任务中表现出了强大的优势。LSTM在处理和预测金融、消费等时间序列数据时,可以很好地捕捉数据中的长期依赖关系,从而实现高精度的预测。

原理阐述

LSTM 是一种改进型的RNN,特别适用于时间序列数据的建模。与传统RNN相比,LSTM能够更好地解决梯度爆炸和梯度消失问题,能够学习并记住长期依赖关系。因此,LSTM在各类时间序列预测问题中,尤其是在财务数据分析、股市预测、消费行为分析等场景中得到了广泛应用。

LSTM的核心在于其特殊的门结构,主要包括:

  1. 输入门(Input Gate):决定当前输入数据的哪些部分将用于更新网络的记忆单元。
  2. 遗忘门(Forget Gate):决定当前记忆单元中的哪些部分将被遗忘。
  3. 输出门(Output Gate):决定当前时刻的输出,决定了模型的最终输出。

LSTM数学公式:

遗忘门

其中, 表示遗忘门的输出, 是Sigmoid激活函数, 是权重矩阵, 是上一时刻的隐藏状态, 是当前的输入。

输入门

其中, 是输入门的输出,  是候选记忆单元, 是双曲正切激活函数。

更新记忆单元

其中, 是当前时刻的记忆单元。

输出门

其中, 是输出门的输出, 是当前时刻的隐藏状态,也是LSTM的输出。

问题定义

本案例的目标是基于LSTM模型对每日消费数据进行预测,并帮助用户进行预算管理。用户可以通过预测的消费数据进行预算调整,以确保每月的支出不超出设定的预算上限。

我们假设有一个虚拟的消费数据集,其中包含每日的消费记录,我们将使用该数据集训练LSTM模型,预测未来几天的消费金额。

虚拟数据集生成

我们将创建一个包含每日消费的虚拟数据集。为了简化问题,我们假设每日的消费金额受前几天消费的影响,并且存在季节性和周期性波动。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 设置随机种子
np.random.seed(42)

# 生成虚拟的每日消费数据(假设有365天的数据)
days = 365
date_range = pd.date_range(start='2023-01-01', periods=days, freq='D')

# 创建消费数据(包含周期性波动)
daily_expenses = 50 + 20 * np.sin(np.linspace(010 * np.pi, days)) + np.random.normal(05, days)

# 将数据转化为DataFrame格式
df = pd.DataFrame({'date': date_range, 'expense': daily_expenses})

# 绘制消费数据的折线图
plt.figure(figsize=(106))
plt.plot(df['date'], df['expense'], label='Daily Expenses')
plt.title('Simulated Daily Expenses over One Year')
plt.xlabel('Date')
plt.ylabel('Expense ($)')
plt.xticks(rotation=45)
plt.legend()
plt.show()

df.to_csv('daily_expenses.csv', index=False)

在这段代码中,首先生成了365天(代表一年的数据)每日的消费金额。为了模拟消费波动,我们加入了正弦波形(模拟季节性波动)以及一些随机噪声。

LSTM模型构建与训练

LSTM模型的输入是历史消费数据,输出是未来几天的消费预测。为了训练LSTM模型,我们需要对数据进行预处理,包括数据归一化、时间窗口创建等步骤。

Python代码:LSTM模型训练

import torch
import torch.nn as nn
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import train_test_split

# 数据预处理
scaler = MinMaxScaler(feature_range=(-11))
scaled_data = scaler.fit_transform(df['expense'].values.reshape(-11))

# 创建时间窗口数据
def create_dataset(data, time_step=30):
    X, y = [], []
    for i in range(len(data) - time_step - 1):
        X.append(data[i:(i + time_step), 0])
        y.append(data[i + time_step, 0])
    return np.array(X), np.array(y)

time_step = 30  # 使用过去30天的数据预测未来一天
X, y = create_dataset(scaled_data, time_step)

# 拆分数据集为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, shuffle=False)

# 转换为PyTorch张量
X_train = torch.tensor(X_train, dtype=torch.float32)
y_train = torch.tensor(y_train, dtype=torch.float32)
X_test = torch.tensor(X_test, dtype=torch.float32)
y_test = torch.tensor(y_test, dtype=torch.float32)

# LSTM模型定义
class LSTMModel(nn.Module):
    def __init__(self, input_size=1, hidden_layer_size=64, output_size=1):
        super(LSTMModel, self).__init__()
        self.lstm = nn.LSTM(input_size, hidden_layer_size, batch_first=True)
        self.fc = nn.Linear(hidden_layer_size, output_size)

    def forward(self, x):
        out, _ = self.lstm(x)
        out = self.fc(out[:, -1, :])
        return out

# 模型初始化
model = LSTMModel(input_size=1, hidden_layer_size=64, output_size=1)

# 损失函数与优化器
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

# 训练模型
epochs = 100
train_loss = []

for epoch in range(epochs):
    model.train()
    optimizer.zero_grad()
    output = model(X_train.unsqueeze(-1))  # 添加最后一个维度以符合LSTM的输入要求
    loss = criterion(output, y_train.unsqueeze(-1))
    loss.backward()
    optimizer.step()
    
    train_loss.append(loss.item())
    if (epoch + 1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{epochs}], Loss: {loss.item():.4f}')

# 绘制训练过程中的损失曲线
plt.figure(figsize=(106))
plt.plot(range(epochs), train_loss, label='Training Loss')
plt.title('Training Loss over Epochs')
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

这段代码定义了LSTM模型,并使用均方误差(MSE)作为损失函数来训练模型。训练过程中的损失值也被记录下来,并以曲线的形式进行展示。

模型预测与评估

训练完成后,我们可以使用测试集对模型进行预测,并与实际值进行对比。通过绘制预测曲线和真实消费曲线,可以直观地看出模型的预测效果。

# 模型预测
model.eval()
with torch.no_grad():
    predicted = model(X_test.unsqueeze(-1)).squeeze().numpy()

# 反归一化
predicted = scaler.inverse_transform(predicted.reshape(-11))
y_test = scaler.inverse_transform(y_test.reshape(-11))

# 绘制预测结果与真实结果的对比图
plt.figure(figsize=(106))
plt.plot(df['date'].iloc[-len(y_test):], y_test, label='Actual Expenses')
plt.plot(df['date'].iloc[-len(predicted):], predicted, label='Predicted Expenses')
plt.title('Actual vs Predicted Daily Expenses')
plt.xlabel('Date')
plt.ylabel('Expense ($)')
plt.xticks(rotation=45)
plt.legend()
plt.show()

# 计算模型性能
from sklearn.metrics import mean_squared_error, r2_score

mse = mean_squared_error(y_test, predicted)
r2 = r2_score(y_test, predicted)
print(f'Mean Squared Error: {mse:.4f}')
print(f'R2 Score: {r2:.4f}')

在这里,我们将模型的预测结果与实际值进行了对比,并计算了均方误差(MSE)和R²得分来评估模型的预测性能。

算法优化点与调参流程

在训练LSTM模型时,可能会遇到过拟合或欠拟合等问题。常见的优化点包括:

  1. 调节学习率:学习率过大可能导致训练不稳定,过小则可能导致收敛过慢。可以使用学习率调度器或使用自适应优化器(如Adam)。
  2. 调整隐藏层大小:增加隐藏层大小可能提升模型的表达能力,但也可能增加计算复杂度和过拟合的风险。
  3. 添加Dropout层:在LSTM层之间添加Dropout层,可以防止过拟合。
  4. 数据增强:通过对原始数据进行平滑、去噪等预处理,提升模型的泛化能力。

调参流程

  1. 初始调参:从较小的模型开始,选择合适的批量大小和学习率。
  2. 交叉验证:通过交叉验证选择最佳的模型超参数。
  3. 模型正则化:根据训练过程中的损失曲线和验证集表现,使用Dropout、L2正则化等技术防止过拟合。
  4. 评估与优化:根据评估指标(如MSE、R²得分)来进一步优化模型。

通过LSTM模型对每日消费数据进行预测,能够帮助用户做出合理的预算管理决策。通过图形化的分析和模型评估,能够更直观地了解模型的表现,并根据实际情况进行调整和优化。

最后

大家有问题可以直接在评论区留言即可~

喜欢本文的朋友可收藏、点赞、转发起来!

往期精彩回顾




  • 交流群

请备注:”昵称-学校/公司-研究方向“,例如:”张小明-浙大-CV“加群。

也可以加入机器学习交流qq群772479961


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/176386
 
18 次点击