其中, 表示遺忘門的輸出, 是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模型,我們需要對數據進行預處理,包括數據歸一化、時間窗口創建等步驟。
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模型時,可能會遇到過擬合或欠擬合等問題。常見的優化點包括:
調參流程:
通過LSTM模型對每日消費數據進行預測,能夠幫助用戶做出合理的預算管理決策。通過圖形化的分析和模型評估,能夠更直觀地了解模型的表現,并根據實際情況進行調整和優化。
本文章轉載微信公眾號@深夜努力寫Python