3. 数据准备与特征工程:催收相关数据源与特征衍生
催收评分卡的核心在于从多源异构数据中提取能够预测还款概率的稳定特征。本章聚焦于催收场景下的数据源整合、特征衍生逻辑与分箱方法,确保后续模型既能捕捉风险信号,又具备业务可解释性。
3.1 催收相关数据源
催收评分卡的数据源通常分为三大类:还款行为数据、联系信息数据与外部征信数据。下表对比了三类数据源的核心字段、更新频率与典型用途:
| 数据源类别 | 核心字段示例 | 更新频率 | 典型用途 |
|---|---|---|---|
| 还款行为数据 | 逾期天数、还款金额、还款次数、承诺还款履约率 | 每日/实时 | 评估当前逾期严重程度与还款意愿 |
| 联系信息数据 | 联系人接通率、通话时长、号码变更次数、失联天数 | 每日 | 判断失联风险与可联性 |
| 外部征信数据 | 多头借贷数、征信查询次数、历史逾期记录、黑名单命中 | 每周/月 | 补充全局信用画像与欺诈风险 |
数据源整合原则: 催收评分卡的特征应优先使用近 30 天内的行为数据,因为催收决策对时效性高度敏感。外部征信数据虽然稳定,但更新滞后,适合作为长期信用维度的补充。
3.2 特征衍生方法论
原始字段通常无法直接用于建模,需要通过衍生创造更具预测力的特征。催收场景下,特征衍生主要围绕时间窗口、比率、趋势与交叉组合四个方向展开。
3.2.1 时间窗口统计特征
基于固定时间窗口(如 7 天、14 天、30 天)对行为数据进行聚合统计,捕捉短期行为模式:
- 最大值/最小值: 近 7 天最大逾期天数、近 30 天最小还款金额。
- 均值/标准差: 近 14 天日均通话时长、近 30 天还款金额波动率。
- 计数/占比: 近 7 天接通次数、近 30 天承诺还款履约占比。
3.2.2 比率与趋势特征
比率特征消除量纲影响,趋势特征反映行为变化方向:
- 还款率: 近 30 天实际还款金额 / 应还金额。
- 失联率: 近 7 天未接通次数 / 总外呼次数。
- 斜率特征: 近 14 天逾期天数的线性回归斜率,正值表示恶化。
3.2.3 交叉组合特征
将不同数据源的特征进行组合,往往能产生强预测力特征:
- 还款行为 × 联系信息: 近 7 天接通率 × 近 7 天还款次数(高接通+高还款 = 优质客户)。
- 外部征信 × 还款行为: 多头借贷数 × 逾期天数(多头+高逾期 = 高风险)。
特征衍生避坑: 避免使用未来信息(如“未来 7 天是否还款”作为特征),避免衍生特征数量过多导致过拟合。建议初始衍生特征控制在 200~500 个,后续通过特征筛选压缩至 30~50 个。
3.3 特征分箱方法
分箱是将连续变量或高基数离散变量转化为有限个区间(箱)的过程,目的是增强模型稳定性与可解释性。催收评分卡常用以下三种分箱方法:
| 分箱方法 | 原理 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 等距分箱 | 按数值区间等宽划分 | 分布均匀的连续变量(如年龄) | 简单直观,易于实现 | 对异常值敏感,箱内样本可能不均 |
| 等频分箱 | 按样本数量等比例划分 | 长尾分布变量(如收入、金额) | 箱内样本量均衡,稳定性好 | 可能将相似值分到不同箱 |
| 最优分箱(决策树/卡方) | 基于目标变量(是否还款)的分布差异最大化 | 需要高区分度的关键特征 | 区分能力最强,业务解释性好 | 计算成本高,需防止过拟合 |
分箱质量检查: 每个箱的样本占比不应低于 5%,箱内坏账率(逾期率)应呈现单调性(如逾期天数越高,还款概率越低),否则需要手动调整箱边界。
3.4 特征工程与分箱流程
下图展示了从原始数据到分箱特征的整体流程,包含数据源接入、特征衍生、分箱处理与质量验证四个阶段:
3.5 分箱后的特征评估指标
分箱完成后,需通过以下指标评估每个特征的质量,决定是否入模:
- IV(Information Value,信息量): 衡量特征对目标变量的区分能力。IV < 0.02 为弱特征,0.02~0.1 为中等,0.1~0.3 为强特征,> 0.3 需警惕过拟合。
- 单调性: 分箱后各箱的坏账率应呈现单调递增或递减趋势,否则说明分箱不合理或特征存在噪声。
- 缺失率: 特征缺失率超过 50% 时,需谨慎入模,或单独设置“缺失”箱。
实战建议: 在催收评分卡中,优先保留 IV > 0.02 且单调性良好的特征。对于 IV 极高(> 0.5)的特征,建议检查是否包含了未来信息或与目标变量存在直接逻辑关联(如“是否已还款”作为特征)。
3.6 特征工程代码示例
以下 Python 代码展示了基于 30 天窗口的还款行为特征衍生与等频分箱过程:
import pandas as pd
import numpy as np
from sklearn.preprocessing import KBinsDiscretizer
# 示例数据:还款行为表
df = pd.DataFrame({
'user_id': [1, 1, 1, 2, 2, 3],
'due_date': pd.to_datetime(['2024-01-05', '2024-01-12', '2024-01-19',
'2024-01-07', '2024-01-14', '2024-01-10']),
'overdue_days': [5, 10, 15, 2, 8, 30],
'payment_amount': [1000, 0, 500, 2000, 1500, 0]
})
# 特征衍生:近30天最大逾期天数、还款次数
def derive_features(group):
return pd.Series({
'max_overdue_30d': group['overdue_days'].max(),
'payment_count_30d': (group['payment_amount'] > 0).sum(),
'total_payment_30d': group['payment_amount'].sum()
})
feature_df = df.groupby('user_id').apply(derive_features).reset_index()
print("衍生特征:\n", feature_df)
# 等频分箱:将 max_overdue_30d 分为 4 箱
discretizer = KBinsDiscretizer(n_bins=4, encode='ordinal', strategy='quantile')
feature_df['overdue_bin'] = discretizer.fit_transform(
feature_df[['max_overdue_30d']]
).astype(int)
print("\n分箱结果:")
print(feature_df[['user_id', 'max_overdue_30d', 'overdue_bin']])
分箱后处理: 建议将分箱结果映射为 WOE(Weight of Evidence,证据权重)值,作为模型输入。WOE 转换能线性化特征与目标变量的关系,提升逻辑回归等线性模型的表现。