4. 数据准备与特征工程面试题
在Qlib量化研究面试中,数据准备与特征工程是区分“会调包”和“懂研究”的关键分水岭。面试官并不满足于你回答“用D.features取因子”,而是想确认你能否把原始行情、财务、另类数据转化为可复现、可解释、可上线的特征矩阵。本章围绕高频问题、回答框架和公司侧重点展开,帮助你把零散经验组织成结构化表达。
一、核心原理:Qlib数据层到底在解决什么
Qlib的数据准备不是简单的“读CSV”,而是构建一条从原始数据到模型可用特征的流水线。其核心抽象包括DataHandler、Processor和Dataset。DataHandler负责按时间、股票、字段组织数据;Processor负责缺失值填充、标准化、中性化等变换;Dataset则把特征和标签组装成训练样本。面试官常问:“你如何保证训练集和验证集之间没有未来信息泄漏?”这其实是在考察你对时间序列对齐和滚动窗口的理解。
关键原则有三条:第一,所有特征计算只能使用当前时点及之前的数据;第二,横截面处理(如去极值、标准化)必须在每个时间截面上独立完成;第三,标签构造要明确预测周期和可交易性。很多候选人在这里失分,是因为把“全样本标准化”当成了默认操作,导致验证集信息渗入训练集。
二、方法流程:从原始数据到特征矩阵
一个可复现的流程通常包含以下步骤,建议在面试中用“先……再……最后……”的句式表达:
- 数据源梳理:行情、财务、公告、舆情、另类数据分别来自哪里,更新频率和延迟如何。
- 清洗与对齐:处理停牌、涨跌停、复权、财报发布日期与报告期的区别。
- 缺失值处理:前向填充、截面中位数填充、或直接标记缺失。
- 去极值与标准化:MAD、分位数截断、Z-Score,注意按日截面操作。
- 特征构造:动量、波动率、换手率、估值、成长、质量等因子。
- 中性化与正交化:行业、市值中性化,避免风格暴露。
- 验证与入库:IC、RankIC、换手率、覆盖率,写入Qlib数据集。
在Qlib中,可以用配置或代码定义Processor链。例如:
from qlib.data.dataset.processor import DropnaProcessor, CSZScoreNorm
processors = [
DropnaProcessor(fields_group="feature"),
CSZScoreNorm(fields_group="feature", method="zscore")
]
这段代码的含义是:先删除特征缺失的样本,再在每个时间截面上做Z-Score标准化。面试时如果能解释“为什么用CSZScoreNorm而不是全局ZScore”,会显著加分。
三、高频问题与回答框架
以下表格整理了常见问题、回答要点和公司侧重点,建议结合自身项目准备具体案例。
| 高频问题 | 回答框架 | 公司侧重点 |
|---|---|---|
| 你如何处理缺失值? | 先分类缺失原因,再选择填充或标记,最后验证对IC的影响 | 大厂关注可复现与线上一致性 |
| 如何避免未来函数? | 时间对齐、滚动窗口、财报滞后、标签可交易性 | 私募与高频团队尤其敏感 |
| 因子中性化怎么做? | 行业哑变量回归、市值回归、残差作为新因子 | 资管与多因子团队常问 |
| 特征稳定性如何验证? | 分年度IC、滚动IC、特征分布漂移、PSI | 互联网量化平台关注监控 |
| Qlib中DataHandler和Dataset区别? | Handler管数据组织,Dataset管样本组装与切分 | 使用Qlib的团队必问 |
四、案例场景与误区复盘
假设面试官问:“你做过一个动量因子,但回测很好、实盘很差,怎么排查?”你可以从数据准备角度切入:首先检查动量计算是否使用了未来复权信息;其次确认股票池是否包含已退市或ST股票;然后看是否在涨跌停日仍然调仓;最后验证因子是否在行业和市值上暴露过大。这个回答展示了从数据到交易的完整链路思维。
常见误区包括:
- 全样本标准化:把训练集和验证集混在一起做Z-Score,造成信息泄漏。
- 财报数据直接用报告期:忽略公告日期,导致提前使用未公开信息。
- 缺失值一律填0:在收益率等字段上填0会引入错误信号。
- 只关注IC不关注换手:高IC但高换手的因子实盘成本会吞噬收益。
- 忽略股票池动态变化:用当前成分股回测历史,存在幸存者偏差。
最后,建议准备一个你实际做过的特征工程案例,能量化说明处理前后IC、RankIC、覆盖率或回测夏普的变化。面试官更相信有数据支撑的经验,而不是泛泛而谈的方法论。