Lag-Llama:轻松上手时间序列预测的开源基石安装与使用指南

Lag-Llama:轻松上手时间序列预测的开源基石安装与使用指南

时间序列预测在金融、气象、生产调度、销售预测等众多领域至关重要。相比传统 ARIMA、ETS 等模型,现代深度学习框架能够更好地挖掘复杂的时序特征。然而,搭建一个端到端、高性能的时间序列预测流水线往往需要投入大量精力:包括数据预处理、时滞特征生成、模型架构设计、训练与评估、可视化等环节。Lag-Llama 正是应运而生的一款开源基石工具,集成了常见的时滞特征(lag features)自动生成、数据集切分、模型模板(基于 Llama Transformer 架构)以及评估指标,帮助用户快速搭建和迭代时间序列预测项目。

本文将从以下几个方面展开:

  1. Lag-Llama 概览:介绍框架设计理念和核心组件。
  2. 环境安装与依赖:如何在本地/虚拟环境中快速安装 Lag-Llama。
  3. 数据准备与时滞特征生成:示例讲解数据导入、缺失值处理、自动生成 Lag 特征。
  4. 模型配置与训练:基于 Lag-Llama 内置模型模板,训练一个示例预测模型。
  5. 预测与评估:使用训练好的模型进行未来时刻预测,并展示评估结果及可视化。
  6. 高级功能:如多变量预测、滚动预测、超参数搜索、模型集成等。
  7. 实践示例:一个完整的小案例——使用公开数据(如电力负载或股票指数)演示从零到一的流程。

只要按步就班,即使对时序预测不熟悉,也能快速上手。文中每一步都附带代码示例(Python),并用Mermaid 图解展示整体流程,帮助初学者更容易理解。下面开始正文。


1. Lag-Llama 概览

1.1 设计理念与核心优势

  • 自动化时滞特征工程
    传统时序建模中,手工挑选滞后阶数和差分阶数是一件费时费力的事。Lag-Llama 提供了一套可配置的“Lag Feature Generator”,只需指定最大滞后阶数和滚动窗口统计方式(如均值、标准差、最小值、最大值),自动生成一整套时滞特征,省去繁琐的手工操作。
  • 基于 Transformer 的模型模板
    Lag-Llama 内置了基于 Llama Transformer 的时间序列预测模型模板,融合了注意力机制,能够更好地捕捉长序列中的全局依赖。用户只需配置好超参数(如层数、注意力头数、序列长度等),即可一键构建可训练模型。
  • 统一的数据流水线
    Lag-Llama 对常见数据预处理(缺失值填充、归一化、窗口切分)进行了封装,使得整个预测流程(从原始 CSV 到训练集、验证集再到评估)一条龙式无缝对接。
  • 可插拔式扩展
    如果你想替换模型或自定义损失函数、评估指标,Lag-Llama 提供了清晰的接口,支持用户将自定义组件整合到流水线中。
  • 多变量 & 单变量混合预测
    支持对多维度时序进行联合建模,也能对指定维度做单独预测。对于工业场景中常见的“有多路传感器数据”以及“重点预测某一路”的并行场景,非常灵活。

1.2 核心组件与模块结构

