其中, 表示遺忘門的輸出, 是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(0, 10 * np.pi, days)) + np.random.normal(0, 5, days)

# 將數據轉化為DataFrame格式
df = pd.DataFrame({'date': date_range, 'expense': daily_expenses})

# 繪制消費數據的折線圖
plt.figure(figsize=(10, 6))
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=(-1, 1))
scaled_data = scaler.fit_transform(df['expense'].values.reshape(-1, 1))

# 創建時間窗口數據
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=(10, 6))
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(-1, 1))
y_test = scaler.inverse_transform(y_test.reshape(-1, 1))

# 繪制預測結果與真實結果的對比圖
plt.figure(figsize=(10, 6))
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)和R2得分來評估模型的預測性能。

算法優化點與調參流程

在訓練LSTM模型時,可能會遇到過擬合或欠擬合等問題。常見的優化點包括:

  1. 調節學習率:學習率過大可能導致訓練不穩定,過小則可能導致收斂過慢。可以使用學習率調度器或使用自適應優化器(如Adam)。
  2. 調整隱藏層大小:增加隱藏層大小可能提升模型的表達能力,但也可能增加計算復雜度和過擬合的風險。
  3. 添加Dropout層:在LSTM層之間添加Dropout層,可以防止過擬合。
  4. 數據增強:通過對原始數據進行平滑、去噪等預處理,提升模型的泛化能力。

調參流程

  1. 初始調參:從較小的模型開始,選擇合適的批量大小和學習率。
  2. 交叉驗證:通過交叉驗證選擇最佳的模型超參數。
  3. 模型正則化:根據訓練過程中的損失曲線和驗證集表現,使用Dropout、L2正則化等技術防止過擬合。
  4. 評估與優化:根據評估指標(如MSE、R2得分)來進一步優化模型。

通過LSTM模型對每日消費數據進行預測,能夠幫助用戶做出合理的預算管理決策。通過圖形化的分析和模型評估,能夠更直觀地了解模型的表現,并根據實際情況進行調整和優化。

本文章轉載微信公眾號@深夜努力寫Python

上一篇:

突破最強時間序列模型,向量自回歸!!

下一篇:

突破K-means,與DTW時間序列聚類分析 !!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費