3. 数据准备与特征工程:数据清洗、缺失值处理、异常值检测、特征分箱与WOE编码

在信用评分模型开发中,数据准备与特征工程占据整个项目60%以上的工作量。原始信贷数据通常包含噪声、缺失、异常以及非线性关系,直接建模会导致模型不稳定、区分能力下降。本节将系统讲解从原始数据到建模特征的核心处理流程。

3.1 数据清洗:构建高质量样本的基础

数据清洗的目标是消除原始数据中的格式错误、逻辑矛盾与重复记录,确保后续处理的可靠性。

清洗类型常见问题处理方法
格式统一日期格式不一致(2024/01/01 vs 2024-01-01)统一转换为标准日期格式
逻辑校验年龄为负数、贷款金额为0结合业务规则剔除或修正
重复记录同一客户多次申请,ID重复按申请时间保留最新记录
异常字符数值字段包含字母、特殊符号正则匹配清洗或置为缺失
实战提示:在清洗阶段保留原始字段副本,建立数据血缘记录。每次清洗操作都应有明确的业务规则文档,避免"黑箱清洗"导致模型上线后无法追溯数据问题。

3.2 缺失值处理:平衡信息损失与偏差

信贷数据中缺失值普遍存在,处理方式直接影响模型性能。根据缺失机制(MCAR、MAR、MNAR)选择合适策略。

  • 删除法:当缺失比例低于5%且为随机缺失时,可直接删除缺失样本或特征。
  • 均值/中位数填充:适用于数值型特征,简单快速但会降低方差。
  • 众数填充:适用于分类型特征,如婚姻状况、学历等级。
  • 模型预测填充:使用KNN、随机森林等算法预测缺失值,精度高但计算成本大。
  • 缺失值单独成类:将缺失视为一个独立类别,特别适合WOE编码场景。
信用评分最佳实践:对于信贷申请数据,建议将缺失值单独作为一个分箱类别参与WOE编码。这种方式保留了缺失样本的分布信息,且不会引入填充偏差,在评分卡建模中表现稳定。

3.3 异常值检测:识别极端风险样本

异常值在信用评分中可能代表欺诈申请或极端风险客户,需要谨慎处理。

异常值检测方法对比 Z-Score 方法 假设数据服从正态分布 |Z| > 3 视为异常 IQR 四分位法 Q1 - 1.5×IQR 以下 Q3 + 1.5×IQR 以上 业务规则法 年龄 < 18 或 > 70 收入为0或负值 异常值处理策略 截尾处理(Winsorize)→ 替换为边界值 单独分箱 → 将异常值归为独立类别
注意:不要机械地删除所有异常值。在信用评分中,某些"异常"客户(如超高收入、极低负债率)可能是优质客户,直接删除会损失模型对好客户的区分能力。建议先分箱观察异常值所在箱的坏账率,再决定处理方式。

3.4 特征分箱:捕捉非线性关系

特征分箱是将连续变量或离散变量划分为若干区间(箱),是评分卡建模的核心步骤。分箱质量直接影响WOE编码效果和模型稳定性。

常用分箱方法

分箱方法原理优点缺点
等距分箱按数值范围均匀划分简单直观样本分布不均,空箱风险
等频分箱每箱包含相同样本数箱内样本均衡边界值可能不自然
决策树分箱用单变量决策树寻找最优切分点自动捕捉非线性过拟合风险
卡方分箱基于卡方检验合并相邻区间统计显著性驱动计算复杂度较高
分箱原则:每个箱至少包含5%的样本;坏账率(Bad Rate)在相邻箱之间应呈现单调性;箱数控制在5~10个之间;特殊值(如0、缺失)单独成箱。

3.5 WOE编码:将分箱转化为模型输入

WOE(Weight of Evidence,证据权重)是评分卡模型中最常用的特征编码方式,将分箱后的类别转化为反映好坏客户分布差异的数值。

WOE计算公式

WOE_i = ln( (Bad_i / Bad_total) / (Good_i / Good_total) )

其中:
- Bad_i  = 第i个箱中的坏客户数
- Good_i = 第i个箱中的好客户数
- Bad_total  = 全部坏客户数
- Good_total = 全部好客户数

WOE编码的核心优势

  • 线性化处理:将非线性关系转化为线性关系,适配逻辑回归模型。
  • 缺失值包容:缺失值作为独立箱参与编码,无需额外填充。
  • 异常值鲁棒:极端值被分箱吸收,不会过度影响模型。
  • 业务可解释:WOE正值表示该箱好客户占比更高,负值表示坏客户占比更高。
特征分箱与WOE编码流程 原始特征 连续/离散值 特征分箱 等频/决策树/卡方 WOE编码 ln(坏占比/好占比) 模型输入 WOE数值特征 分箱与WOE编码示例:年龄特征 分箱区间 [18, 25) [25, 35) [35, 45) [45, 55) [55, 65] 坏账率 12.5% 8.2% 4.1% 3.5% 7.8% WOE值 -0.42 -0.18 0.35 0.48 -0.22

WOE编码的Python实现

import pandas as pd
import numpy as np

def woe_encode(df, feature, target, bins=5):
    """
    对特征进行分箱并计算WOE编码
    
    Parameters:
    df: DataFrame,包含特征和目标变量
    feature: str,特征名称
    target: str,目标变量名称(0=好客户,1=坏客户)
    bins: int,分箱数量
    
    Returns:
    woe_dict: dict,每个箱对应的WOE值
    """
    # 等频分箱
    df['bin'] = pd.qcut(df[feature], q=bins, duplicates='drop')
    
    # 计算每个箱的好坏分布
    grouped = df.groupby('bin')[target].agg(['count', 'sum'])
    grouped.columns = ['total', 'bad']
    grouped['good'] = grouped['total'] - grouped['bad']
    
    # 计算WOE
    total_bad = grouped['bad'].sum()
    total_good = grouped['good'].sum()
    
    grouped['bad_pct'] = grouped['bad'] / total_bad
    grouped['good_pct'] = grouped['good'] / total_good
    grouped['woe'] = np.log(grouped['good_pct'] / grouped['bad_pct'])
    
    # 处理无穷值
    grouped['woe'] = grouped['woe'].replace([np.inf, -np.inf], 0)
    
    return grouped['woe'].to_dict()
实战技巧:WOE编码完成后,建议计算每个特征的IV值(Information Value,信息量)来评估特征区分能力。IV < 0.02为弱特征,0.02~0.1为中等,0.1~0.3为强特征,> 0.5需警惕过拟合。

3.6 本章小结

数据准备与特征工程是信用评分模型成败的关键环节。数据清洗确保数据质量,缺失值处理平衡信息损失,异常值检测识别极端风险,特征分箱捕捉非线性关系,WOE编码将分箱结果转化为线性模型可用的数值特征。每一步都需要结合业务逻辑和数据分布做出合理决策,而非机械套用统计方法。