3、数据探索与质量分析

在特征工程正式启动之前,必须对原始数据进行全面的探索性数据分析(EDA)与质量审计。这一阶段的目标是识别数据中的缺失模式、异常分布、变量形态以及多重共线性风险,为后续的缺失值填补、异常值截尾和特征筛选提供决策依据。

核心原则:数据质量分析不是一次性检查,而是一个迭代过程。每次特征处理后都应重新评估数据分布与相关性,确保变换后的特征仍符合建模假设。

3.1 缺失值分析

缺失值在信用评分卡原始数据中极为常见,原因包括客户未填写、系统未采集、数据迁移丢失等。缺失分析需要回答三个问题:缺失率有多高?缺失是否随机?缺失与目标变量是否相关?

3.1.1 缺失率统计

首先计算每个特征的缺失比例,按缺失率从高到低排序。通常将缺失率分为三个等级:

缺失率范围 处理策略 示例特征
< 5% 直接删除记录或均值/中位数填补 年龄、收入
5% – 30% 模型预测填补、多重插补或单独编码 工作年限、房产价值
> 30% 考虑删除特征或构造“是否缺失”指示变量 第二联系人收入、征信查询次数
经验提示:对于信用评分卡,缺失本身可能包含信息。例如“工作单位电话缺失”可能暗示客户职业稳定性较低。建议对缺失率在 5%–30% 的特征同时保留原始值和缺失指示变量。

3.1.2 缺失模式可视化

使用矩阵图或热力图展示缺失的联合分布,判断缺失是否为完全随机(MCAR)、随机缺失(MAR)或非随机缺失(MNAR)。对于信用数据,常见的是 MAR 模式——例如“房产价值”缺失往往与“是否有房产”变量相关。

# Python 示例:缺失率计算与缺失矩阵
import pandas as pd
import missingno as msno

# 计算缺失率
missing_rate = df.isnull().mean().sort_values(ascending=False)
print(missing_rate[missing_rate > 0])

# 缺失矩阵可视化(需在 Jupyter 中运行)
msno.matrix(df.sample(500))

3.2 异常值检测

异常值在信用评分卡中通常指极端收入、超高负债率、异常短的信用历史等。异常值会严重影响 WOE 分箱的稳定性,必须在分箱前识别并处理。

3.2.1 常用检测方法

  • Z-Score 法:假设数据近似正态,|Z| > 3 视为异常。适用于对称分布特征。
  • IQR 四分位距法:低于 Q1 - 1.5×IQR 或高于 Q3 + 1.5×IQR 视为异常。对偏态分布更稳健。
  • 业务规则法:根据信贷业务常识设定阈值,如“年龄 < 18 或 > 80”、“年收入 > 1 亿元”等。
方法 适用场景 优点 缺点
Z-Score 近似正态分布 计算简单,有统计基础 对异常值本身敏感,不适用于偏态分布
IQR 法 偏态分布、含离群点 稳健,不受极端值影响 阈值固定,可能漏掉部分异常
业务规则 所有特征 可解释性强,符合风控逻辑 依赖专家经验,可能过于主观
注意:不要机械地删除所有异常值。对于信用评分卡,某些“异常”客户(如极高收入者)可能正是优质客群。建议先对异常值进行单独分箱,观察其与违约率的关系后再决定处理方式。

3.3 数据分布可视化

分布可视化帮助理解特征的集中趋势、离散程度、偏态和峰度,为分箱策略提供直观依据。信用评分卡中最常用的两种图形是直方图和箱线图。

3.3.1 直方图

直方图展示连续变量的频率分布。通过调整 bin 数量,可以观察数据是否呈正态分布、是否存在长尾或双峰。对于信用特征,常见分布形态包括:

  • 右偏分布:收入、贷款金额、信用额度——大部分客户集中在低值区域,少数高值客户形成长尾。
  • 左偏分布:信用评分、还款率——大部分客户集中在高值区域。
  • 双峰分布:年龄(年轻群体和中年群体两个峰值)、负债率(低负债和高负债两个客群)。
# Python 示例:直方图与密度曲线
import matplotlib.pyplot as plt
import seaborn as sns

fig, axes = plt.subplots(1, 2, figsize=(12, 4))
sns.histplot(df['income'], bins=50, kde=True, ax=axes[0])
axes[0].set_title('收入分布(右偏)')

sns.histplot(df['age'], bins=30, kde=True, ax=axes[1])
axes[1].set_title('年龄分布(双峰)')
plt.tight_layout()

3.3.2 箱线图

