跳转至

时间序列预测

概述

时间序列预测是分析和预测按时间顺序排列的数据点的技术,广泛应用于股票预测、天气预报、销量预测等场景。


时间序列基础

时间序列组成

# 四个组成部分

趋势(Trend):长期上升或下降
季节性(Seasonality):固定周期的波动
周期性(Cyclical):非固定周期的波动
残差(Residual):随机噪声

平稳性检验

from statsmodels.tsa.stattools import adfuller

def test_stationarity(series):
    result = adfuller(series)
    print(f'ADF统计量: {result[0]:.4f}')
    print(f'p值: {result[1]:.4f}')
    print('平稳' if result[1] < 0.05 else '非平稳')

经典方法

移动平均(MA)

import pandas as pd

def moving_average(series, window=7):
    return series.rolling(window=window).mean()

ARIMA模型

from statsmodels.tsa.arima.model import ARIMA

# ARIMA(p, d, q)
# p: 自回归阶数
# d: 差分阶数
# q: 移动平均阶数

model = ARIMA(train_data, order=(1, 1, 1))
fitted_model = model.fit()
predictions = fitted_model.forecast(steps=30)

Prophet(Facebook)

from prophet import Prophet

# 数据格式:ds(日期), y(值)
df = pd.DataFrame({'ds': dates, 'y': values})

model = Prophet(yearly_seasonality=True)
model.fit(df)

future = model.make_future_dataframe(periods=30)
forecast = model.predict(future)

深度学习方法

LSTM预测

import torch
import torch.nn as nn

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

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

# 数据准备
def create_sequences(data, seq_length):
    xs, ys = [], []
    for i in range(len(data) - seq_length):
        xs.append(data[i:i+seq_length])
        ys.append(data[i+seq_length])
    return torch.FloatTensor(xs), torch.FloatTensor(ys)

Transformer预测

class TimeSeriesTransformer(nn.Module):
    def __init__(self, input_size=1, d_model=64, nhead=4, num_layers=2):
        super().__init__()
        self.input_proj = nn.Linear(input_size, d_model)
        self.pos_encoding = PositionalEncoding(d_model)
        encoder_layer = nn.TransformerEncoderLayer(d_model, nhead)
        self.transformer = nn.TransformerEncoder(encoder_layer, num_layers)
        self.fc = nn.Linear(d_model, 1)

    def forward(self, x):
        x = self.input_proj(x)
        x = self.pos_encoding(x)
        x = self.transformer(x)
        return self.fc(x[:, -1, :])

实战:销量预测

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler

# 数据加载
df = pd.read_csv('sales.csv')
scaler = MinMaxScaler()
scaled_data = scaler.fit_transform(df[['sales']])

# 创建序列
seq_length = 30
X, y = create_sequences(scaled_data, seq_length)

# 划分训练集
split = int(0.8 * len(X))
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]

# 训练模型
model = LSTMPredictor()
criterion = nn.MSELoss()
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)

for epoch in range(50):
    model.train()
    pred = model(X_train)
    loss = criterion(pred, y_train)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

# 预测
model.eval()
with torch.no_grad():
    predictions = model(X_test)
    predictions = scaler.inverse_transform(predictions.numpy())

评估指标

from sklearn.metrics import mean_absolute_error, mean_squared_error

def evaluate_forecast(y_true, y_pred):
    mae = mean_absolute_error(y_true, y_pred)
    rmse = np.sqrt(mean_squared_error(y_true, y_pred))
    mape = np.mean(np.abs((y_true - y_pred) / y_true)) * 100
    return {'MAE': mae, 'RMSE': rmse, 'MAPE': mape}

下一步学习

  1. 深度学习教程 - 理解LSTM/Transformer
  2. 推荐系统实战 - 时序推荐
  3. MLOps实践 - 模型部署