3. 特征工程基础:特征类型、质量评估与缺失值异常值处理

在催收模型中,原始数据无法直接喂给 LightGBM。特征工程是将原始数据转化为模型可理解、可学习的数值特征的过程。本章将系统讲解催收场景下的特征类型划分、质量评估方法以及缺失值与异常值的处理策略,为后续特征筛选打下坚实基础。

3.1 特征类型:数值型、类别型、时序型

催收数据中的特征可按其数学性质分为三大类,不同类型决定了后续编码与变换方式。

特征类型 定义 催收场景举例 LightGBM 处理要点
数值型 连续或离散的数值,有大小和顺序意义 逾期天数、欠款金额、历史还款次数、年龄 可直接输入;建议做分箱或归一化以提升鲁棒性
类别型 有限个离散取值,无大小顺序(或顺序无意义) 城市、职业、产品类型、催收员ID 需转换为整数编码;高基数类别建议使用计数编码或目标编码
时序型 与时间顺序相关的特征,包含趋势、周期、间隔 最近联系时间、逾期起始日期、账单日 需提取时间差、星期几、月份、节假日标志等衍生特征
实战提示: 催收模型中,时序型特征往往比静态数值型特征更重要。例如“距离上次还款的天数”比“总欠款金额”更能预测短期还款意愿。建议将原始时间戳转化为相对时间差后再输入模型。

3.2 特征质量评估

特征质量直接影响模型上限。在催收场景中,我们通常从以下四个维度评估每个特征的质量:

  • 覆盖率: 特征非空比例。覆盖率低于 60% 的特征需谨慎使用,除非缺失本身具有业务含义。
  • 区分度: 特征在不同目标类别(如“已还款” vs “未还款”)上的分布差异。常用指标为 IV 值(信息量)或 KS 统计量。
  • 稳定性: 特征分布随时间的变化程度。使用 PSI(群体稳定性指标)衡量,PSI > 0.25 的特征建议剔除。
  • 相关性: 特征与目标变量之间的关联强度,以及特征之间的多重共线性。催收模型中,与“逾期天数”高度相关的特征需注意去冗余。
催收特征质量速查表:
✅ 覆盖率 > 80% → 优质
✅ IV > 0.1 → 有区分力
✅ PSI < 0.1 → 高度稳定
✅ 相关系数 |r| < 0.8 → 无严重共线性

3.3 缺失值处理

催收数据中缺失值普遍存在,原因包括:客户未填写、系统未采集、数据源合并丢失等。处理策略需结合业务含义与模型特性。

3.3.1 缺失值类型判断

  • 完全随机缺失(MCAR): 缺失与任何变量无关。可直接删除或填充均值/中位数。
  • 随机缺失(MAR): 缺失与其他观测变量相关。例如高逾期客户更可能缺失联系电话。建议使用模型预测填充。
  • 非随机缺失(MNAR): 缺失与缺失值本身相关。例如“收入”字段,高收入者可能故意不填。此时缺失本身可作为重要特征。

3.3.2 催收场景推荐处理方案

特征类型 缺失率 < 5% 缺失率 5%–30% 缺失率 > 30%
数值型 中位数填充 中位数填充 + 新增“是否缺失”标志 保留缺失标志,数值填充为 -999 或 0(需业务确认)
类别型 众数填充 众数填充 + 新增“缺失”类别 将“缺失”作为独立类别编码
时序型 前向填充或线性插值 前向填充 + 缺失时长特征 仅保留缺失时长特征,原始值丢弃
避坑提醒: 不要对催收数据中的“逾期天数”做均值填充!逾期天数的缺失往往意味着该笔贷款尚未进入逾期阶段,此时应填充为 0 而非均值。务必先理解缺失的业务含义。

3.4 异常值处理

异常值在催收数据中常见于:欠款金额极端高、联系次数异常多、年龄超出合理范围等。异常值会拉偏 LightGBM 的分裂点,导致模型泛化能力下降。