箱线图同时展示中位数、四分位数和异常值,适合对比不同分组(如好客户 vs 坏客户)的分布差异。在信用评分卡中,常用箱线图检查特征在“违约”与“未违约”两组之间的区分能力。

# Python 示例:分组箱线图
sns.boxplot(x='default_flag', y='credit_limit', data=df)
plt.title('信用额度按违约状态分布对比')
plt.show()
可视化技巧:在直方图上叠加 KDE 密度曲线可以更平滑地观察分布形态;在箱线图中添加散点(swarm plot)可以避免样本量较大时箱线图掩盖数据密度信息。
数据分布与异常检测流程 数据分布与异常检测流程 原始数据 缺失值分析 异常值检测 分布可视化 缺失率统计与排序 缺失模式判断(MCAR/MAR) Z-Score / IQR 计算 业务规则阈值校验 直方图 + KDE 密度曲线 分组箱线图对比 质量分析报告与处理策略 三个分支并行执行,最终汇总为统一报告

3.4 相关性矩阵

相关性矩阵用于检测特征之间的线性相关程度。在信用评分卡中,高度相关的特征(|r| > 0.7)会导致多重共线性,使 WOE 分箱后的逻辑回归系数不稳定,降低模型可解释性。

3.4.1 计算方法

对于连续变量,使用 Pearson 相关系数;对于有序分类变量,使用 Spearman 秩相关系数。信用评分卡中通常混合使用两种方法:

  • Pearson:适用于近似正态分布的连续特征,如年龄、信用额度。
  • Spearman:适用于偏态分布或有序特征,如收入等级、信用评分区间。

3.4.2 可视化与解读

热力图是展示相关性矩阵最直观的方式。颜色深浅表示相关强度,通常使用红蓝渐变色:红色表示正相关,蓝色表示负相关,颜色越深相关性越强。

# Python 示例:相关性矩阵热力图
import seaborn as sns
import matplotlib.pyplot as plt

# 计算相关系数矩阵
corr_matrix = df.corr(method='spearman')

# 绘制热力图
plt.figure(figsize=(10, 8))
sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='RdBu_r', 
            vmin=-1, vmax=1, center=0, square=True)
plt.title('特征相关性矩阵热力图')
plt.tight_layout()
plt.show()
多重共线性处理原则:当发现两个特征相关系数 |r| > 0.7 时,建议保留与目标变量(违约状态)相关性更高或业务意义更明确的一个,删除另一个。例如“月收入”与“年收入”高度相关,通常保留年收入。切勿同时保留,否则会导致逻辑回归的系数估计方差膨胀。

3.4.3 与目标变量的相关性

除了特征之间的相关性,还需要计算每个特征与目标变量(违约/非违约)的相关性。这有助于初步筛选强相关特征,并为后续的 WOE 分箱提供方向。通常使用 点二列相关系数 或 信息价值(IV) 来评估。

相关性强度 |r| 范围 IV 范围 特征筛选建议
弱 0 – 0.1 < 0.02 考虑删除
中等 0.1 – 0.3 0.02 – 0.1 保留,进一步分箱
强 0.3 – 0.5 0.1 – 0.3 高价值特征,优先保留
极强 > 0.5 > 0.3 需检查是否过度拟合或数据泄露
相关性矩阵与特征筛选决策 相关性矩阵与特征筛选决策 相关性矩阵热力图(示意) 1.00 0.65 -0.42 -0.18 0.05 0.65 1.00 0.08 -0.25 -0.12 -0.42 0.08 1.00 0.55 -0.30 -0.18 -0.25 0.55 1.00 -0.38 0.05 -0.12 -0.30 -0.38 1.00 强正相关 弱相关 强负相关 特征筛选决策流程 计算所有特征两两相关系数 |r| > 0.7 的特征对标记为高相关 比较与目标变量的 IV 或相关系数 保留 IV 更高 / 业务意义更强的特征 输出:低相关特征子集,用于分箱建模

3.5 质量分析报告模板

完成上述分析后,建议输出一份标准化的数据质量报告,作为特征处理的基线文档。报告应包含以下核心内容:

  1. 数据概览:样本量、特征数量、目标变量分布(违约率)。
  2. 缺失分析表:每个特征的缺失率、缺失模式判断结果。
  3. 异常值统计:每个特征的异常值数量、占比、检测方法。
  4. 分布特征:均值、中位数、标准差、偏度、峰度,以及直方图/箱线图快照。
  5. 相关性矩阵:高相关特征对列表(|r| > 0.7),以及每个特征与目标变量的相关系数。
  6. 初步处理建议:基于上述分析,给出每个特征的缺失填补方法、异常值截尾阈值、是否删除或保留的建议。
最佳实践:将质量分析