4. 数据探索与质量分析

在构建商户风险评分卡之前,必须对原始数据进行彻底的探索性数据分析(EDA)与质量审计。本章聚焦于数据清洗的三大核心任务:缺失值、异常值与重复值的检测与处理,并通过可视化手段理解各特征的数据分布形态。高质量的数据是评分卡模型稳定性和区分度的基石。

4.1 数据质量三要素检测

数据质量分析通常遵循“先检测、后处理”的原则。下表总结了三种常见数据质量问题的定义、检测方法与初步处理策略:

质量维度 定义 检测方法 初步处理策略
缺失值 数据记录中某个字段为空或为 NULL isnull().sum() / 缺失率统计 删除(行/列)、均值/中位数填充、模型预测填充
异常值 显著偏离正常分布范围的极端值 Z-Score、IQR 规则、箱线图 截尾(Winsorize)、删除、视为缺失值
重复值 完全相同的记录出现多次 duplicated().sum() 保留首条记录并删除其余重复项
关键指标: 对于商户风险数据,缺失率超过 50% 的特征通常建议直接删除;异常值检测中,IQR 方法(下界 Q1-1.5*IQR,上界 Q3+1.5*IQR)对非正态分布数据更为稳健。

4.2 缺失值检测与可视化

缺失值不仅会减少有效样本量,还可能导致模型估计偏差。我们首先通过代码统计每个特征的缺失数量与比例,然后使用矩阵热图直观展示缺失模式。

import pandas as pd
import missingno as msno
import matplotlib.pyplot as plt

# 假设 df 为商户风险数据集
missing_count = df.isnull().sum()
missing_ratio = df.isnull().mean()

# 输出缺失统计
missing_df = pd.DataFrame({'缺失数量': missing_count, '缺失比例': missing_ratio})
missing_df = missing_df[missing_df['缺失数量'] > 0].sort_values('缺失比例', ascending=False)
print(missing_df)

# 可视化缺失模式
msno.matrix(df, figsize=(12, 6), fontsize=10)
plt.title('商户数据缺失值矩阵图', fontsize=14)
plt.show()

缺失值矩阵图中,白色横线代表该位置数据缺失,密集的白色区域表示该特征缺失严重。对于缺失率较低的特征(如 < 5%),可采用中位数填充;对于缺失率中等(5%-30%)的特征,建议结合业务逻辑或使用模型(如 KNN、随机森林)进行预测填充。

4.3 异常值检测与箱线图分析

商户风险数据中的异常值可能代表欺诈交易、录入错误或极端经营状况。箱线图是检测连续变量异常值的经典工具,它基于四分位数自动标记离群点。

import seaborn as sns

# 选取关键连续特征绘制箱线图
features = ['交易金额', '交易笔数', '商户年龄(月)', '负债率']
fig, axes = plt.subplots(2, 2, figsize=(14, 10))

for idx, feat in enumerate(features):
    row, col = divmod(idx, 2)
    sns.boxplot(y=df[feat], ax=axes[row, col], color='#3498db')
    axes[row, col].set_title(f'{feat} 箱线图', fontsize=12)
    axes[row, col].set_ylabel('')

plt.tight_layout()
plt.show()
处理建议: 对于“交易金额”等右偏分布特征,异常值通常位于上界之外。建议采用 Winsorize 方法,将超出 99% 分位数的值替换为该分位数,而非直接删除,以保留样本量。

4.4 重复值检测与去重

重复记录可能源于数据采集系统的重复上报或合并时的冗余。商户风险评分卡要求每条记录对应唯一的商户-时间窗口,因此必须严格去重。

# 检测重复行
dup_rows = df.duplicated().sum()
print(f"完全重复的记录数: {dup_rows}")

# 基于关键字段检测重复(如商户ID+月份)
key_dup = df.duplicated(subset=['商户ID', '数据月份'], keep='first').sum()
print(f"基于[商户ID, 数据月份]的重复记录数: {key_dup}")

# 去重操作
df_clean = df.drop_duplicates(subset=['商户ID', '数据月份'], keep='first')
注意: 去重前务必确认重复记录是否包含不同时间点的有效信息。若同一商户在同一月份出现多条记录,应检查是否为不同业务类型,必要时进行聚合而非简单删除。

4.5 数据分布可视化

理解特征的数据分布形态有助于后续的分箱策略与模型选择。我们通过直方图与密度图观察分布的中心趋势、离散程度与偏态特征。

# 绘制直方图与核密度估计
fig, axes = plt.subplots(2, 3, figsize=(16, 10))
features_plot = ['交易金额', '交易笔数', '商户年龄(月)', '负债率', '逾期次数', '信用评分']

for idx, feat in enumerate(features_plot):
    row, col = divmod(idx, 3)
    sns.histplot(df_clean[feat], kde=True, bins=50, color='#2ecc71', ax=axes[row, col])
    axes[row, col].set_title(f'{feat} 分布图', fontsize=12)
    axes[row, col].set_xlabel('')

plt.tight_layout()
plt.show()

分布可视化结果通常揭示以下规律:

  • 右偏分布: 如“交易金额”、“交易笔数”,多数商户集中在低值区间,少数高值商户拉长右尾。此类特征适合进行对数变换或等频分箱。
  • 近似正态分布: 如“商户年龄(月)”,可直接用于线性模型或等距分箱。
  • 双峰或多峰分布: 如“负债率”,暗示数据中存在不同的商户子群,为后续分群建模提供了依据。
数据质量分析与分布可视化流程 原始商户数据集 缺失值检测 异常值检测 重复值检测 数据清洗(填充/截尾/去重) 数据分布可视化(直方图/箱线图) 高质量清洗数据集 数据质量分析是评分卡建模的必经之路,直接影响后续分箱与模型训练效果

4.6 数据质量报告与决策

完成上述检测与可视化后,应汇总一份数据质量报告,作为特征筛选与分群策略的依据。报告应包含以下核心内容:

  1. 特征缺失率排名: 列出缺失率最高的前 10 个特征,并标注处理方式。
  2. 异常值特征清单: 标注每个连续特征的异常值数量与占比,以及采用的截尾分位数。
  3. 重复记录统计: 去重前后的样本量对比,确保去重逻辑合理。
  4. 分布形态总结: 对每个特征标注分布类型(正态、偏态、双峰等),为分箱方法选择提供参考。
实践要点: 数据清洗不是一次性工作。在后续特征工程与模型迭代中,应定期回溯数据质量,特别是当新增数据源或业务规则变更时。建议将数据质量检查脚本封装为自动化流水线,每次建模前自动生成质量报告。