2. 因子库基础:什么是因子库、因子库的常见结构与存储方式
在风控建模与监控体系中,因子库是存放所有衍生特征(即因子)的中央仓库。它不仅是模型训练的数据源头,也是 PSI 漂移巡查的直接扫描对象。理解因子库的结构与存储方式,是搭建自动化监控体系的第一步。
2.1 什么是因子库
因子库是一个结构化存储的集合,用于统一管理从原始数据加工而来的衍生变量。每个因子通常包含以下元数据与数据内容:
| 维度 | 说明 | 示例 |
|---|---|---|
| 因子名称 | 唯一标识符,用于模型与监控系统引用 | loan_amt_ratio |
| 业务含义 | 描述因子代表的业务逻辑 | 贷款金额与收入的比例 |
| 计算逻辑 | SQL 或 Python 表达式,用于生成因子值 | loan_amt / income |
| 数据类型 | 连续型、离散型、布尔型等 | float |
| 时间戳 | 因子值的计算日期或批次时间 | 2025-03-01 |
| 版本号 | 因子逻辑变更的版本标记 | v2.1 |
关键认知: 因子库 ≠ 原始数据仓库。原始数据经过清洗、聚合、衍生后才进入因子库;因子库是面向模型与监控的“半成品”层。
2.2 因子库的常见结构
根据业务场景与查询模式,因子库主要采用两种表结构:宽表与窄表。两种结构在存储效率、查询性能与维护成本上各有优劣。
2.2.1 宽表结构
宽表将每个因子作为一列,一行代表一个样本(如一个用户、一笔订单)在某个时间点的全部因子值。
-- 宽表示例:user_factor_wide
user_id | dt | loan_amt_ratio | age_group | income_level | credit_score
---------|------------|------------------|-------------|----------------|--------------
U001 | 2025-03-01 | 0.45 | 30-35 | high | 720
U002 | 2025-03-01 | 0.62 | 25-30 | medium | 680
U003 | 2025-03-01 | 0.33 | 35-40 | low | 650
| 优点 | 缺点 |
|---|---|
| 查询单样本所有因子时速度极快(一次 IO) | 新增因子需要修改表结构(加列),DDL 成本高 |
| 适合模型推理时的批量特征读取 | 因子数量过多时(如 500+ 列),存储膨胀,维护困难 |
| 直观易理解,非技术人员也能直接查看 | 空值稀疏时浪费大量存储空间 |
2.2.2 窄表结构
窄表将因子名与因子值作为键值对存储,一行只记录一个因子。通常使用“实体-属性-值”(EAV)模型。
-- 窄表示例:user_factor_narrow
user_id | dt | factor_name | factor_value
---------|------------|------------------|--------------
U001 | 2025-03-01 | loan_amt_ratio | 0.45
U001 | 2025-03-01 | age_group | 30-35
U001 | 2025-03-01 | income_level | high
U002 | 2025-03-01 | loan_amt_ratio | 0.62
U002 | 2025-03-01 | age_group | 25-30
| 优点 | 缺点 |
|---|---|
| 新增因子无需改表结构,直接插入新行即可 | 查询单样本全部因子需要多次 JOIN 或行转列,性能较低 |
| 存储紧凑,空值不占物理空间 | 数据行数膨胀(因子数 × 样本数),索引压力大 |
| 适合因子频繁迭代、动态扩展的场景 | 对 BI 工具不友好,通常需要物化视图辅助 |
实践建议: 多数风控团队采用“宽表为主、窄表为辅”的策略。生产监控使用宽表做批量 PSI 计算;因子开发与版本管理使用窄表记录变更历史。
2.3 因子库的存储方式
因子库的物理存储通常依赖以下三种方式,选择依据是数据规模、查询延迟与成本预算:
- 关系型数据库(RDBMS):如 MySQL、PostgreSQL。适合因子数量少(< 200)、查询并发高的场景。宽表结构下,配合索引可达到毫秒级单行查询。
- 列式存储引擎:如 ClickHouse、Doris。适合宽表结构下的大批量因子扫描。PSI 监控需要按时间分区读取全量因子分布,列式存储的压缩与聚合性能远优于行存。
- 分布式文件系统 + 分区表:如 Hive / Iceberg 按日期分区存储。适合超大规模因子库(千亿行级别),配合 Parquet 格式可实现高压缩比,但查询延迟通常在秒级到分钟级。
避坑提醒: 不要将因子库直接建在 OLTP 业务库上。因子计算与监控查询会大量扫描数据,极易引发业务库锁竞争与性能抖动。因子库应独立部署,或使用只读副本。
2.4 因子库结构对比总览
下表从监控巡查的视角,对比宽表与窄表在 PSI 计算场景下的表现:
| 对比维度 | 宽表 | 窄表 |
|---|---|---|
| PSI 批量计算速度 | 快(一次扫描获取所有因子分布) | 慢(需按因子名过滤 + 多次聚合) |
| 新增因子对监控的影响 | 需修改 ETL 与监控脚本(加列) | 自动纳入,只需在监控配置中注册新因子名 |
| 历史回溯难度 | 低(列固定,直接 WHERE 时间范围) | 高(需行转列,且因子名可能变更) |
| 存储空间(含空值) | 高(每列固定长度,空值占位) | 低(无空值不占行) |
| 推荐场景 | 稳定因子库 + 高频 PSI 巡查 | 动态因子库 + 低频全量校验 |
2.5 因子库与 PSI 监控的衔接
在后续章节中,我们将基于因子库的宽表结构,按以下流程执行 PSI 漂移巡查:
- 基准分布提取:从因子库宽表中,按时间窗口(如最近 30 天)提取每个因子的分箱分布。
- 当前分布提取:按巡查周期(如每日)提取最新批次数据的因子分布。
- PSI 计算:逐因子计算基准与当前的分布差异,输出 PSI 值。
- 告警与归因:PSI 超过阈值的因子进入告警列表,结合窄表的历史版本追溯逻辑变更。
核心结论: 因子库的结构设计直接决定了 PSI 监控的计算效率与维护成本。宽表适合“快照式”批量扫描,窄表适合“追溯式”版本管理。在实际工程中,两者通常并存,互为补充。