第四章:探索性数据分析(EDA)与数据质量报告生成

数据拿到手,别急着建模。我见过太多团队,上来就调参跑模型,结果跑出来的分数根本不敢用。为什么?因为数据里藏着什么问题,你根本不知道。EDA这步,说白了就是给你的数据做个全面体检。不做体检就上手术台,风险太大。

我个人习惯,先花至少一天时间做EDA。别觉得浪费时间——数据质量报告出来以后,你后面的工作会顺畅得多。这一章,我就带着你走一遍EDA的核心流程,顺便说说我踩过的坑。

4.1 EDA到底要干什么?

信用评分模型里,EDA的目标很明确:

  • 看懂每个字段的分布形态
  • 发现缺失值、异常值、重复值
  • 检查变量的逻辑合理性(比如年龄不能是负数)
  • 初步判断变量和违约率的关系
  • 为数据清洗和特征工程提供依据

嗯,说白了就是三件事:看分布、找脏数据、摸关系。

我的经验: 有一次我处理一个车贷数据集,月供字段里出现了零值。我一开始以为是正常情况,结果一查是系统bug,把空值填成了0。要不是做了分布图,这个坑就会一路带到模型里。

4.2 单变量分析——先摸清每个字段的底细

单变量分析是最基础的。我会把字段分成两类:数值型和分类型。处理方式不一样。

4.2.1 数值型字段

我会先看五个统计量:最小值、最大值、均值、中位数、标准差。然后画直方图或箱线图。特别关注:

  • 是否有极端值(比如收入字段出现1亿)
  • 分布是否严重偏态(信用分字段通常偏左,正常)
  • 是否有不合理取值(比如年龄大于120)

举个例子,你想想看:收入字段如果均值是5000,中位数是3000,说明大部分人收入偏低,但少数高收入拉高了均值。这种偏态分布,后面做分箱或WOE转换时得格外小心。

我曾经踩过的坑: 处理一个教育贷款数据集时,我发现"工作年限"字段有负值。查日志才发现是数据录入时把"0"输成了"-1"。如果不做异常值检测,模型会把负值当成有效信息。

4.2.2 分类型字段

对于性别、婚姻状况、学历这类离散字段,我会看频数和占比。主要检查:

  • 类别数量是否过多(比如城市字段有3000个值,那得考虑合并)
  • 是否有低占比类别(占比低于1%的,可以考虑归为"其他")
  • 是否有逻辑矛盾(比如"性别"字段出现"未知",而"婚姻状况"字段出现"已婚且有配偶")

我记得有一次,一个信用卡申请数据集里,"居住状态"字段有"自有"、"租住"、"集体宿舍",还有一个"其他"占比不到0.5%。建模时如果不处理,这个类别在训练集和测试集里可能会分布不一致,导致模型不稳定。

4.3 双变量分析——看变量和违约的关系

单变量看完了,接下来要看每个变量和目标变量(是否违约)的关系。这才是EDA的核心。

对于数值型变量,我会分违约组和正常组,画两个箱线图对比。如果两组的中位数差异明显,这个变量大概率有价值。

对于分类型变量,我会计算每个类别下的违约率,然后画柱状图。比如"学历"字段:如果"硕士及以上"违约率只有2%,而"高中以下"违约率是8%,这就是个强区分变量。

学历类别 样本数 违约样本数 违约率
硕士及以上 5,000 100 2.0%
本科 12,000 480 4.0%
大专 8,000 560 7.0%
高中及以下 5,000 400 8.0%

你看这个表,违约率从2%到8%,梯度非常清晰。这种变量在信用评分模型里就是"好变量"。反过来,如果某个变量的各类别违约率差不多(比如都在5%左右),那它对模型帮助不大。

4.4 缺失值分析——别漏掉任何一块拼图

缺失值处理不当,模型会学出奇怪的东西。我一般会做两步:

  1. 统计每个字段的缺失率
  2. 分析缺失模式——是随机缺失,还是和某个字段有关?

