其中:

2. 輸入門(Input Gate)

決定當前輸入信息是否寫入記憶單元中,用于更新記憶內容。輸入門同樣通過sigmoid函數生成一個0到1的值,表示當前輸入數據的重要性。

數學公式為:

同時,我們會計算一個候選記憶狀態(Candidate Memory Cell),用于提取輸入信息的主要特征,并將其加入到記憶單元中:

3. 輸出門(Output Gate)

決定當前記憶單元中的信息輸出到隱藏狀態的程度,用于產生當前時刻的隱藏狀態h2?,并將其傳遞給下一個時間步和最終輸出層。

數學公式:

然后,將更新后的記憶單元狀態與輸出門的控制相結合,得到新的隱藏狀態:

記憶單元更新

LSTM 整體流程

通過上述過程,LSTM在每個時間步的操作可以概括為以下步驟:

通過這種記憶單元狀態的更新與控制機制,LSTM能夠有效地在較長的序列中保持記憶,從而適用于時間序列預測等長時序依賴的任務。

2. 數據預處理與虛擬數據集生成

為了更好的理解算法本身,實際數據非常大,不利于我們學習,我們構建一個虛擬天氣數據集,包括溫度、濕度、風速等變量。假設我們有一年的歷史數據,每日更新。我們將模擬這些數據并將其用于訓練和測試。

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

# 生成虛擬天氣數據集
np.random.seed(42)
days = 365 # 一年數據
temperature = 30 + 5 * np.sin(np.linspace(0, 2 * np.pi, days)) + np.random.normal(0, 1, days)
humidity = 50 + 10 * np.sin(np.linspace(0, 2 * np.pi, days)) + np.random.normal(0, 2, days)
wind_speed = 10 + 3 * np.sin(np.linspace(0, 2 * np.pi, days)) + np.random.normal(0, 1, days)

data = pd.DataFrame({
'temperature': temperature,
'humidity': humidity,
'wind_speed': wind_speed
})

data.head()

數據標準化

在訓練模型之前,需要將數據標準化,以便LSTM能夠更有效地學習數據特征。

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler(feature_range=(0, 1))
data_scaled = scaler.fit_transform(data)

3. LSTM模型構建與訓練

數據切分

將數據分為訓練集和測試集(80%訓練,20%測試)。

train_size = int(len(data_scaled) * 0.8)
train_data = data_scaled[:train_size]
test_data = data_scaled[train_size:]

def create_sequences(data, seq_length):
xs, ys = [], []
for i in range(len(data) - seq_length):
x = data[i:i+seq_length]
y = data[i+seq_length]
xs.append(x)
ys.append(y)
return np.array(xs), np.array(ys)

seq_length = 7 # 用前7天的數據預測第8天
X_train, y_train = create_sequences(train_data, seq_length)
X_test, y_test = create_sequences(test_data, seq_length)

模型定義

我們使用PyTorch構建LSTM模型。

import torch
import torch.nn as nn

class WeatherLSTM(nn.Module):
def __init__(self, input_size, hidden_size, output_size, num_layers=1):
super(WeatherLSTM, self).__init__()
self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)

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

# 定義超參數
input_size = 3 # 特征數:溫度、濕度、風速
hidden_size = 64
output_size = 3
num_layers = 1

model = WeatherLSTM(input_size, hidden_size, output_size, num_layers)
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)

模型訓練

import torch.optim as optim

num_epochs = 100
for epoch in range(num_epochs):
model.train()
optimizer.zero_grad()
outputs = model(torch.Tensor(X_train))
loss = criterion(outputs, torch.Tensor(y_train))
loss.backward()
optimizer.step()

if (epoch+1) % 10 == 0:
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

4. 預測與可視化分析

模型訓練完成后,我們對測試集進行預測,用圖形展示給大家~

預測結果

model.eval()
with torch.no_grad():
predicted = model(torch.Tensor(X_test)).detach().numpy()
predicted = scaler.inverse_transform(predicted)
actual = scaler.inverse_transform(y_test)

# 轉為DataFrame便于可視化
predicted_df = pd.DataFrame(predicted, columns=['temperature', 'humidity', 'wind_speed'])
actual_df = pd.DataFrame(actual, columns=['temperature', 'humidity', 'wind_speed'])

可視化分析

1. 溫度預測結果:展示LSTM對溫度的預測與實際值的比較。

2. 濕度預測結果:展示LSTM對濕度的預測與實際值的差距。

3. 風速預測結果:分析風速的預測效果。

4. 多特征趨勢對比:對比所有特征在不同時間段的預測效果。

colors = ['#1f77b4', '#ff7f0e']  # 藍色:實際值,橙色:預測值
fig, axes = plt.subplots(3, 1, figsize=(12, 10))

# 標題和字體設置
fig.suptitle('Weather Prediction Using LSTM', fontsize=16, weight='bold')

# 溫度預測圖
axes[0].plot(actual_df['temperature'], color=colors[0], label='Actual Temperature', linewidth=1.5)
axes[0].plot(predicted_df['temperature'], color=colors[1], linestyle='--', label='Predicted Temperature', linewidth=1.5)
axes[0].set_title('Temperature Prediction', fontsize=14, weight='bold')
axes[0].set_ylabel('Temperature (°C)', fontsize=12)
axes[0].legend(fontsize=10, loc='upper right')
axes[0].grid(alpha=0.3)

