如何把自己的模型接入 Qlib 工作流:继承 Model 基类并用 qrun 验证
【免费下载链接】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 R&D process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib
Qlib(微软开源的 AI 量化投资平台)把"数据加载/处理/切片 → 模型训练与推理 → 信号分析与回测"组织成一条由配置文件驱动的标准工作流。如果你已经有一个自己的预测模型,想让它和平台内置的LightGBM、MLP、LSTM等一样参与训练、评估和记录,需要完成三件事:编写一个继承qlib.model.base.Model的自定义模型类、在配置文件里用model字段指向它、再用内置命令qrun跑完整工作流验证。官方文档 Custom Model Integration 给出的就是这条路径。本文按此路径整理成可执行步骤,适用于 A 股(region: cn)数据下的 Python 环境。
前置条件:安装 Qlib 并准备数据
根据 安装文档,Qlib 支持 Windows 和 Linux(推荐 Linux),支持 Python3,文档中标注"up to Python3.8"。安装与检查:
pip install pyqlib>>> import qlib >>> qlib.__version__ <LATEST VERSION>能打印出版本号说明安装成功。文档同时提到 Qlib 需要 lightgbm 和 pytorch 包,可用 pip 安装。
工作流运行需要本地数据。按 Data Preparation 文档 下载中国股票数据(数据来自 Yahoo Finance,文档提示数据可能不完美,如有高质量数据集建议自行准备):
python scripts/get_data.py qlib_data --target_dir ~/.qlib/qlib_data/cn_data --region cn注意region必须与provider_uri中存放的数据一致(cn 数据配cn模式)。
第一步:编写继承 Model 基类的自定义模型
Qlib 要求所有模型继承基类 qlib.model.base.Model。查看该源码可知,Model要求实现:
fit(self, dataset: Dataset, reweighter: Reweighter):从dataset学习模型,默认raise NotImplementedError(),必须覆盖;predict(self, dataset: Dataset, segment="test"):抽象方法,返回预测结果(文档示例中为pandas.Series),必须覆盖。
fit的文档注释中给出了从 dataset 取特征和标签的标准写法(训练段train必需,验证段valid可选):
# get features and labels df_train, df_valid = dataset.prepare( ["train", "valid"], col_set=["feature", "label"], data_key=DataHandlerLP.DK_L ) x_train, y_train = df_train["feature"], df_train["label"] x_valid, y_valid = df_valid["feature"], df_valid["label"]此外有两个约束来自文档,写代码时要记住:
- 超参数必须与
__init__一致:Qlib 会把配置文件model字段中的参数传给__init__,因此__init__必须能接受这些参数(集成文档要求"hyperparameters of model in the configuration must be consistent with those defined in the__init__method")。 - 学习得到的模型属性名不要以
_开头:Model.fit的注释明确说明,否则模型无法 dump 到磁盘。
集成文档给出了三个方法的示例实现(文档示例代码,以 LightGBM 为底层模型的自定义模型):
# __init__:配置文件中出现超参数(如 loss: mse)必须在此能被接受 def __init__(self, loss='mse', **kwargs): if loss not in {'mse', 'binary'}: raise NotImplementedError self._scorer = mean_squared_error if loss == 'mse' else roc_auc_score self._params.update(objective=loss, **kwargs) self._model = None # fit:必须接受 dataset;可选参数给默认值,如 num_boost_round = 1000 def fit(self, dataset: DatasetH, num_boost_round = 1000, **kwargs): # prepare dataset for lgb training and evaluation df_train, df_valid = dataset.prepare( ["train", "valid"], col_set=["feature", "label"], data_key=DataHandlerLP.DK_L ) x_train, y_train = df_train["feature"], df_train["label"] x_valid, y_valid = df_valid["feature"], df_valid["label"] # Lightgbm need 1D array as its label if y_train.values.ndim == 2 and y_train.values.shape[1] == 1: y_train, y_valid = np.squeeze(y_train.values), np.squeeze(y_valid.values) else: raise ValueError("LightGBM doesn't support multi-label training") dtrain = lgb.Dataset(x_train.values, label=y_train) dvalid = lgb.Dataset(x_valid.values, label=y_valid) self.model = lgb.train( self.params, dtrain, num_boost_round=num_boost_round, valid_sets=[dtrain, dvalid], valid_names=["train", "valid"], **kwargs ) # predict:必须接受 dataset,返回 prediction score def predict(self, dataset: DatasetH, **kwargs)-> pandas.Series: if self.model is None: raise ValueError("model is not fitted yet!") x_test = dataset.prepare("test", col_set="feature", data_key=DataHandlerLP.DK_I) return pd.Series(self.model.predict(x_test.values), index=x_test.index)这些片段需要放进一个 Python 模块(例如my_model.py)并组合成一个类,所需导入可参考内置实现 LGBModel 的导入方式:
import numpy as np import pandas as pd import lightgbm as lgb from qlib.model.base import Model from qlib.data.dataset import DatasetH from qlib.data.dataset.handler import DataHandlerLP from sklearn.metrics import mean_squared_error, roc_auc_score如果模型支持继续训练(finetune),这是可选项:继承 ModelFT(ModelFT(Model))并实现finetune(self, dataset: DatasetH, ...),集成文档也给出了lgb.train(..., init_model=self.model, ...)形式的参考实现。
写模型时建议对照平台内置的参考实现 qlib/contrib/model/gbdt.py,其中LGBModel完整演示了__init__、fit、predict、finetune四个方法在真实代码中的形态。
第二步:在配置文件中指向自定义模型
qrun 的配置文件结构见 Workflow 文档:qlib_init(数据路径与市场模式)+task(model/dataset/record三个小节)。接入自定义模型只需修改model字段,class是类名、module_path是模块路径、其余参数通过**kwargs传入__init__。以基准配置 workflow_config_lightgbm_Alpha158.yaml 为基础,把 model 部分替换为你自己的类:
task: model: class: LGBModel module_path: qlib.contrib.model.gbdt kwargs: loss: mse colsample_bytree: 0.8879 learning_rate: 0.2 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]class改为你的类名、module_path改为你的模块路径、kwargs换成你的超参数即可;dataset与record小节保持不变。注意dataset的segments定义了train/valid/test三段划分,fit和predict取数时就是按这些段名工作的。
一个文档不一致之处需要留意:集成文档 的示例片段把超参数写在args下,而 Workflow 文档和examples/benchmarks下的实际配置文件使用的键名是kwargs。上例遵循实际配置文件与 Workflow 文档的写法。
配置中&anchor/*anchor是 YAML 锚点,用于让market、benchmark等字段只写一处,修改时无需遍历整个文件。
第三步:用 qrun 运行并验证
qrun是 Qlib 安装后放置到$PATH中的内置命令。集成文档给出的测试方式:
cd examples # Avoid running program under the directory contains `qlib` qrun benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml集成文档原文假定配置文件名为workflow_config_lightgbm.yaml,仓库中实际存在的是workflow_config_lightgbm_Alpha158.yaml,以上命令使用实际文件名。测试你自己的模型时,把参数换成你的配置文件路径(qrun your_config.yaml)即可。文档特意要求cd examples:避免在包含qlib源码的目录下运行(初始化文档 也警告不要在 Qlib 仓库目录内 import qlib 包,否则可能出错)。
qrun 执行一次execution会依次完成:数据(加载、处理、切片)、模型(训练、推理、保存与加载)、评估(预测信号分析、回测)三个阶段,所以一次运行就能同时验证"模型能训练、能出预测分、能参与评估"。如果运行出问题,Workflow 文档给出调试模式:
python -m pdb qlib/cli/run.py examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml如何核对运行结果
Qlib 用实验管理系统 QlibRecorder 追踪每次 execution 的全部信息和产物(详见 Recorder 文档)。配置里record小节声明的三类 Record Template 决定了你能看到哪些结果:
SignalRecord:生成模型的预测(prediction)结果;SigAnaRecord:生成IC、ICIR、Rank IC、Rank ICIR;PortAnaRecord:生成回测(backtest)结果。
实验管理默认实现基于 MLflow,文档说明可以使用mlflow ui命令来可视化和检查实验结果。examples/benchmarks/LightGBM/workflow_config_lightgbm_Alpha158.yaml里的 record 配置就是同时启用以上三种记录的完整写法,你的配置文件沿用即可。
文档没有给出"成功"的标准日志或固定指标数值;判断依据是工作流三个阶段跑完且对应记录产物生成,指标数值需结合自己模型与数据在 MLflow 界面中查看。
可选:把模型作为独立模块单独测试
组件是松耦合的,Forecast Model也可以脱离 qrun 单独使用。Forecast Model 文档 和 examples/workflow_by_code.py 展示了这条路径:用init_instance_by_config从配置字典构建模型与数据集,在R.start(experiment_name=...)中调用model.fit(dataset),再用SignalRecord(model, dataset, recorder).generate()生成预测,SigAnaRecord/PortAnaRecord生成信号分析与回测。这条路径适合在写配置文件之前,先在代码层面验证自定义模型的fit/predict行为。
边界与限制
- 文档说明 Python 对象基于 pickle 保存,dump 环境与加载环境不一致时可能出现兼容问题(Recorder 文档的 Known Limitations),跨环境加载模型对象时要留意。
region与provider_uri的数据必须对齐;scripts/get_data.py只提供中国股票市场数据,美股数据需自行准备。- 配置文件里的时间范围(如示例中的 2008–2020)来自基准配置,替换成自己的数据区间时
data_handler_config与各段划分要同步修改,保持 train/valid/test 不重叠。 - 需要 finetune 能力时必须继承
ModelFT而不是Model,Model本身不提供该接口。
完成以上三步后,你的模型就和平台内置模型走同一条工作流:qrun 一次命令完成训练、预测、IC 分析与回测,所有产物可通过 MLflow 界面核对。
【免费下载链接】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 R&D process.项目地址: https://gitcode.com/GitHub_Trending/qli/qlib
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考