Lag-Llama/
├─ laglama/                    # 主包目录
│  ├─ __init__.py
│  ├─ data/                    # 数据处理相关
│  │   ├─ loader.py            # 数据加载与基本清洗
│  │   ├─ missing.py           # 缺失值处理
│  │   ├─ feature.py           # 滞后特征自动生成
│  │   └─ split.py             # 划分训练/验证/测试集
│  ├─ model/                   # 模型相关
│  │   ├─ base.py              # 基类定义
│  │   ├─ llama_ts.py          # Transformer 时序预测模型
│  │   ├─ loss.py              # 损失函数集合
│  │   └─ train.py             # 训练/验证流程
│  ├─ utils/                   # 工具函数
│  │   ├─ metrics.py           # 评估指标
│  │   ├─ viz.py               # 可视化函数
│  │   └─ config.py            # 配置管理
│  └─ cli.py                   # 命令行接口,支持一键式流水线执行
├─ examples/                   # 示例项目
│  ├─ electricity_load/        # 电力负载预测示例
│  └─ stock_price/             # 股票指数预测示例
├─ tests/                      # 单元测试
├─ setup.py                    # 安装脚本
└─ README.md
  • dataloader.py:负责从 CSV/JSON/数据库中读取原始时序数据,并返回 Pandas DataFrame。
  • missing.py:常见缺失值处理方案(前向填充、后向填充、插值、均值/中位数填充等)。
  • feature.py:自动生成 lag_1, lag_2, …, lag_k 且可同时计算滚动窗口统计量(如滚动均值、滚动方差)。
  • split.py:根据时间切片完成训练/验证/测试集的切分,可指定验证集比例、是否采用“滑窗”方式进行多次滚动验证。
  • llama_ts.py:主力模型,基于 PyTorch,采用多层 Transformer Encoder+Decoder 结构,结合时滞特征和可选的外生变量(exogenous features)。
  • train.py:封装了训练、验证、学习率调度、模型保存/加载等逻辑。
  • metrics.py:均方误差(MSE)、均方根误差(RMSE)、平均绝对百分比误差(MAPE)、R² 等常见时间序列评估指标。
  • viz.py:绘制训练曲线和预测结果对比图,支持 Matplotlib 与 Plotly 两种模式。
  • cli.py:提供命令行参数解析,一行命令即可完成“预处理 → 特征生成 → 模型训练 → 预测 → 评估 → 可视化”。

2. 环境安装与依赖

2.1 环境要求

  • Python 版本:推荐 3.8−3.10(已在 3.11+ 上测试通过,但部分依赖包兼容性待完善)。
  • 操作系统:Linux/macOS/Windows 三者均可,本文以 macOS + Python 3.9 为示例。
  • 硬件:若希望充分利用 GPU 加速,需要安装 CUDA(只在 Linux 与 Windows 上可用)。CPU 也能跑,但速度会慢一些。
  • 依赖包:包括 numpy, pandas, scikit-learn, torch>=1.12, matplotlib(或 plotly),以及可选的 tqdm, tensorboard 等。

2.2 虚拟环境创建与依赖安装

  1. 创建虚拟环境(以 venv 为例)

    # 进入项目目录
    cd ~/projects/
    # 创建虚拟环境
    python3 -m venv lag_llama_env
    # 激活虚拟环境
    source lag_llama_env/bin/activate    # macOS/Linux
    # Windows PowerShell:
    # .\lag_llama_env\Scripts\Activate.ps1
  2. 升级 pip 并安装依赖

    pip install --upgrade pip setuptools
    # 克隆 Lag-Llama 仓库(假设在 GitHub)
    git clone https://github.com/your-org/lag-llama.git
    cd lag-llama
    
    # 直接用 setup.py 安装
    pip install -e .

    上述 -e 参数表示“开发模式安装”,便于日后修改源码并立即生效。安装完成后,您即可在任何地方通过 import laglama 使用。

  3. 手动安装第三方依赖
    如果不想安装全部依赖,可以仅安装核心包,需要时再补充。例如:

    pip install numpy pandas scikit-learn torch matplotlib tqdm

    再根据代码报错提示,逐步补充其他依赖(如 tensorboard, plotly 等)。

  4. 验证安装
    创建一个 Python 控制台,导入核心模块,检查是否报错:

    >>> import laglama
    >>> laglama.__version__
    '0.1.0'    # 假设当前版本是 0.1.0
    >>> from laglama.data.feature import LagFeatureGenerator
    >>> from laglama.model.llama_ts import LlamaTSModel
    >>> print("安装成功 ✓")

    如果能正常输出版本号并导入核心类,就说明安装成功。


3. 数据准备与时滞特征生成

下面以一个典型的电力负载(Electricity Load)数据集为例,演示从数据导入到时滞特征预处理的完整流程。

3.1 示例数据简介

假设我们有一个 CSV 文件 electricity.csv,内容大致如下:

timestampload
2020-01-01 00:00:001234.5
2020-01-01 01:00:001250.2
2020-01-01 02:00:001228.7
......
2020-12-31 23:00:001350.1
  • timestamp:日期时间戳,分辨率为小时。
  • load:该时刻的电力负载值。

当然,实际项目中可能存在多个传感器:"load\_sensor1", "load\_sensor2" 等列。本文仅以单变量“load”演示,后续可拓展到多变量情形。

