Lag-Llama:轻松上手时间序列预测的开源基石安装与使用指南
Lag-Llama:轻松上手时间序列预测的开源基石安装与使用指南
时间序列预测在金融、气象、生产调度、销售预测等众多领域至关重要。相比传统 ARIMA、ETS 等模型,现代深度学习框架能够更好地挖掘复杂的时序特征。然而,搭建一个端到端、高性能的时间序列预测流水线往往需要投入大量精力:包括数据预处理、时滞特征生成、模型架构设计、训练与评估、可视化等环节。Lag-Llama 正是应运而生的一款开源基石工具,集成了常见的时滞特征(lag features)自动生成、数据集切分、模型模板(基于 Llama Transformer 架构)以及评估指标,帮助用户快速搭建和迭代时间序列预测项目。
本文将从以下几个方面展开:
- Lag-Llama 概览:介绍框架设计理念和核心组件。
- 环境安装与依赖:如何在本地/虚拟环境中快速安装 Lag-Llama。
- 数据准备与时滞特征生成:示例讲解数据导入、缺失值处理、自动生成 Lag 特征。
- 模型配置与训练:基于 Lag-Llama 内置模型模板,训练一个示例预测模型。
- 预测与评估:使用训练好的模型进行未来时刻预测,并展示评估结果及可视化。
- 高级功能:如多变量预测、滚动预测、超参数搜索、模型集成等。
- 实践示例:一个完整的小案例——使用公开数据(如电力负载或股票指数)演示从零到一的流程。
只要按步就班,即使对时序预测不熟悉,也能快速上手。文中每一步都附带代码示例(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 虚拟环境创建与依赖安装
创建虚拟环境(以 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
升级 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
使用。手动安装第三方依赖
如果不想安装全部依赖,可以仅安装核心包,需要时再补充。例如:pip install numpy pandas scikit-learn torch matplotlib tqdm
再根据代码报错提示,逐步补充其他依赖(如
tensorboard
,plotly
等)。验证安装
创建一个 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
,内容大致如下:
timestamp | load |
---|---|
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-12-31 23:00:00 | 1350.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 实现。该模型主要由以下几个部分组成:
- Embedding 层:将数值特征(Lag特征、滚动统计)和时间标记(如小时、星期几、月份等离散特征)映射到向量空间。
- Transformer Encoder:多层自注意力机制,捕捉滞后特征与其他外部特征之间的依赖关系。
- 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_loader
、val_loader
和test_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
)
生成的可视化图示例:

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
。内部逻辑简述:
- 当前时刻(t):从
df_original
中取最后sequence_length
行,生成所需的最新滞后特征。 - 模型对这
sequence_length
长度的输入进行一次预测,得到未来horizon
(12) 个小时的 load 预测。 - 将这 12 个预测值拼接到
df_original
后面,并更新最新数据。 - 继续用新的
sequence_length
(包含一部分真实 + 一部分预测)生成特征,再次预测,直到达到num_steps
。
这样做可以模拟实际在线预测场景。
6.3 超参数搜索(Hyperparameter Search)
虽然 Lag-Llama 提供了默认 Transformer 结构,但不同数据集往往需要调整学习率、Transformer 层数、注意力头数、dropout 比率等以获得最佳效果。Lag-Llama 集成了对接 scikit-learn
的 RandomizedSearchCV
风格接口,可辅助用户进行自动调参。
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. 小结与最佳实践
先打好数据预处理底座
- 数据质量决定模型上限。确保缺失值处理合理、时序索引对齐、时滞特征生成与原始目标列对应。
理解时滞特征的重要性
- 简单的
lag_k
与滚动窗口统计往往能捕捉明显的周期性与短期依赖,为后续 Transformer 提供“锚点”。
- 简单的
合理设置序列长度与预测步长
- 机器记忆有限,序列过长可能导致梯度消失或注意力机制耗时;序列过短又可能丢失长周期信息。通常先从 48−168 步(小时)尝试。
监控验证集指标与早停
- 为防止过拟合,建议严格使用验证集进行超参数调优,并启用 Early Stopping。
从单变量到多变量逐步扩展
- 建议先尝试仅用目标序列进行预测,熟悉整个流程后再加入外生变量、多路传感器。
定期检验滚动预测表现
- 在生产环境中,连续预测与模型自我更新可能导致误差累积,定期用真实数据重训练或微调非常关键。
可视化与监控
- 通过可视化对比图快速发现预测偏差大的时区,从而排查模型或数据问题。
9. 参考资源
- Lag-Llama 仓库:https://github.com/your-org/lag-llama
- Transformer 论文:Vaswani 等人,《Attention Is All You Need》,2017。
- 时间序列预测经典教材:Hyndman & Athanasopoulos,《Forecasting: Principles and Practice》。
- PyTorch 官方文档:https://pytorch.org
- Mermaid 绘图手册:https://mermaid-js.github.io/mermaid
通过本文,你已经了解了 Lag-Llama 的核心设计思路、快速安装方法、完整端到端流水线,以及若干高级用法。无论你是想用它做一次简单的单变量时序预测,还是想在工业场景中扩展到多变量、滚动预测、模型集成,Lag-Llama 都提供了清晰易用的接口和模板。
评论已关闭