举个例子,某数据集中"工作年限"字段缺失率达到30%,但"收入"字段完整。那么缺失的工作年限可能是随机缺失,可以用中位数填补。但如果是"学历"缺失,而"收入"也偏低,那缺失可能并非随机——这时候直接填中位数会引入偏差。

实践建议: 缺失率超过50%的字段,我一般直接剔除。缺失率在5%-50%的,我会做多重插补或单独标记"缺失"类别。低于5%的,中位数或者众数填补即可。

4.5 数据质量报告——把发现变成文档

EDA做完了,不能只留在脑子里。必须生成一份数据质量报告,让团队每个人都看得懂。我习惯用Python的pandas-profiling(现在叫ydata-profiling)自动生成报告,但也会手动补充关键发现。

报告里应该包含哪些内容呢?下面是清单:

  • 总体数据概况:行数、列数、内存占用
  • 缺失值汇总:字段名、缺失数量、缺失率
  • 异常值列表:哪些字段有极端值,处理建议
  • 重复行统计:重复样本数和处理方式
  • 变量分布描述:对重点字段给出分布特征
  • 变量与目标的相关性:初步筛选变量
  • 数据质量问题与行动项:比如"字段A需要联系业务方确认逻辑"

下面是一个简化的Python代码示范:

import pandas as pd
import numpy as np

# 读取数据
df = pd.read_csv('credit_data.csv')

# 缺失值统计
missing = df.isnull().sum()
missing_rate = missing / len(df)
missing_df = pd.DataFrame({'字段': df.columns, '缺失数': missing, '缺失率': missing_rate})

# 异常值检测(以年龄为例,假设合理范围18-80)
outliers = df[(df['age'] < 18) | (df['age'] > 80)]
print(f'年龄异常值数量: {len(outliers)}')

# 重复行检测
duplicates = df.duplicated().sum()
print(f'重复行数: {duplicates}')

# 生成简要报告
report = {
    '总样本数': len(df),
    '总字段数': len(df.columns),
    '缺失字段数': (missing > 0).sum(),
    '重复行数': duplicates,
    '内存占用(MB)': df.memory_usage(deep=True).sum() / 1024**2
}
print(report)
一点提醒: 自动生成的报告很全,但别完全依赖它。我每次都会再手动浏览几个关键字段的分布图,因为有些模式(比如双峰分布)自动报告可能标注为"正常",但实际业务上可能有问题。

4.6 数据质量报告生成流程(一张图说清)

上面的步骤有些多,我给总结成一张流程图。你看一眼就明白整个EDA和报告生成的路径:

EDA与数据质量报告生成流程 原始数据集 单变量分析(分布/统计量) 双变量分析(与违约的关系) 缺失值与异常值检测 汇总发现与行动项 生成数据质量报告 报告包含:缺失汇总、异常值列表、重复行、变量分布、变量-目标关系、行动项

4.7 注意事项:别让EDA变成走过场

最后,说几条我这些年总结的教训:

  • 不要只看汇总统计量——平均数有时会骗人,一定要画图看分布。我遇到过均值正常但实际分布有双峰的案例。
  • 注意时间维度——信用数据通常有时间戳。如果训练集和测试集的时间分布不一致,模型会失效。我曾经因此重做过整个项目。
  • 记录每一个发现——哪怕你觉得"这个异常值可能是数据录入错误",也要写进报告。后续沟通时你会有据可查。
  • 控制报告篇幅——太详细没人看,太粗略又没用。我一般把详细统计放在附录,正文只呈现关键发现和行动项。
再次提醒: 数据质量报告不是一次性输出。随着数据更新,你需要重新跑EDA并更新报告。我习惯在每个建模迭代开始前都做一次快速EDA检查——哪怕只是看看新数据的缺失率有没有变化。

EDA做扎实了,后面的数据清洗、特征工程、建模都会非常顺畅。嗯,这一章就这么多。动手把这套流程跑一遍,你很快就会有自己的感觉。数据不会骗人,但前提是你得懂得怎么看它。