ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Qlib Forecast Model 实战指南:预测模型的训练、预测与自定义扩展

Qlib Forecast Model 实战指南:预测模型的训练、预测与自定义扩展 Qlib Forecast Model 实战指南预测模型的训练、预测与自定义扩展【免费下载链接】qlibQlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML modeling paradigms, including supervised learning, market dynamics modeling, and RL, and is now equipped with https://github.com/microsoft/RD-Agent to automate RD process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib本篇聚焦 Qlib 的 Forecast Model预测模型组件讲解预测模型在 Qlib 中的定位、基类接口Model/ModelFT的设计以及如何在脱离完整工作流的情况下把 LightGBM 作为独立模块跑通「数据准备 → 模型训练 → 预测信号生成」全流程读完你可以掌握如何用配置化方式初始化任意模型、如何通过SignalRecord落盘预测分数并理解预测分数pred_score的默认语义。1. Forecast Model 在 Qlib 中的定位Forecast Model的职责是为股票生成prediction score预测分数。在 Qlib 中它有两种使用方式自动工作流方式通过命令行qrun XXX.yaml在完整工作流中运行工作流管理详见 Workflow 文档独立模块方式由于 Qlib 的组件是松耦合设计Forecast Model可以脱离完整工作流作为一个独立模块单独使用。本文主要展开第二种方式手动构建 task 配置、实例化模型与数据集、训练后生成预测信号。2. 基类与接口Model、BaseModel 与 ModelFTQlib 在 qlib/model/base.py 中提供了所有模型都应继承的基类体系qlib.model.base.Model可学习模型的基类定义了fit与predict两个核心接口qlib.model.base.ModelFT在Model基础上增加finetune抽象方法用于支持模型微调Fine-tuning更底层的qlib.model.base.BaseModel所有建模对象的父类它实现了__call__把模型对象包装得像函数一样可以直接调用内部转发给predict并混入了Serializable以支持序列化落盘。2.1 Model 的 fit 与 predictfit与predict的签名约定了模型与数据集的交互方式见 Model 基类实现fit(self, dataset, reweighter)从Dataset中学习模型。官方 docstring 给出了一段从 dataset 中取训练数据的标准写法# 获取特征与标签 df_train, df_valid dataset.prepare( [train, valid], col_set[feature, label], data_keyDataHandlerLP.DK_L ) x_train, y_train df_train[feature], df_train[label] x_valid, y_valid df_valid[feature], df_valid[label] # 获取样本权重若 handler 未配置 weight 列则退化为全 1 权重 try: wdf_train, wdf_valid dataset.prepare([train, valid], col_set[weight], data_keyDataHandlerLP.DK_L) w_train, w_valid wdf_train[weight], wdf_valid[weight] except KeyError as e: w_train pd.DataFrame(np.ones_like(y_train.values), indexy_train.index) w_valid pd.DataFrame(np.ones_like(y_valid.values), indexy_valid.index)其中DataHandlerLP.DK_L/DK_I分别指代 learn 处理与 infer 处理后的数据键这一约定贯穿所有内置模型。predict(self, dataset, segmenttest)默认对test分段做预测返回pandas.Series等结构化结果。一个值得注意的实现细节基类 docstring 明确要求学习到的模型属性名不能以_开头否则模型无法被完整 dump 到磁盘——这是为了配合 Qlib 的序列化机制。2.2 ModelFT 与 finetuneModelFT实现见 ModelFT为支持微调的模型增加了finetune(dataset)抽象方法。官方 docstring 展示了配合工作流 Recorder 的典型用法# 第一步在实验中训练初始模型 with R.start(experiment_nameinit models): model.fit(dataset) R.save_objects(init_modelmodel) rid R.get_recorder().id # 第二步基于已保存的模型做微调 with R.start(experiment_namefinetune model): recorder R.get_recorder(recorder_idrid, experiment_nameinit models) model recorder.load_object(init_model) model.finetune(dataset, num_boost_round10)即以先前训练好的模型为起点在新数据上继续训练若干轮这在滚动更新rolling场景下非常实用。3. 示例把 LightGBM 作为独立模块运行Qlib 内置的 Model Zoo 包含LightGBM、MLP、LSTM等模型它们作为 Forecast Model 的基线。以下示例演示以LightGBM为独立模块的运行方式。前置步骤先通过qlib.init初始化 Qlib初始化方式见 Initialization 文档。然后运行如下代码获取预测分数pred_scorefrom qlib.contrib.model.gbdt import LGBModel from qlib.contrib.data.handler import Alpha158 from qlib.utils import init_instance_by_config, flatten_dict from qlib.workflow import R from qlib.workflow.record_temp import SignalRecord, PortAnaRecord market csi300 benchmark SH000300 data_handler_config { start_time: 2008-01-01, end_time: 2020-08-01, fit_start_time: 2008-01-01, fit_end_time: 2014-12-31, instruments: market, } task { model: { class: LGBModel, module_path: qlib.contrib.model.gbdt, kwargs: { loss: mse, colsample_bytree: 0.8879, learning_rate: 0.0421, subsample: 0.8789, lambda_l1: 205.6999, lambda_l2: 580.9768, max_depth: 8, num_leaves: 210, num_threads: 20, }, }, dataset: { class: DatasetH, module_path: qlib.data.dataset, kwargs: { handler: { class: Alpha158, module_path: qlib.contrib.data.handler, kwargs: data_handler_config, }, segments: { train: (2008-01-01, 2014-12-31), valid: (2015-01-01, 2016-12-31), test: (2017-01-01, 2020-08-01), }, }, }, } # model initialization model init_instance_by_config(task[model]) dataset init_instance_by_config(task[dataset]) # start exp with R.start(experiment_nameworkflow): # train R.log_params(**flatten_dict(task)) model.fit(dataset) # prediction recorder R.get_recorder() sr SignalRecord(model, dataset, recorder) sr.generate()上面这段示例代码与仓库中 examples/workflow_by_code.py 的独立模块运行逻辑一致且该文件还额外演示了SigAnaRecord信号分析与PortAnaRecord组合回测分析的接续调用测试配置 qlib/tests/config.py 中的GBDT_MODEL也使用了与文档示例完全相同的一组超参数说明这组参数是 Qlib 官方的 CSI300 基线配置。3.1 配置项逐项说明数据段配置data_handler_config传给Alpha158参数示例值含义start_time/end_time2008-01-01 / 2020-08-01数据处理的总体时间范围fit_start_time/fit_end_time2008-01-01 / 2014-12-31学习类处理器如标准化的拟合区间通常与 train 段对齐避免用未来数据拟合统计量instrumentscsi300股票池instrument 列表模型配置task[model]classmodule_path指向 LGBModelkwargs中loss只支持mse/binary两种目标源码中其余取值直接抛NotImplementedError其余键colsample_bytree、learning_rate、subsample、lambda_l1、lambda_l2、max_depth、num_leaves、num_threads会原样透传给 LightGBM 的params。数据集配置task[dataset]DatasetH包装一个数据处理器handler与分段segments。segments把时间轴切成 train / valid / test 三段fit时按 train、valid 取数据predict时默认取 test 段。3.2 配置如何变成对象init_instance_by_config示例中init_instance_by_config(task[model])一行就完成了模型实例化。其机制在 qlib/utils/mod.py 中实现get_callable_kwargs解析配置class字段支持a.b.c.ClassName全限定写法或ClassNamemodule_path的分离写法本示例用后者通过importlib.import_module(module_path)动态导入模块取到类对象用kwargs完成构造若构造报TypeError如参数不匹配会回退重试。这种「配置即对象」的机制使得同一套 task 字典既能用于 Python 脚本也能用于qrun XXX.yaml的声明式工作流两个入口共享同一份配置语义。3.3 训练与预测信号的落盘示例进入R.start(experiment_nameworkflow)上下文后R.log_params(**flatten_dict(task))把嵌套 task 配置展平为「键.路径值」的平铺字典后记录为实验参数flatten_dict的实现见 qlib/utils/init.pymodel.fit(dataset)训练模型SignalRecord(model, dataset, recorder).generate()生成预测信号。SignalRecord是 Qlib 工作流中的 Record Template记录模板更多用法见 Recorder 文档。它的generate实现见 SignalRecord做了三件事调用model.predict(dataset)得到预测分数将预测结果保存为pred.pklpd.Series会被转成单列score的 DataFrame即文档中提到的pred_score从 handler 的原始标签DK_R中取出 test 段标签保存为label.pkl便于后续做 IC 等信号分析。3.4 关于 Alpha158 与预测分数示例中的Alpha158是 Qlib 提供的数据处理器158 个技术类因子详见 Data Handler 文档。从 Alpha158 源码 可以看到特征由 K线、价格OPEN/HIGH/LOW/VWAP、滚动统计三类因子组合构成默认标签配置为Ref($close, -2)/Ref($close, -1) - 1命名为LABEL0即 T1 相对 T 日收盘的次日收益。这引出文档的最后一句关键结论模型预测的语义取决于用户设计的 label。在默认设置下预测分数表示预测模型对标的的评级——分数越高的标的预期收益越高。因此 Top-K 选股策略「买分数最高的前 K 只」与标签语义是自洽的。4. LGBModel 实现深潜作为基线模型LGBModel 同时继承ModelFT与LightGBMFIntLightGBM 特征重要性解释器其核心行为值得对照文档示例理解构造参数lossmseearly_stopping_rounds50num_boost_round1000其余**kwargs全部并入 LightGBM 参数表见 LGBModel.init。fit 流程fit_prepare_data优先准备 train 段valid 段可选——这使模型在只有 train 段的数据集上也能训练标签必须可 squeeze 成一维LightGBM 不支持多标签训练可选传入Reweighter生成样本权重w训练回调包含早停lgb.early_stopping、周期日志与record_evaluation且每个 epoch 的验证指标会经R.log_metrics写入当前 Recorder可在实验对比中直接查看。predict 流程predict未训练直接抛ValueError数据取自DK_Iinfer 处理后的特征返回与x_test索引对齐的pd.Series——这正是SignalRecord能直接落盘的原因。finetune 流程finetune以现有模型为init_model在 train 段上追加num_boost_round默认 10轮训练与ModelFT.finetune的抽象定义对应。5. 自定义模型Qlib 支持自定义模型只要你的模型继承qlib.model.base.Model实现fit/predict属性名避免以_开头即可通过相同的init_instance_by_config配置机制集成进工作流或独立脚本。完整的自定义模型集成指引见 Custom Model Integration 文档。6. API 参考Model、ModelFT、finetune等接口的完整定义见 Model API 参考文档qlib.model.base模块源码位于 qlib/model/base.py。【免费下载链接】qlibQlib is an AI-oriented Quant investment platform that aims to use AI tech to empower Quant Research, from exploring ideas to implementing productions. Qlib supports diverse ML modeling paradigms, including supervised learning, market dynamics modeling, and RL, and is now equipped with https://github.com/microsoft/RD-Agent to automate RD process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进