3.4.1 异常值检测方法

  • IQR 法: 超出 Q1 - 1.5×IQR 或 Q3 + 1.5×IQR 的值视为异常。适用于近似正态分布的特征。
  • Z-Score 法: |Z| > 3 视为异常。适用于数据量较大且分布对称的场景。
  • 业务规则法: 例如“年龄 < 18 或 > 70”、“欠款金额为负数”等直接定义为异常。
  • 孤立森林: 无监督方法,适合高维特征空间中的异常检测。

3.4.2 异常值处理策略

策略 适用场景 催收案例
截断(Winsorize) 特征分布长尾,异常值数量少 将“欠款金额”上限设为 99% 分位数
分箱 异常值有业务含义,但数值不稳定 将“联系次数”分为 0、1-3、4-10、>10 四档
单独编码 异常值代表特殊群体 “年龄 > 65”单独标记为“高龄客群”
删除 确认是录入错误且样本量充足 “逾期天数 = -5”明显错误,直接删除该样本
催收实战建议: 对于“欠款金额”这类长尾分布特征,推荐使用 对数变换 + 截断 的组合方式。先取 log(1+x) 压缩尺度,再在 99.5% 分位数处截断,既能保留区分度,又能抑制极端值对 LightGBM 分裂的干扰。

3.5 特征类型与处理流程总览

下图总结了从原始特征到清洗后特征的完整处理流程,帮助你在实际项目中按步骤操作:

催收特征处理流程总览 催收特征处理流程总览 原始特征集合 步骤1:特征类型识别 数值型特征 类别型特征 时序型特征 质量评估 质量评估 质量评估 缺失/异常处理 缺失/异常处理 缺失/异常处理 清洗后特征集合

3.6 代码实战:缺失值与异常值处理示例

以下代码展示了在 Python 中对催收数据集进行缺失值填充与异常值截断的典型操作:

import pandas as pd
import numpy as np

# 示例数据:催收样本
df = pd.DataFrame({
    '逾期天数': [15, 30, None, 60, 90, None, 45, 120, 180, 5],
    '欠款金额': [2000, 5000, 3000, 15000, 80000, 4000, 6000, 200000, 3500, 2500],
    '年龄': [28, 35, 42, None, 55, 31, 29, 48, 22, 38],
    '城市': ['北京', '上海', None, '广州', '深圳', '北京', '上海', None, '广州', '深圳']
})

# 1. 缺失值处理
# 数值型:中位数填充 + 缺失标志
for col in ['逾期天数', '年龄']:
    df[f'{col}_缺失标志'] = df[col].isna().astype(int)
    df[col].fillna(df[col].median(), inplace=True)

# 类别型:众数填充 + 缺失类别
df['城市'].fillna('未知', inplace=True)

# 2. 异常值处理:IQR 截断
def winsorize_series(s, lower=0.01, upper=0.99):
    q_low = s.quantile(lower)
    q_high = s.quantile(upper)
    return s.clip(lower=q_low, upper=q_high)

df['欠款金额_截断'] = winsorize_series(df['欠款金额'])

# 3. 时序特征衍生(假设有日期字段)
# df['逾期起始日'] = pd.to_datetime(df['逾期起始日'])
# df['逾期持续天数'] = (pd.Timestamp.today() - df['逾期起始日']).dt.days

print("处理完成,特征维度:", df.shape)
print(df.head())
代码要点:
• 对“逾期天数”使用中位数填充,避免均值被极端值拉偏。
• 对“欠款金额”做分位数截断,保留 99% 的正常样本分布。
• 类别型特征“城市”将缺失值作为独立类别“未知”处理,保留缺失信息。
• 建议在实际项目中为每个数值型特征都生成一个“缺失标志”特征,LightGBM 可以自动学习缺失模式。

3.7 本章小结

特征工程是催收模型成功的关键起点。通过本章学习,你应掌握:

  • 区分数值型、类别型、时序型特征,并针对不同类型选择编码与变换方式。
  • 从覆盖率、区分度、稳定性、相关性四个维度评估特征质量。
  • 根据缺失率与业务含义,选择中位数填充、众数填充、缺失标志或独立类别等策略。
  • 使用 IQR 截断、分箱或业务规则处理异常值,避免极端值干扰模型分裂。