SQL 在风控样本校验中的角色
在风控模型开发与监控的生命周期中,样本偏差校验是确保模型稳定性和预测能力的关键环节。SQL 凭借其对结构化数据的高效处理能力,成为连接原始数据仓库与风控校验逻辑的核心工具。本章将系统阐述 SQL 在风控样本校验中的独特优势、典型数据仓库与风控表结构设计,以及标准化的 SQL 校验流程。
2.1 SQL 在风控样本校验中的核心优势
相比于 Python、R 等通用分析工具,SQL 在风控样本校验场景中具备以下不可替代的优势:
| 优势维度 | 具体说明 | 风控场景示例 |
|---|---|---|
| 数据原生性 | 风控数据通常存储在数据仓库或数据湖中,SQL 无需数据迁移即可直接查询 | 直接从 Hive/ClickHouse 中提取 3 个月逾期样本 |
| 大规模处理能力 | SQL 引擎(如 SparkSQL、Presto)可分布式处理亿级数据,远超单机内存限制 | 对 5 亿条交易流水进行时间窗口切片 |
| 集合运算简洁性 | 通过 JOIN、UNION、EXCEPT 等操作快速完成样本交叉验证 | 校验训练集与 OOT 时间段的分布一致性 |
| 可审计与可复现 | SQL 脚本天然具备版本控制能力,便于风控合规审计 | 保留每次校验的 SQL 快照用于监管检查 |
| 与调度系统集成 | SQL 可直接嵌入 Airflow、DolphinScheduler 等任务流 | 每日凌晨自动执行样本偏差监控脚本 |
关键认知:SQL 在风控校验中的角色不是替代统计建模工具,而是作为数据准备与偏差量化的第一道关卡。80% 的样本偏差问题可以通过 5~10 行 SQL 聚合语句发现。
2.2 数据仓库与风控表结构设计
风控样本偏差校验依赖清晰的数据分层与表结构设计。典型的风控数据仓库采用 ODS → DWD → DWS → ADS 四层架构,其中与样本校验直接相关的核心表包括:
表命名规范建议:采用 分层_主题_业务_时间粒度 格式,例如 dws_risk_loan_di 表示风险主题下的贷款明细日表。
2.2.1 核心风控表结构清单
| 表名(示例) | 分层 | 核心字段 | 校验用途 |
|---|---|---|---|
dwd_risk_loan_apply_di |
DWD | apply_id, user_id, apply_time, loan_amt, term, product_cd | 申请样本量、时间分布校验 |
dws_risk_user_profile_di |
DWS | user_id, age, gender, income_level, credit_score, hist_overdue_cnt | 用户特征分布偏差校验 |
ads_risk_model_sample_df |
ADS | sample_id, model_ver, sample_type, feature_json, label, weight | 建模样本标签与权重校验 |
dwd_risk_performance_di |
DWD | loan_id, perf_date, ovd_status, ovd_days, recovery_amt | 表现期标签稳定性校验 |
ads_risk_psi_monitor_df |
ADS | monitor_date, feature_name, psi_value, base_dist, curr_dist | PSI 群体稳定性指标计算 |
2.2.2 风控数据仓库分层架构
下图展示了风控数据仓库的分层结构及各层在样本校验中的职责:
常见陷阱:许多团队直接在 ODS 层进行样本校验,导致数据质量问题(重复、空值、时间戳异常)污染校验结果。务必在 DWD 层完成标准化清洗后再执行偏差分析。
2.3 SQL 校验的基本流程
标准化的 SQL 样本偏差校验流程包含 5 个核心步骤,覆盖从数据接入到结果输出的完整链路:
2.3.1 流程总览
2.3.2 各步骤核心 SQL 示例
步骤 1:数据接入 — 从 DWD 层提取训练集与 OOT 样本:
-- 训练集:2024年1月~6月申请样本
CREATE TABLE temp_train_sample AS
SELECT apply_id, user_id, apply_time, loan_amt, term
FROM dwd_risk_loan_apply_di
WHERE apply_time >= '2024-01-01' AND apply_time < '2024-07-01'
AND is_valid = 1;
-- OOT 集:2024年7月~9月申请样本
CREATE TABLE temp_oot_sample AS
SELECT apply_id, user_id, apply_time, loan_amt, term
FROM dwd_risk_loan_apply_di
WHERE apply_time >= '2024-07-01' AND apply_time < '2024-10-01'
AND is_valid = 1;
步骤 2:质量清洗 — 检查并处理关键字段的空值与异常:
-- 空值检测
SELECT 'train' AS sample_type,
COUNT(*) AS total_cnt,
SUM(CASE WHEN loan_amt IS NULL THEN 1 ELSE 0 END) AS null_loan_amt,
SUM(CASE WHEN term <= 0 THEN 1 ELSE 0 END) AS invalid_term
FROM temp_train_sample
UNION ALL
SELECT 'oot' AS sample_type,
COUNT(*),
SUM(CASE WHEN loan_amt IS NULL THEN 1 ELSE 0 END),
SUM(CASE WHEN term <= 0 THEN 1 ELSE 0 END)
FROM temp_oot_sample;
步骤 3:维度统计 — 按时间粒度统计样本量分布:
-- 按月统计训练集与 OOT 样本量
SELECT DATE_FORMAT(apply_time, 'yyyy-MM') AS month,
COUNT(*) AS sample_cnt
FROM temp_train_sample
GROUP BY DATE_FORMAT(apply_time, 'yyyy-MM')
ORDER BY month;
步骤 4:偏差量化 — 计算特征 PSI(群体稳定性指标):
-- 以 loan_amt 分箱为例计算 PSI
WITH base_dist AS (
SELECT CASE WHEN loan_amt < 5000 THEN '0-5k'
WHEN loan_amt < 20000 THEN '5k-20k'
ELSE '20k+' END AS bucket,
COUNT(*) AS base_cnt
FROM temp_train_sample
GROUP BY CASE WHEN loan_amt < 5000 THEN '0-5k'
WHEN loan_amt < 20000 THEN '5k-20k'
ELSE '20k+' END
),
curr_dist AS (
SELECT CASE WHEN loan_amt < 5000 THEN '0-5k'
WHEN loan_amt < 20000 THEN '5k-20k'
ELSE '20k+' END AS bucket,
COUNT(*) AS curr_cnt
FROM temp_oot_sample
GROUP BY CASE WHEN loan_amt < 5000 THEN '0-5k'
WHEN loan_amt < 20000 THEN '5k-20k'
ELSE '20k+' END
)
SELECT b.bucket,
b.base_cnt / SUM(b.base_cnt) OVER() AS base_pct,
c.curr_cnt / SUM(c.curr_cnt) OVER() AS curr_pct,
(b.base_cnt / SUM(b.base_cnt) OVER() - c.curr_cnt / SUM(c.curr_cnt) OVER())
* LN(b.base_cnt / SUM(b.base_cnt) OVER() / NULLIF(c.curr_cnt / SUM(c.curr_cnt) OVER(), 0)) AS psi_component
FROM base_dist b
JOIN curr_dist c ON b.bucket = c.bucket;
步骤 5:结果输出 — 将校验结果写入 ADS 监控表:
INSERT INTO ads_risk_psi_monitor_df
(monitor_date, feature_name, psi_value, base_period, curr_period, alert_flag)
SELECT CURRENT_DATE AS monitor_date,
'loan_amt' AS feature_name,
ROUND(SUM(psi_component), 6) AS psi_value,
'2024H1' AS base_period,
'2024Q3' AS curr_period,
CASE WHEN SUM(psi_component) > 0.1 THEN 1 ELSE 0 END AS alert_flag
FROM (
-- 上述 PSI 计算子查询
) t;
流程要点总结:SQL 校验流程的核心在于 标准化 与 可重复。建议将上述 5 步封装为存储过程或 SQL 模板,每次模型迭代或数据更新时自动触发执行,形成持续监控闭环。
2.4 本章小结
- SQL 优势:数据原生、大规模处理、集合运算简洁、可审计、易集成,是风控样本校验的首选工具。
- 表结构设计:遵循 ODS→DWD→DWS→ADS 分层,每层承担不同的校验职责,核心表包括申请明细、用户画像、建模样本、表现期标签和 PSI 监控表。
- 校验流程:数据接入 → 质量清洗 → 维度统计 → 偏差量化 → 结果输出,5 步闭环确保样本偏差可发现、可量化、可告警。