# 濕度預測圖
axes[1].plot(actual_df['humidity'], color=colors[0], label='Actual Humidity', linewidth=1.5)
axes[1].plot(predicted_df['humidity'], color=colors[1], linestyle='--', label='Predicted Humidity', linewidth=1.5)
axes[1].set_title('Humidity Prediction', fontsize=14, weight='bold')
axes[1].set_ylabel('Humidity (%)', fontsize=12)
axes[1].legend(fontsize=10, loc='upper right')
axes[1].grid(alpha=0.3)

# 風速預測圖
axes[2].plot(actual_df['wind_speed'], color=colors[0], label='Actual Wind Speed', linewidth=1.5)
axes[2].plot(predicted_df['wind_speed'], color=colors[1], linestyle='--', label='Predicted Wind Speed', linewidth=1.5)
axes[2].set_title('Wind Speed Prediction', fontsize=14, weight='bold')
axes[2].set_ylabel('Wind Speed (km/h)', fontsize=12)
axes[2].set_xlabel('Days', fontsize=12)
axes[2].legend(fontsize=10, loc='upper right')
axes[2].grid(alpha=0.3)

# 調整布局并顯示
plt.tight_layout(rect=[0, 0, 1, 0.96])
plt.show()

我們使用了三個基本的折線圖來對比LSTM模型在溫度、濕度和風速預測方面的實際值和預測值。

溫度預測的圖形展示了LSTM模型對溫度時間序列的捕捉能力。如果預測線能夠緊密跟隨實際溫度曲線,說明模型能較好地捕捉溫度的變化趨勢。如果偏差較大,則需要調整模型復雜度或序列長度。

濕度預測的圖形反映了LSTM對濕度時序變化的擬合效果。通常濕度變化較溫度更不規則,因此濕度預測的誤差可能更大,這提示我們可以考慮將濕度數據的平滑度處理,減少噪聲。

風速圖形反映了模型在風速數據上的預測效果。如果預測值偏差較大,可能說明風速的時序特征在當前的LSTM結構下未能得到充分捕捉,這時可以嘗試增加風速數據的周期性特征,或調整輸入序列長度。

5. 模型優化與調參建議

LSTM模型的性能在很大程度上依賴于參數設置和數據處理。下面論述一些比較重要的方面~

模型優化方向

1. 隱藏層數量和單元數優化

在 LSTM 中,隱藏層數量和每一層的隱藏單元數會影響模型的復雜度。通常情況下,較高的隱藏單元數和更多的LSTM層能夠捕捉更復雜的時序特征,但過多的隱藏單元數和層數可能導致過擬合。

因此,我們可以嘗試:

2. 學習率調整

學習率是優化器的重要參數之一,它決定了每次參數更新的步長。在訓練過程中,可以使用學習率衰減策略,即隨著訓練輪次增加逐步減小學習率,幫助模型在接近最優點時更加平穩地收斂。常見策略:

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1)
for epoch in range(num_epochs):
# 模型訓練代碼...
optimizer.step()
scheduler.step() # 調整學習率

3. 正則化手段

LSTM 模型可能會因數據有限而出現過擬合問題,適當的正則化手段可以提高模型的泛化能力:

self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True, dropout=0.2)

4. 批量大小調整

批量大小決定了每次訓練中使用的數據量,合適的批量大小(如32、64、128等)在計算效率和泛化性能上會有較好的平衡。對于時間序列數據,一般來說,較小的批量可以幫助捕捉更多的特征信息。

調參流程

在優化模型時,系統化的調參流程能夠提高效率并找到最佳參數組合。

推薦的幾個調參方式:

1. 確定基本模型結構:先從簡單的LSTM結構入手,比如1層LSTM,16個隱藏單元,學習率0.01。

2. 逐步增加復雜度:根據模型初始結果,逐漸增加隱藏單元數或層數,并觀察訓練集和測試集的誤差變化。

3. 優化學習率和批量大小:通過實驗不同的學習率(0.01,0.001等)和批量大小,找到誤差最小且收斂速度較快的組合。

4. 添加正則化項:當模型效果較好但存在過擬合時,添加正則化手段(如Dropout)并調整比例(如0.1、0.2等)。

5. 迭代實驗:通過實驗記錄并分析結果曲線,繼續微調參數,直至得到滿意的結果。

最后

咱們這次實驗,通過LSTM模型來預測未來一周的天氣變化,涵蓋了數據預處理、模型構建、訓練、預測和結果分析等多個環節。通過優化模型參數,我們實現了對溫度、濕度和風速等氣象變量的預測,在圖形中得到了直觀展示。

未來的改進方向,大家可以考慮下面幾點:

1. 集成模型:可以嘗試使用多模型集成方法(如LSTM + GRU,LSTM + CNN)進一步提高模型的預測性能。

2. 多特征工程:引入更多氣象數據(如氣壓、降水量等),并考慮時間因素(如季節性)來豐富輸入特征。

3. 多步預測:通過多步預測來實現對更長期的天氣預測。

4. 動態序列長度:針對不同氣象變量優化序列長度,找到每個變量的最佳時間窗口。

以上內容,希望可以幫助大家理解LSTM模型在預測問題上的有效性和可行性。

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

上一篇:

突破LightGBM!最強時間序列模型!!

下一篇:

通透!十大時間序列技術 !!
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

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

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

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

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

#AI深度推理大模型API

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

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