3.2 数据加载与基本清洗(loader.py

Lag-Llama 内置了一个方便的 DataLoader 类,只需传入 CSV 路径和关键列名,即可得到 Pandas DataFrame。示例代码:

# 示例:data_loader.py
from laglama.data.loader import DataLoader

# 1. 加载原始 CSV
file_path = "data/electricity.csv"
# timestamp_col:时间戳列名,value_col:待预测列名
loader = DataLoader(file_path, timestamp_col="timestamp", value_col="load")

# 2. 指定时间列解析与设置索引
df = loader.load_as_df(parse_dates=True, index_col="timestamp")
print(df.head())

可能输出:

                     load
timestamp                
2020-01-01 00:00:00 1234.5
2020-01-01 01:00:00 1250.2
2020-01-01 02:00:00 1228.7
2020-01-01 03:00:00 1215.3
2020-01-01 04:00:00 1208.9
  • load_as_df 方法可接收更多参数,比如 fill_missing=True,表示启用缺失值自动填充(见下一节)。

3.3 缺失值处理(missing.py

时序数据往往存在部分时刻缺失。Lag-Llama 提供多种缺失值处理策略,如前向填充(ffill)、后向填充(bfill)、线性插值(interpolate)、固定值填充等。示例:

from laglama.data.missing import MissingValueHandler

# 创建缺失值处理器
mv_handler = MissingValueHandler(strategy="interpolate", limit=2)
# strategy: "ffill", "bfill", "interpolate", "mean", "median", "zero"
# limit: 最大连续缺失数量限制

# 假设 df 里缺失了一些点
# df = loader.load_as_df(...)
df_filled = mv_handler.fill(df)
  • 如果使用 interpolate,Lag-Llama 会默认对数值型字段执行线性插值。
  • limit 参数限定了最大允许的连续缺失长度,超过该长度会抛出 ValueError,提醒用户注意数据完整性问题。

3.4 自动生成时滞特征(feature.py

时序预测中,Lag 特征(lag\_1, lag\_2, …, lag\_k)往往是最基础且最有效的输入特征。Lag-Llama 的 LagFeatureGenerator 能够一行代码生成指定阶数的滞后列,同时支持滚动窗口统计量(如移动平均、移动标准差等)。

from laglama.data.feature import LagFeatureGenerator

# 假设 df_filled 为预处理之后的 DataFrame,包含一列 "load"
# 我们想自动生成过去 24 小时的时滞特征,以及 7 天内 24 小时的平均负载(滚动窗口)
lag_gen = LagFeatureGenerator(
    target_col="load",
    max_lag=24,                  # 生成 lag_1 ... lag_24
    rolling_windows=[24, 168],   # 24h 和 7天(24*7=168h)两个滚动窗口
    rolling_funcs=["mean", "std"]  # 对滚动窗口进行均值和标准差运算
)

df_with_features = lag_gen.transform(df_filled)
print(df_with_features.columns)

执行后,df_with_features 可能包含以下列:

Index([
  'load',
  'lag_1', 'lag_2', ..., 'lag_24',
  'rolling_24_mean', 'rolling_24_std',
  'rolling_168_mean', 'rolling_168_std'
], dtype='object')
  • lag_1 表示当前时刻往前 1 小时的 load 值,lag_24 表示往前 24 小时的 load。
  • rolling_24_mean 表示过去 24 小时的负载平均值,rolling_168_std 表示过去 168 小时(7 天)的负载标准差。
  • Lag-Llama 会自动对齐这些特征,并删除因滞后/滚动带来的缺失行(即前 168 行会被丢弃),保持特征与标签一一对应。

4. 模型配置与训练

时序预测模型的引擎在 Lag-Llama 中由 LlamaTSModel 提供,底层基于 PyTorch 实现。该模型主要由以下几个部分组成:

  1. Embedding 层:将数值特征(Lag特征、滚动统计)和时间标记(如小时、星期几、月份等离散特征)映射到向量空间。
  2. Transformer Encoder:多层自注意力机制,捕捉滞后特征与其他外部特征之间的依赖关系。
  3. Decoder / 输出层:将 Encoder 的输出传入一个简单的全连接网络,预测未来指定步长(horizon)上的目标值。

4.1 配置文件示例

Lag-Llama 使用 YAML/JSON 配置文件管理训练参数,例如 config.yaml

data:
  file_path: "data/electricity.csv"
  timestamp_col: "timestamp"
  target_col: "load"
  freq: "H"                  # 数据频率:小时级
  train_ratio: 0.7           # 训练集占总数据的比例
  val_ratio: 0.1             # 验证集占比
  test_ratio: 0.2            # 测试集占比
  missing_strategy: "interpolate"
  max_lag: 24
  rolling_windows: [24, 168]
  rolling_funcs: ["mean", "std"]

model:
  input_dim: null            # 自动推断
  d_model: 64                # Transformer 隐藏维度
  n_heads: 4                 # 注意力头数
  num_encoder_layers: 2
  dim_feedforward: 128       # FFN 隐藏层大小
  dropout: 0.1

train:
  epochs: 50
  batch_size: 32
  lr: 0.001
  weight_decay: 0.0001
  device: "cuda"             # 或 "cpu"
  save_dir: "checkpoints/"
  eval_metric: "rmse"
  • data 部分:定义数据路径、列名、时序频率,以及特征工程参数。
  • model 部分:描述 Transformer 网络的各项超参数。
  • train 部分:训练轮数、学习率、优化器权重衰减、批大小以及保存检查点目录等。

4.2 划分训练/验证/测试集(split.py

Lag-Llama 的 DatasetSplitter 类会在完成特征生成后,根据配置自动划分三套数据集,并返回对应的 PyTorch DataLoader

from laglama.data.split import DatasetSplitter

# 1. 假设 df_with_features 已经包含完整特征和标签列 "load"
splitter = DatasetSplitter(
    df=df_with_features,
    target_col="load",
    train_ratio=0.7,
    val_ratio=0.1,
    test_ratio=0.2,
    horizon=12,         # 预测未来 12 步(即 12 个小时)
    sequence_length=48  # 输入序列长度为 48(过去 48 小时的特征)
)

train_loader, val_loader, test_loader = splitter.get_dataloaders(
    batch_size=32, shuffle=True
)
  • horizon=12:表示模型一次性预测未来 12 个小时的 load。
  • sequence_length=48:输入给模型的滑窗序列为过去 48 小时的数据(含滞后特征)。
  • train_loaderval_loadertest_loader 均为 PyTorch DataLoader,可直接在训练循环中使用。

4.3 构建模型实例

import torch
from laglama.model.llama_ts import LlamaTSModel
from laglama.utils.config import ConfigParser

# 1. 读取配置文件
config = ConfigParser("config.yaml")

# 2. 获取训练参数
model_params = config.get("model")
input_dim = splitte r.input_dim  # DatasetSplitter 会自动计算特征维度

# 3. 实例化模型
model = LlamaTSModel(
    input_dim=input_dim,
    d_model=model_params["d_model"],
    n_heads=model_params["n_heads"],
    num_encoder_layers=model_params["num_encoder_layers"],
    dim_feedforward=model_params["dim_feedforward"],
    dropout=model_params["dropout"],
    horizon=12  # 输出步长需与 splitter.horizon 对应
)
  • 这里直接从 DatasetSplitter 获取 input_dim,即特征矩阵的列数。
  • horizon 参数决定预测长度,需与数据切分模块保持一致,否则后续维度会不匹配。

4.4 训练与验证(train.py

Lag-Llama 提供了 Trainer 类封装训练逻辑,包括优化器、学习率调度、损失计算、早停(Early Stopping)等。示例:

from laglama.model.train import Trainer
from torch.optim import Adam

# 1. 定义优化器
optimizer = Adam(model.parameters(), lr=config.get("train.lr"), weight_decay=config.get("train.weight_decay"))

# 2. 可选:学习率调度器(这里使用 ReduceLROnPlateau)
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
    optimizer,
    mode="min",       # rmse 越小越好
    factor=0.5,
    patience=5,
    verbose=True
)

# 3. 实例化 Trainer
trainer = Trainer(
    model=model,
    optimizer=optimizer,
    scheduler=scheduler,
    train_loader=train_loader,
    val_loader=val_loader,
    device=config.get("train.device"),
    epochs=config.get("train.epochs"),
    eval_metric=config.get("train.eval_metric"),
    save_dir=config.get("train.save_dir")
)

# 4. 开始训练
trainer.train()

训练过程中会输出以下信息(以 Epoch 为单位):

Epoch 1/50 | Train Loss: 1250.634 | Val RMSE: 32.128
Epoch 2/50 | Train Loss: 1120.432 | Val RMSE: 28.764
...
Epoch 10/50 | Train Loss:  980.245 | Val RMSE: 23.514
...
Epoch 50/50 | Train Loss:  750.976 | Val RMSE: 18.902
  • Train Loss:训练集上的损失值。默认使用 MSE(均方误差),若指定 eval_metric = "mae",则以 MAE(平均绝对误差)为损失。
  • Val RMSE:验证集上的均方根误差。Early Stopping 会监控此指标,当若干个 epoch 后不再改善,则提前终止训练并保存最优模型。

4.5 训练流程图(Mermaid 图解)

flowchart TD
  A[原始 CSV 文件] --> B[DataLoader 加载 DataFrame]
  B --> C[MissingValueHandler 处理缺失]
  C --> D[LagFeatureGenerator 生成 Lag 特征]
  D --> E[DatasetSplitter 划分 train/val/test]
  E --> F[DataLoader (PyTorch) 数据迭代器]
  F --> G[LlamaTSModel (Transformer) 训练循环]
  G --> H[保存最佳模型 checkpoint]
  • 红色部分 表示每一阶段对应的核心模块。
  • 数据流自上而下,各组件按顺序调用,构成完整的训练流水线。

5. 预测与评估

训练完成后,我们需要使用保存的最佳模型对测试集或新数据进行预测,并评估模型效果。

5.1 加载训练好的模型

import torch

# 假设最佳模型已保存在 checkpoints/best_model.pth
model_path = "checkpoints/best_model.pth"
# 加载模型到相同架构
best_model = LlamaTSModel(
    input_dim=input_dim,
    d_model=model_params["d_model"],
    n_heads=model_params["n_heads"],
    num_encoder_layers=model_params["num_encoder_layers"],
    dim_feedforward=model_params["dim_feedforward"],
    dropout=model_params["dropout"],
    horizon=12
)
# 加载权重
best_model.load_state_dict(torch.load(model_path))
best_model.to(config.get("train.device"))
best_model.eval()

5.2 在测试集上进行推理

import numpy as np
from laglama.utils.metrics import compute_metrics

all_preds = []
all_targets = []

with torch.no_grad():
    for batch in test_loader:
        inputs, targets = batch["features"].to(config.get("train.device")), batch["labels"].to(config.get("train.device"))
        preds = best_model(inputs)
        all_preds.append(preds.cpu().numpy())
        all_targets.append(targets.cpu().numpy())

# 将 list of arrays 拼接成大数组
all_preds = np.concatenate(all_preds, axis=0)    # 形状: [num_samples, horizon]
all_targets = np.concatenate(all_targets, axis=0)

# 计算常见指标
metrics = compute_metrics(all_targets, all_preds, metrics=["rmse", "mape", "mae", "r2"])
print("Test Metrics:", metrics)
  • compute_metrics 会返回如下字典:

    {
      'rmse': 18.903,
      'mape': 0.0567,
      'mae': 14.235,
      'r2': 0.763
    }

5.3 可视化预测结果(viz.py

为了直观对比预测值与真实值走势,可以借助 Lag-Llama 自带的可视化工具,绘制指定序列片段对比图:

from laglama.utils.viz import plot_predictions

# 仅取测试集中的前 200 条样本进行可视化
plot_predictions(
    true_series=all_targets[:200, :],   # 形状 [200, horizon]
    pred_series=all_preds[:200, :],
    horizon=12,
    save_path="visuals/test_predictions.png"
)

该函数会自动绘制多行子图,每行展示一个样本在 horizon 范围内的真实曲线 vs 预测曲线,并保存到 test_predictions.png。也可指定 show=True,实时弹出窗口显示:

plot_predictions(
    true_series=all_targets[:50, :],
    pred_series=all_preds[:50, :],
    horizon=12,
    show=True
)

生成的可视化图示例:

预测 vs 真实对比预测 vs 真实对比


6. 高级功能

Lag-Llama 不仅支持单变量预测,还提供了以下进阶功能,以满足更复杂的业务场景:

6.1 多变量(Multivariate)预测

如果你的数据除了 “load” 之外,还有温度、湿度、天气类型等外部特征,也可以一并纳入模型。只需在数据加载时将那些列也读入,然后在 LagFeatureGenerator 中同时对多列进行滞后特征生成,最后模型的 input_dim 会自动增大。例如:

# 假设 CSV 中还包含 “temperature”, “humidity” 两列
loader = DataLoader(
    file_path="data/electricity_weather.csv",
    timestamp_col="timestamp",
    target_col="load",
    extra_cols=["temperature", "humidity"]
)
df = loader.load_as_df(parse_dates=True, index_col="timestamp")
df_filled = MissingValueHandler("interpolate").fill(df)

# 生成滞后特征时同时给 extra_cols 传参
lag_gen = LagFeatureGenerator(
    target_col="load",
    extra_cols=["temperature", "humidity"],
    max_lag=24,
    rolling_windows=[24],
    rolling_funcs=["mean"]
)
df_with_mv_features = lag_gen.transform(df_filled)
  • extra_cols 参数告诉生成器需要对额外列也进行相应的滞后和滚动统计。
  • 最终得到的 DataFrame 会包含 temperature_lag_1, humidity_lag_1 等列。
  • 此时模型输入维度(input_dim)会 =((1 + len(extra\_cols)) × (max\_lag + num\_rolling\_windows×num\_funcs) + 时间特征维度)。无需手动计算,DatasetSplitter 会自动推断。

6.2 滚动预测(Rolling Forecast)

在实际生产中,往往需要“循环地”向前预测:即模型第一次预测未来 12 小时,接着拿最新预测值与真实值补入序列,再次预测下一个 12 小时。Lag-Llama 提供了 RollingForecaster 类帮助实现该逻辑:

from laglama.model.train import RollingForecaster

# 初始化时需要传入训练好的模型、原始 DataFrame、LagFeatureGenerator
forecaster = RollingForecaster(
    model=best_model,
    df_original=df_with_features,  # 含完整特征的原 DF
    lag_feature_generator=lag_gen,
    horizon=12,
    device=config.get("train.device")
)

# 从原始数据最后一个时刻开始,循环预测未来 72 小时
pred_df = forecaster.predict(num_steps=72)
print(pred_df.head(10))

返回的 pred_df 是一个 DataFrame,索引为新预测的时间戳,每个时刻对应预测的 load。内部逻辑简述:

  1. 当前时刻(t):从 df_original 中取最后 sequence_length 行,生成所需的最新滞后特征。
  2. 模型对这 sequence_length 长度的输入进行一次预测,得到未来 horizon(12) 个小时的 load 预测。
  3. 将这 12 个预测值拼接到 df_original 后面,并更新最新数据。
  4. 继续用新的 sequence_length(包含一部分真实 + 一部分预测)生成特征,再次预测,直到达到 num_steps

这样做可以模拟实际在线预测场景。

6.3 超参数搜索(Hyperparameter Search)

虽然 Lag-Llama 提供了默认 Transformer 结构,但不同数据集往往需要调整学习率、Transformer 层数、注意力头数、dropout 比率等以获得最佳效果。Lag-Llama 集成了对接 scikit-learnRandomizedSearchCV 风格接口,可辅助用户进行自动调参。

from laglama.model.train import HyperparamTuner

search_space = {
    "d_model": [32, 64, 128],
    "n_heads": [2, 4, 8],
    "num_encoder_layers": [1, 2, 3],
    "dim_feedforward": [64, 128, 256],
    "dropout": [0.1, 0.2, 0.3],
    "lr": [1e-3, 5e-4, 1e-4]
}

tuner = HyperparamTuner(
    config=config,           # 原始配置(YAML/Dict)
    search_space=search_space,
    max_evals=20,            # 最多尝试 20 种组合
    cv_splits=3,             # 3 折时间序列交叉验证
    metric="rmse"
)

best_params = tuner.run(train_loader, val_loader)
print("最佳超参数:", best_params)
  • HyperparamTuner 会在给定的 search_space 中随机采样 max_evals 个组合,针对每组超参数重新训练模型,并在验证集上计算 rmse
  • 最终返回一组“最佳超参数”。你可以将其写回到 config.yaml,然后用它来做最终训练。

6.4 模型集成(Ensemble)

为了进一步提升预测精度,Lag-Llama 支持多模型集成。常见做法是同时训练多个不同超参数/不同模型(如 LightGBM、XGBoost、LSTM、Transformer 等),并取它们预测结果的加权平均或堆叠(stacking)。Lag-Llama 提供了 EnsemblePredictor 接口,可轻松加载多个模型并完成集成:

from laglama.model.ensemble import EnsemblePredictor

# 假设我们有 3 个不同配置训练出的模型检查点
model_paths = [
    "checkpoints/model_A.pth",
    "checkpoints/model_B.pth",
    "checkpoints/model_C.pth"
]
# 初始化 EnsemblePredictor
ensemble = EnsemblePredictor(
    model_class=LlamaTSModel,
    model_paths=model_paths,
    input_dim=input_dim,
    model_configs=[config_A, config_B, config_C],  # 对应各自的超参数配置
    device=config.get("train.device")
)

# 在测试集上预测并平均
ensemble_preds = ensemble.predict(test_loader)
ensemble_metrics = compute_metrics(all_targets, ensemble_preds, metrics=["rmse", "mae"])
print("Ensemble Test RMSE:", ensemble_metrics["rmse"])
  • model_configs 是一个列表,包含对应每个模型的超参数字典(如 d_model, n_heads 等)。
  • predict 方法内部对每个模型分别进行推理,再将预测结果按均匀权重进行平均(可自定义加权方式)。

7. 实践示例:电力负载预测全流程

为了帮助读者将上述各步骤串联起来,下面给出一个完整的“从零到一”示例,演示如何使用 Lag-Llama 对电力负载数据集进行预测。假设项目目录结构如下:

my_project/
├─ data/
│   └─ electricity.csv
├─ config.yaml
├─ train_pipeline.py
└─ requirements.txt
  • electricity.csv:原始数据。
  • config.yaml:前文示例中的配置文件。
  • train_pipeline.py:我们编写的“一键运行”脚本。
  • requirements.txt:用于记录依赖版本。

7.1 requirements.txt 示例

numpy>=1.21
pandas>=1.3
scikit-learn>=1.0
torch>=1.12
matplotlib>=3.5
tqdm>=4.62
lag-llama>=0.1.0

7.2 config.yaml 内容

(参考第 4.1 小节示例,略)

7.3 train\_pipeline.py

# train_pipeline.py

import os
import torch
import numpy as np
from laglama.data.loader import DataLoader
from laglama.data.missing import MissingValueHandler
from laglama.data.feature import LagFeatureGenerator
from laglama.data.split import DatasetSplitter
from laglama.model.llama_ts import LlamaTSModel
from laglama.model.train import Trainer
from laglama.utils.config import ConfigParser
from laglama.utils.metrics import compute_metrics
from laglama.utils.viz import plot_predictions

def main():
    # 1. 读取配置
    config = ConfigParser("config.yaml")

    # 2. 数据加载与预处理
    loader = DataLoader(
        file_path=config.get("data.file_path"),
        timestamp_col=config.get("data.timestamp_col"),
        value_col=config.get("data.target_col"),
        freq=config.get("data.freq")
    )
    df_raw = loader.load_as_df(parse_dates=True, index_col=config.get("data.timestamp_col"))

    mv_handler = MissingValueHandler(strategy=config.get("data.missing_strategy"))
    df_filled = mv_handler.fill(df_raw)

    # 3. 时滞特征生成
    lag_gen = LagFeatureGenerator(
        target_col=config.get("data.target_col"),
        max_lag=config.get("data.max_lag"),
        rolling_windows=config.get("data.rolling_windows"),
        rolling_funcs=config.get("data.rolling_funcs")
    )
    df_features = lag_gen.transform(df_filled)

    # 4. 划分数据集
    splitter = DatasetSplitter(
        df=df_features,
        target_col=config.get("data.target_col"),
        train_ratio=config.get("data.train_ratio"),
        val_ratio=config.get("data.val_ratio"),
        test_ratio=config.get("data.test_ratio"),
        horizon=config.get("model.horizon", 12),
        sequence_length=config.get("model.sequence_length", 48)
    )
    train_loader, val_loader, test_loader = splitter.get_dataloaders(
        batch_size=config.get("train.batch_size"), shuffle=True
    )

    # 5. 构建模型
    model_params = config.get("model")
    model = LlamaTSModel(
        input_dim=splitter.input_dim,
        d_model=model_params["d_model"],
        n_heads=model_params["n_heads"],
        num_encoder_layers=model_params["num_encoder_layers"],
        dim_feedforward=model_params["dim_feedforward"],
        dropout=model_params["dropout"],
        horizon=config.get("model.horizon", 12)
    ).to(config.get("train.device"))

    # 6. 定义优化器与调度器
    optimizer = torch.optim.Adam(
        model.parameters(),
        lr=config.get("train.lr"),
        weight_decay=config.get("train.weight_decay")
    )
    scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(
        optimizer, mode="min", factor=0.5, patience=5, verbose=True
    )

    # 7. 训练
    trainer = Trainer(
        model=model,
        optimizer=optimizer,
        scheduler=scheduler,
        train_loader=train_loader,
        val_loader=val_loader,
        device=config.get("train.device"),
        epochs=config.get("train.epochs"),
        eval_metric=config.get("train.eval_metric"),
        save_dir=config.get("train.save_dir")
    )
    trainer.train()

    # 8. 测试集预测与评估
    # 加载最佳模型
    best_model_path = os.path.join(config.get("train.save_dir"), "best_model.pth")
    model.load_state_dict(torch.load(best_model_path))
    model.eval()

    all_preds = []
    all_targets = []
    with torch.no_grad():
        for batch in test_loader:
            inputs = batch["features"].to(config.get("train.device"))
            targets = batch["labels"].to(config.get("train.device"))
            preds = model(inputs)
            all_preds.append(preds.cpu().numpy())
            all_targets.append(targets.cpu().numpy())

    all_preds = np.concatenate(all_preds, axis=0)
    all_targets = np.concatenate(all_targets, axis=0)
    metrics = compute_metrics(all_targets, all_preds, metrics=["rmse", "mape", "mae", "r2"])
    print("=== 测试集评估指标 ===")
    for k, v in metrics.items():
        print(f"{k.upper()}: {v:.4f}")

    # 9. 可视化前 50 个样本预测对比
    plot_predictions(
        true_series=all_targets[:50, :],
        pred_series=all_preds[:50, :],
        horizon=config.get("model.horizon", 12),
        show=True
    )

if __name__ == "__main__":
    main()

7.4 运行流水线

在终端输入:

source lag_llama_env/bin/activate
python train_pipeline.py

即可完成“数据预处理 → 特征处理 → 模型训练 → 评估 → 可视化”一站式流程。若要实现“滚动预测”或“多模型集成”,只需在 train_pipeline.py 中引入对应模块并调用相应方法即可。


8. 小结与最佳实践

  1. 先打好数据预处理底座

    • 数据质量决定模型上限。确保缺失值处理合理、时序索引对齐、时滞特征生成与原始目标列对应。
  2. 理解时滞特征的重要性

    • 简单的 lag_k 与滚动窗口统计往往能捕捉明显的周期性与短期依赖,为后续 Transformer 提供“锚点”。
  3. 合理设置序列长度与预测步长

    • 机器记忆有限,序列过长可能导致梯度消失或注意力机制耗时;序列过短又可能丢失长周期信息。通常先从 48−168 步(小时)尝试。
  4. 监控验证集指标与早停

    • 为防止过拟合,建议严格使用验证集进行超参数调优,并启用 Early Stopping。
  5. 从单变量到多变量逐步扩展

    • 建议先尝试仅用目标序列进行预测,熟悉整个流程后再加入外生变量、多路传感器。
  6. 定期检验滚动预测表现

    • 在生产环境中,连续预测与模型自我更新可能导致误差累积,定期用真实数据重训练或微调非常关键。
  7. 可视化与监控

    • 通过可视化对比图快速发现预测偏差大的时区,从而排查模型或数据问题。

9. 参考资源


通过本文,你已经了解了 Lag-Llama 的核心设计思路、快速安装方法、完整端到端流水线,以及若干高级用法。无论你是想用它做一次简单的单变量时序预测,还是想在工业场景中扩展到多变量、滚动预测、模型集成,Lag-Llama 都提供了清晰易用的接口和模板。

评论已关闭

推荐阅读

DDPG 模型解析,附Pytorch完整代码
2024年11月24日
DQN 模型解析,附Pytorch完整代码
2024年11月24日
AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日