
如何高效爬取全球新聞網站 – 整合Scrapy、Selenium與Mediastack API實現自動化新聞采集
優點:
缺點:
適用場景:適合平穩的時間序列,如金融數據、溫度變化等。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# 設置種子以確保可重復性
np.random.seed(42)
# 模擬數據 AR(2) 模型
n = 1000
y = np.zeros(n)
epsilon = np.random.normal(0, 1, n)
phi = [0.5, -0.3]
# 生成時間序列
for t in range(2, n):
y[t] = phi[0] * y[t-1] + phi[1] * y[t-2] + epsilon[t]
# 創建一個數據框架
df = pd.DataFrame({'Time': np.arange(n), 'Value': y})
# 繪制圖像:時間序列圖和自相關圖
fig, ax = plt.subplots(1, 2, figsize=(12, 6), dpi=120)
# 時間序列圖
ax[0].plot(df['Time'], df['Value'], color='blue')
ax[0].set_title('AR(2) Time Series')
ax[0].set_xlabel('Time')
ax[0].set_ylabel('Value')
# 自相關圖
pd.plotting.autocorrelation_plot(df['Value'], ax=ax[1])
ax[1].set_title('Autocorrelation of AR(2) Series')
plt.tight_layout()
plt.show()
時間序列圖:展示時間序列的變化趨勢,確認數據的平穩性。
自相關圖 (ACF 圖):自相關圖展示了不同滯后時間下序列與其自身的相關性。我們使用自相關圖來驗證 AR 模型的合理性,若自相關性在某些滯后期顯著,則表明該模型是合理的。
移動平均模型 (MA) 假設時間序列的當前值是過去誤差項的線性組合。與自回歸模型不同,MA 模型強調的是誤差項的影響,而非時間序列自身的歷史值。
移動平均模型的公式為:
優點:
缺點:
適用場景:適合隨機波動較強的平穩時間序列。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# 設置種子
np.random.seed(42)
# 模擬數據 MA(1) 模型
n = 100
epsilon = np.random.normal(0, 1, n)
y = np.zeros(n)
theta = 0.6
# 生成時間序列
for t in range(1, n):
y[t] = epsilon[t] + theta * epsilon[t-1]
# 創建數據框架
df = pd.DataFrame({'Time': np.arange(n), 'Value': y})
# 繪制圖像:時間序列圖和部分自相關圖
fig, ax = plt.subplots(1, 2, figsize=(12, 6), dpi=120)
# 時間序列圖
ax[0].plot(df['Time'], df['Value'], color='green')
ax[0].set_title('MA(1) Time Series')
ax[0].set_xlabel('Time')
ax[0].set_ylabel('Value')
# 部分自相關圖
from statsmodels.graphics.tsaplots import plot_pacf
plot_pacf(df['Value'], ax=ax[1], lags=20)
ax[1].set_title('Partial Autocorrelation of MA(1) Series')
plt.tight_layout()
plt.show()
時間序列圖:展示 MA(1) 模型生成的時間序列,觀察隨機波動的特征。
部分自相關圖 (PACF 圖):部分自相關圖展示了去除自回歸成分后的滯后效應。我們使用部分自相關圖來驗證 MA 模型的合理性,滯后期為 1 的部分自相關性應該顯著。
ARMA 模型結合了自回歸 (AR) 和移動平均 (MA) 的思想。它通過同時考慮時間序列的自身歷史值(AR部分)和過去誤差的線性組合(MA部分)來進行預測。
ARMA(p, q) 模型的公式為:
推導:ARMA 模型是 AR 和 MA 模型的組合。AR 部分通過最小化誤差平方和 (OLS) 估計,MA 部分通過最大化誤差項的似然函數 (MLE) 來估計。
優點:
缺點:
適用場景:適用于平穩的時間序列,如經濟數據、氣象數據等。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# 設置種子
np.random.seed(42)
# 模擬數據 ARMA(2,1) 模型
n = 100
y = np.zeros(n)
epsilon = np.random.normal(0, 1, n)
phi = [0.5, -0.4]
theta = 0.3
# 生成時間序列
for t in range(2, n):
y[t] = phi[0] * y[t-1] + phi[1] * y[t-2] + epsilon[t] + theta * epsilon[t-1]
# 創建數據框架
df = pd.DataFrame({'Time': np.arange(n), 'Value': y})
# 繪制圖像:時間序列圖和ACF圖
fig, ax = plt.subplots(1, 2, figsize=(12, 6), dpi=120)
# 時間序列圖
ax[0].plot(df['Time'], df['Value'], color='purple')
ax[0].set_title('ARMA(2,1) Time Series')
ax[0].set_xlabel('Time')
ax[0].set_ylabel('Value')
# 自相關圖
pd.plotting.autocorrelation_plot(df['Value'], ax=ax[1])
ax[1].set_title('Autocorrelation of ARMA(2,1) Series')
plt.tight_layout()
plt.show()
時間序列圖:觀察 ARMA(2, 1) 模型生成的時間序列,顯示其隨機波動和趨勢變化。
自相關圖 (ACF 圖):通過自相關圖來驗證 ARMA 模型中的滯后效應。如果滯后期的自相關性顯著,則可以說明模型的合理性。
ARIMA 模型是 ARMA 模型的擴展,增加了一個差分項,用于處理非平穩時間序列。差分的目的是去除時間序列中的趨勢和季節性波動,使其平穩。
ARIMA(p, d, q) 模型的公式為:
優點:
缺點:
適用場景:適用于非平穩數據,如股票價格、經濟指標等。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.tsa.arima.model import ARIMA
# 設置種子
np.random.seed(42)
# 模擬數據 ARIMA(1,1,1) 模型
n = 100
y = np.zeros(n)
epsilon = np.random.normal(0, 1, n)
phi = 0.6
theta = 0.4
# 生成時間序列 (一階差分)
for t in range(1, n):
y[t] = phi * y[t-1] + epsilon[t] + theta * epsilon[t-1]
# 創建數據框架
df = pd.DataFrame({'Time': np.arange(n), 'Value': y})
# 繪制圖像:原始序列與差分序列
fig, ax = plt.subplots(1, 2, figsize=(12, 6), dpi=120)
# 原始序列
ax[0].plot(df['Time'], df['Value'], color='red')
ax[0].set_title('ARIMA(1,1,1) Time Series')
ax[0].set_xlabel('Time')
ax[0].set_ylabel('Value')
# 一階差分
diff_y = np.diff(df['Value'], n=1)
ax[1].plot(df['Time'][:-1], diff_y, color='blue')
ax[1].set_title('First Difference of ARIMA(1,1,1) Series')
ax[1].set_xlabel('Time')
ax[1].set_ylabel('Differenced Value')
plt.tight_layout()
plt.show()
原始序列圖:展示生成的 ARIMA(1, 1, 1) 模型的時間序列,觀察其非平穩特性。
一階差分圖:通過一階差分圖顯示經過差分處理后的平穩時間序列,以展示差分操作的效果。
SARIMA 模型擴展了 ARIMA 模型,增加了季節性成分,用于處理具有周期性和季節性變化的時間序列。它結合了非季節性成分和季節性成分。
推導:非季節性成分和季節性成分分別處理,首先通過差分去除趨勢和季節性,然后應用 ARMA 模型對剩余部分進行建模。
優點:
缺點:
適用場景:適用于季節性數據,如氣象數據、銷售數據等。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.tsa.statespace.sarimax import SARIMAX
# 設置種子
np.random.seed(42)
# 模擬數據 SARIMA(1,1,1)(1,1,1,12) 模型
n = 120
seasonal_period = 12
y = np.zeros(n)
epsilon = np.random.normal(0, 1, n)
phi = 0.7
theta = 0.5
Phi = 0.3
Theta = 0.2
# 生成時間序列
for t in range(1, n):
if t >= seasonal_period:
y[t] = phi * y[t-1] + theta * epsilon[t-1] + Phi * y[t-seasonal_period] + Theta * epsilon[t-seasonal_period] + epsilon[t]
else:
y[t] = phi * y[t-1] + theta * epsilon[t-1] + epsilon[t]
# 創建數據框架
df = pd.DataFrame({'Time': np.arange(n), 'Value': y})
# 繪制圖像:原始序列與季節性分解
fig, ax = plt.subplots(1, 2, figsize=(12, 6), dpi=120)
# 原始序列
ax[0].plot(df['Time'], df['Value'], color='orange')
ax[0].set_title('SARIMA(1,1,1)(1,1,1,12) Time Series')
ax[0].set_xlabel('Time')
ax[0].set_ylabel('Value')
# 季節性分解圖
from statsmodels.tsa.seasonal import seasonal_decompose
result = seasonal_decompose(df['Value'], period=seasonal_period, model='additive')
result.seasonal.plot(ax=ax[1], color='blue')
ax[1].set_title('Seasonal Component of SARIMA Series')
ax[1].set_xlabel('Time')
plt.tight_layout()
plt.show()
原始序列圖:展示 SARIMA 模型生成的時間序列,包含季節性成分和隨機波動。
季節性分解圖:分離季節性成分,顯示時間序列中的周期性變化,幫助識別季節性波動。
指數平滑模型 (ETS, Exponential Smoothing Model)是一類用于時間序列預測的模型,其基本思想是給不同時間點的觀測值賦予不同的權重,越接近當前時間點的數據,權重越大。這種加權方式可以很好地平滑時間序列中的短期波動。ETS 模型可以處理趨勢和季節性成分。
簡單指數平滑 (Simple Exponential Smoothing)?的公式為:
推導:ETS 模型通過平滑操作分別計算時間序列的長期趨勢、短期波動和季節性影響。通過設定不同的平滑系數來調整對各個成分的權重。
優點:
缺點:
適用場景:適合平穩數據以及含有周期性和趨勢成分的時間序列,如銷量預測、溫度變化等。
我們生成一個帶有季節性和趨勢的時間序列,并使用 ETS 模型進行預測。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.tsa.holtwinters import ExponentialSmoothing
# 設置種子
np.random.seed(42)
# 生成帶有趨勢和季節性的時間序列數據
n = 150
time = np.arange(n)
seasonal_period = 12
trend = 0.05 * time
seasonal = 10 * np.sin(2 * np.pi * time / seasonal_period)
noise = np.random.normal(0, 2, n)
y = 20 + trend + seasonal + noise
# 創建數據框架
df = pd.DataFrame({'Time': time, 'Value': y})
# 應用ETS模型(加法模型)
model = ExponentialSmoothing(df['Value'], seasonal='add', trend='add', seasonal_periods=seasonal_period)
fit = model.fit()
# 預測未來的值
forecast = fit.forecast(steps=24)
# 繪制原始數據和預測數據
plt.figure(figsize=(12, 6), dpi=120)
plt.plot(df['Time'], df['Value'], label='Original Series', color='blue')
plt.plot(np.arange(n, n + len(forecast)), forecast, label='Forecast', color='orange')
plt.axvline(x=n, color='gray', linestyle='--', label='Prediction Start')
plt.title('ETS Model - Additive Trend and Seasonality')
plt.xlabel('Time')
plt.ylabel('Value')
plt.legend()
plt.show()
時間序列預測圖:展示原始時間序列以及基于 ETS 模型的預測結果,用于展示模型在處理趨勢和季節性數據時的效果。
長短期記憶網絡 (LSTM) 是一種特殊的循環神經網絡 (RNN),適用于處理序列數據中的長期依賴問題。它通過引入記憶單元和門控機制,能夠選擇性地保留或遺忘先前時間點的信息,解決了傳統 RNN 中的梯度消失問題。
LSTM 的核心組件包括遺忘門、輸入門和輸出門,分別控制如何處理記憶狀態。
1. 遺忘門:決定哪些信息需要被遺忘。
2. 輸入門:決定哪些信息需要被寫入記憶。
3. 輸出門:決定如何產生當前時刻的隱狀態。
優點:
缺點:
適用場景:適合處理復雜的時間序列數據,如股票預測、語音識別、自然語言處理等。
使用 PyTorch 實現 LSTM 進行時間序列預測的完整代碼案例。
import numpy as np
import matplotlib.pyplot as plt
import torch
import torch.nn as nn
from sklearn.preprocessing import MinMaxScaler
from torch.autograd import Variable
# 設置隨機種子以確保可復現性
np.random.seed(42)
torch.manual_seed(42)
# 生成正弦波數據
def generate_sine_wave(sequence_length, num_samples):
x = np.linspace(0, 100, num_samples)
y = np.sin(x)
return y
# 參數
sequence_length = 50 # 序列長度
num_samples = 1000 # 樣本數量
# 生成數據
data = generate_sine_wave(sequence_length, num_samples)
# 可視化數據
plt.plot(data)
plt.title("Sine Wave")
plt.show()
# 數據歸一化
scaler = MinMaxScaler(feature_range=(0, 1))
data_scaled = scaler.fit_transform(data.reshape(-1, 1))
# 創建時間序列數據集
def create_dataset(data, sequence_length):
X, y = [], []
for i in range(len(data) - sequence_length):
X.append(data[i:i + sequence_length, 0])
y.append(data[i + sequence_length, 0])
return np.array(X), np.array(y)
# 創建輸入輸出數據
X, y = create_dataset(data_scaled, sequence_length)
# 轉換為 PyTorch 張量
X = torch.from_numpy(X).float().unsqueeze(-1) # shape: (samples, sequence_length, 1)
y = torch.from_numpy(y).float() # shape: (samples,)
class LSTMModel(nn.Module):
def __init__(self, input_size, hidden_size, output_size, num_layers=1):
super(LSTMModel, self).__init__()
self.hidden_size = hidden_size
self.num_layers = num_layers
# 定義 LSTM 層
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):
# 初始化隱狀態和細胞狀態
h0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size)
c0 = torch.zeros(self.num_layers, x.size(0), self.hidden_size)
# 前向傳播 LSTM 層
out, _ = self.lstm(x, (h0, c0))
# 取最后一個時間步的輸出
out = out[:, -1, :]
# 全連接層輸出
out = self.fc(out)
return out
# 定義模型參數
input_size = 1 # 輸入特征數
hidden_size = 50 # LSTM 隱藏層單元數
output_size = 1 # 輸出特征數
num_layers = 1 # LSTM 層數
# 初始化模型
model = LSTMModel(input_size, hidden_size, output_size, num_layers)
# 打印模型結構
print(model)
# 定義損失函數和優化器
criterion = nn.MSELoss() # 使用均方誤差作為損失函數
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
# 劃分訓練集和測試集
train_size = int(len(X) * 0.8)
test_size = len(X) - train_size
X_train, X_test = X[:train_size], X[train_size:]
y_train, y_test = y[:train_size], y[train_size:]
# 訓練模型
num_epochs = 100
for epoch in range(num_epochs):
model.train()
# 前向傳播
outputs = model(X_train)
loss = criterion(outputs, y_train)
# 反向傳播和優化
optimizer.zero_grad()
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(X_test)
predicted = predicted.detach().numpy()
# 反歸一化預測值
predicted = scaler.inverse_transform(predicted)
# 反歸一化真實值
y_test = y_test.detach().numpy()
y_test = scaler.inverse_transform(y_test.reshape(-1, 1))
# 可視化結果
plt.plot(y_test, label='True Value')
plt.plot(predicted, label='Predicted Value')
plt.title('LSTM Time Series Prediction')
plt.legend()
plt.show()
使用了 PyTorch 來構建 LSTM 模型,用于處理時間序列預測問題。
模型包含一個 LSTM 層和一個全連接層,通過 Adam 優化器進行訓練。
Prophet 是由 Facebook 開發的一種時間序列預測模型,基于加性模型,將趨勢、季節性和假期影響分解為不同的成分,能夠處理非線性時間序列。
ophet 的基本公式為:
使用簡單的正弦波時間序列作為數據示例,訓練后的模型能夠預測未來的值。
Prophet 將趨勢項建模為線性或非線性,季節性使用傅里葉級數表示,假期使用顯式的日期列表。
優點:
缺點:
適用場景:適合社交媒體分析、銷量預測、網站流量預測等周期性數據。
我們使用 prophet 模型對帶有周期性的虛擬數據進行預測。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from prophet import Prophet
# 生成帶有趨勢和季節性的時間序列數據
np.random.seed(42)
n = 200
time = pd.date_range(start='2022-01-01', periods=n, freq='D')
trend = np.linspace(0, 10, n)
seasonal = 5 * np.sin(2 * np.pi * np.arange(n) / 30)
noise = np.random.normal(0, 0.5, n)
y = 20 + trend + seasonal + noise
# 創建數據框架
df = pd.DataFrame({'ds': time, 'y': y})
# Prophet 模型
model = Prophet(yearly_seasonality=False, daily_seasonality=True)
model.fit(df)
# 預測未來30天
future = model.make_future_dataframe(periods=30)
forecast = model.predict(future)
# 繪制預測結果
model.plot(forecast)
plt.title('Prophet Time Series Prediction')
plt.show()
Prophet 預測圖:展示 Prophet 模型對時間序列數據的預測,包括趨勢和季節性成分的分解。
貝葉斯結構時間序列模型基于貝葉斯方法,能夠結合不同的成分(趨勢、季節性等)對時間序列進行分解。它在處理非線性時間序列和捕捉不確定性方面有獨特優勢。
TS 模型的基本公式為:
通過貝葉斯推斷,BSTS 能夠對不同的成分進行不確定性估計。
優點:
缺點:
適用場景:適合金融市場、銷售數據、網絡流量等具有復雜特性的時間序列。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from bsts import BSTS
# 生成虛擬數據
np.random.seed(42)
n = 100
time = np.arange(n)
trend = 0.1 * time
noise = np.random.normal(0, 1, n)
y = trend + noise
# BSTS 模型構建與擬合
model = BSTS()
model.fit(y)
# 預測未來值
predicted = model.predict(steps=10)
# 繪制預測結果
plt.figure(figsize=(10, 6))
plt.plot(time, y, label='Original Series')
plt.plot(np.arange(n, n+10), predicted, label='BSTS Prediction', color='orange')
plt.legend()
plt.title('BSTS Time Series Prediction')
plt.show()
時間序列預測圖:展示了 BSTS 模型對未來時間序列的預測,結合了趨勢和噪聲成分,顯示其在不確定性建模中的優勢。
卡爾曼濾波是一種遞歸濾波算法,廣泛用于動態系統的狀態估計,能夠處理噪聲干擾。它通過貝葉斯推斷動態調整對當前狀態的估計,適合平滑和預測時間序列。
曼濾波的更新公式為:
預測:
優點:
缺點:
適用場景:適用于實時狀態估計和動態系統建模,如導航系統、金融市場等。
import numpy as np
import matplotlib.pyplot as plt
from pykalman import KalmanFilter
# 生成時間序列數據
n = 100
time = np.arange(n)
signal = np.sin(0.1 * time)
noise = np.random.normal(0, 0.1, n)
y = signal + noise
# 卡爾曼濾波
kf = KalmanFilter(initial_state_mean=0, n_dim_obs=1)
state_means, _ = kf.smooth(y)
# 繪制原始數據和卡爾曼濾波結果
plt.figure(figsize=(10, 6))
plt.plot(time, y, label='Noisy Signal')
plt.plot(time, state_means, label='Kalman Filtered', color='red')
plt.legend()
plt.title('Kalman Filter - Time Series Smoothing')
plt.show()
時間序列平滑圖:展示原始噪聲數據和經過卡爾曼濾波后的平滑結果。
時間序列平滑圖:展示了卡爾曼濾波在處理帶噪聲的時間序列中的平滑效果,顯示其在動態系統建模中的優越性。