
如何高效爬取全球新聞網站 – 整合Scrapy、Selenium與Mediastack API實現自動化新聞采集
其中:
2. 輸入門(Input Gate)
決定當前輸入信息是否寫入記憶單元中,用于更新記憶內容。輸入門同樣通過sigmoid函數生成一個0到1的值,表示當前輸入數據的重要性。
數學公式為:
同時,我們會計算一個候選記憶狀態(Candidate Memory Cell),用于提取輸入信息的主要特征,并將其加入到記憶單元中:
3. 輸出門(Output Gate)
決定當前記憶單元中的信息輸出到隱藏狀態的程度,用于產生當前時刻的隱藏狀態h2?,并將其傳遞給下一個時間步和最終輸出層。
數學公式:
然后,將更新后的記憶單元狀態與輸出門的控制相結合,得到新的隱藏狀態:
記憶單元更新
通過上述過程,LSTM在每個時間步的操作可以概括為以下步驟:
通過這種記憶單元狀態的更新與控制機制,LSTM能夠有效地在較長的序列中保持記憶,從而適用于時間序列預測等長時序依賴的任務。
為了更好的理解算法本身,實際數據非常大,不利于我們學習,我們構建一個虛擬天氣數據集,包括溫度、濕度、風速等變量。假設我們有一年的歷史數據,每日更新。我們將模擬這些數據并將其用于訓練和測試。
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)
將數據分為訓練集和測試集(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)
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}')
模型訓練完成后,我們對測試集進行預測,用圖形展示給大家~
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結構下未能得到充分捕捉,這時可以嘗試增加風速數據的周期性特征,或調整輸入序列長度。
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模型在預測問題上的有效性和可行性。