☰
银行还款预测EDA实战:数据预处理与特征工程前的关键步骤
2026/10/15 1:20:22 网站建设 项目流程

1. 拿到还款数据先别急着建模,EDA这一步决定了后面80%的成败

做过信贷风控或者金融数据挖掘的人都有一个共识:还款预测这类项目,模型选型其实拉不开太大差距,真正决定最终AUC上限的,是你在特征工程之前对数据做了多深的摸底。我见过太多人拿到一份还款记录表,扫一眼字段名就开始跑LightGBM,结果特征重要性出来一堆莫名其妙的字段排在前列,回头查才发现原始数据里有一列"还款状态"混了三种编码体系,模型学到的全是噪声。

这篇内容就是围绕"银行还款情况预测"项目在特征工程之前必须完成的数据预处理与EDA工作展开。关键词很明确:还款预测、EDA、数据预处理、特征工程前。适合正在做信贷违约预测、贷后行为评分卡、或者任何跟"用户会不会按时还款"相关的数据科学从业者,也适合刚入门金融风控、想搞清楚一份还款明细表到底该怎么拆的人。

我会把整个EDA流程拆成几个必须走的环节:先搞清楚数据长什么样、再逐个字段做分布与异常排查、然后处理缺失与不一致、最后输出一份可以直接喂给特征工程的干净底表。每一步我都会说清楚"为什么这么做"以及"不做会怎样",这些才是文档里不会写的部分。

2. 先给数据做一次全面体检:字段语义与业务口径对齐

2.1 拿到表的第一件事不是看分布,而是搞清楚每一列到底在说什么

很多人拿到还款数据,第一反应是df.describe()。这个操作本身没错,但顺序错了。还款类数据最大的坑不在数值分布,而在字段语义。同样叫"还款状态",有的系统里1代表正常、2代表逾期,有的系统里0代表正常、1代表逾期,还有的系统用A/B/C/D表示五级分类。你如果不先把口径对齐,后面所有EDA都是白做。

我的习惯是拿到数据后先做三件事:

  • 拉一份字段清单,逐列标注:字段名、业务含义、取值类型、是否为目标相关字段、是否在预测时点可知。
  • 找业务方或者数据字典确认每个枚举值的含义,尤其是状态类、标志类字段。
  • 标记出"预测时点不可知"的字段,比如"最终核销金额"这种贷后才知道的,必须在建模前剔除,否则就是标签泄露。

这里有个经验:还款数据里最容易泄露标签的字段往往藏在"金额类"里。比如"当前欠款总额"如果是在还款日之后统计的,那它本身就包含了还款行为的结果,拿它预测"是否会逾期"等于作弊。我在一个模拟项目里就踩过这个坑,模型AUC高得离谱,后来发现用了一个贷后统计字段,去掉之后直接掉了0.15。

2.2 用一张表把字段按"可用性"分类,比盲目跑统计有用得多

我通常会把字段分成四类,做成一张表来管理:

字段类别判断标准处理方式
预测时点可知在还款日之前就能获取保留,进入特征工程候选
预测时点不可知还款日之后才产生直接剔除,防标签泄露
标识类字段用户ID、合同号等保留用于关联,不参与建模
目标衍生字段由还款结果直接计算剔除或仅用于构造标签

这张表看起来简单,但它能帮你避免90%的泄露问题。我见过一个团队做了三个月模型,最后发现用了"逾期天数"这个字段去预测"是否逾期",整个项目推倒重来。所以这一步不是形式主义,是保命操作。

2.3 目标变量的定义要先想清楚,不然后面全白干

还款预测的目标变量通常有两种定义方式:一种是二分类,"是否逾期超过X天";另一种是多分类,"正常/关注/次级/可疑/损失"。这两种定义对应的EDA重点完全不同。

如果是二分类,你要重点关注正负样本比例。信贷数据天然不平衡,逾期样本可能只占2%到5%。这时候你在EDA阶段就要想好后面是用过采样、欠采样还是调整class_weight。如果等到建模才发现不平衡,特征工程的方向可能都错了。

如果是多分类,你要关注类别之间的边界是否清晰。我做过一个项目,五级分类里"关注"和"次级"的界限非常模糊,很多样本在两个类别之间反复横跳,这种数据你硬做多分类,模型学到的全是噪声。后来我们把它合并成三分类,效果反而更好。

提示:目标变量定义一定要在EDA开始前和业务方确认清楚,中途改定义等于所有EDA工作重来。

3. 缺失值与异常值的排查:还款数据里最脏的部分往往藏在这里

3.1 缺失不是随机发生的,还款数据的缺失本身就有业务含义

普通数据集里缺失值可能只是采集遗漏,但还款数据不一样。缺失往往意味着某种业务状态。比如"实际还款日期"为空,可能代表用户根本没还;"逾期天数"为空,可能代表用户从未逾期。如果你直接fillna(0)或者dropna(),就把这些业务含义抹掉了。

我的做法是先把缺失情况可视化,按缺失比例排序,然后逐列判断缺失的业务含义:

  • 缺失比例超过80%的字段,先问业务方这个字段是不是新上线的,如果是,考虑直接剔除。
  • 缺失比例在5%到80%之间的,重点分析缺失样本和 non-缺失样本在目标变量上的分布差异。如果差异显著,说明缺失本身是信息,应该构造一个"是否缺失"的指示变量。
  • 缺失比例低于5%的,可以考虑用中位数、众数或者模型预测填充,但填充前一定要确认缺失是随机的。

我实测下来,还款数据里"是否缺失"这个指示变量经常能进特征重要性前20。原因很简单:一个连还款日期都没记录的用户,和一個记录完整的用户,违约概率天然不同。

3.2 异常值处理:还款金额里的负数不一定是错误

还款数据里的异常值处理特别容易误伤。比如"还款金额"出现负数,新手第一反应是数据错误,直接删掉。但实际上负数可能代表退款、冲正或者提前还款的利息调整,这些是有业务含义的。

我一般用箱线图和分位数来定位异常值,但不会无脑用3σ或者IQR直接剔除。具体流程是:

  1. 先看异常值的数量和占比。如果占比很小(比如0.1%),且明显是录入错误(比如年龄填了999),可以直接处理。
  2. 如果占比不小(比如2%以上),一定要找业务方确认。很多所谓的"异常值"其实是特殊业务场景。
  3. 对于确认是异常的,优先考虑截断(winsorize)而不是删除,因为删除会损失样本,而且可能引入选择偏差。

这里有个细节:还款金额的分布通常是右偏的,少数大额还款会把均值拉高。这时候用中位数比均值更稳健,做分箱的时候也要用等频分箱而不是等距分箱。

3.3 重复值与一致性检查:同一用户多条还款记录怎么处理

还款数据通常是"用户-期数"的粒度,一个用户有多条还款记录。EDA阶段必须检查:

  • 是否存在完全重复的行?如果有,是系统重复推送还是真实的多笔还款?
  • 同一用户同一期数是否有两条记录?如果有,哪条是有效的?
  • 用户ID、合同号这些关联键是否有空值或者格式不一致?

我遇到过一个情况:同一笔还款在系统里被记录了两次,金额一模一样,时间差了几秒。如果不做去重,这个用户的还款总额就翻倍了,后面算"还款率"全错。去重的时候不能只用drop_duplicates(),要结合业务主键来判断,比如"用户ID+期数+还款日期"作为联合主键。

4. 单变量与多变量分布分析:把每个字段的"脾气"摸透

4.1 数值型字段:别只看均值,分位数和偏度才是重点

还款数据里的数值字段主要有几类:还款金额、逾期天数、账龄、收入、负债等。对每一类,EDA的重点不一样。

对于金额类字段,我重点关注:

  • 分布的偏度和峰度。还款金额几乎一定是右偏的,这时候考虑做对数变换。
  • 分位数分布。看P1、P5、P25、P50、P75、P95、P99,判断长尾有多长。
  • 零值和负值的比例。零值可能代表"未还款",负值可能是冲正。

对于天数类字段,比如逾期天数、账龄,重点关注:

  • 是否有负数(账龄为负说明数据有问题)。
  • 分布是否集中在某些特定值(比如逾期天数集中在30、60、90,说明有账期规则)。
  • 极值是否合理(逾期天数超过1000天可能是坏账,也可能是数据错误)。

对于比率类字段,比如负债收入比,重点关注:

  • 是否有超过1的值(负债大于收入是可能的,但要看比例)。
  • 分母为0的情况怎么处理的。

我通常会把所有数值字段的统计量做成一张大表,按偏度绝对值排序,偏度大的优先考虑变换。这张表在特征工程阶段会非常有用。

4.2 类别型字段:枚举值合并是门手艺

还款数据里的类别字段不多,但每个都很关键:还款方式、还款状态、职业类型、学历等。EDA阶段要做的是:

  • 统计每个类别的频次,找出稀有类别(占比低于1%的)。
  • 分析每个类别与目标变量的关系,计算WOE或者逾期率。
  • 决定稀有类别是合并还是保留。

这里有个经验:类别合并不能只看频次,还要看目标变量的单调性。比如职业类型有20个类别,其中5个占比都低于1%,但它们的逾期率差异很大,这时候合并反而会损失信息。我的做法是先把逾期率相近的类别合并,再看合并后的频次是否可接受。

另外,还款状态这种有序类别,一定要按业务逻辑排序,不能按字母或者数字大小排。我见过有人把"正常、逾期、结清"按拼音排序,EDA图表完全没法看。

4.3 时间维度:还款数据不看时间轴等于白做

还款数据天然带时间属性,EDA阶段必须做时间维度的分析:

  • 按还款月份统计逾期率,看是否有季节性或者趋势性。
  • 按账龄(用户借款到现在的月数)统计逾期率,看是否有"账龄效应"。
  • 检查数据的时间覆盖范围,是否有某个月数据缺失或者异常。

我做过一个项目,整体逾期率是4%,但按月份拆开发现某个月的逾期率突然飙到15%。查下来发现那个月系统升级,部分还款记录延迟入账,导致数据失真。如果不做时间维度EDA,这个坑根本发现不了。

时间维度的另一个作用是确定观察期和表现期。还款预测通常需要设定一个观察窗口(比如过去12个月)和表现窗口(比如未来6个月),EDA阶段要确认数据是否覆盖了这两个窗口,以及窗口内的样本量是否足够。

5. 特征工程前的最后一道工序:输出干净可用的底表

5.1 数据清洗的优先级:先做不影响分布的,再做影响分布的

清洗步骤的顺序很重要,顺序错了会导致结果不可复现。我的标准顺序是:

  1. 去重:先去掉完全重复的行,这一步不影响字段分布。
  2. 类型转换:把日期字符串转成datetime,把金额转成float,把状态转成category。
  3. 异常值处理:截断或者修正明显错误的值。
  4. 缺失值处理:构造缺失指示变量,再填充。
  5. 一致性校验:检查关联键、时间逻辑、金额逻辑是否自洽。

为什么把缺失值放在异常值之后?因为异常值处理可能会产生新的缺失(比如把非法值设为NaN),如果先填充再处理异常,填充的值可能又被改掉,逻辑就乱了。

5.2 构造几个基础衍生字段,为特征工程铺路

EDA阶段不需要做完整的特征工程,但可以构造几个基础衍生字段,这些字段在后续特征工程里几乎一定会用到:

  • 还款率= 实际还款金额 / 应还金额。这个字段比原始金额更有信息量。
  • 逾期标志= 实际还款日期 > 应还日期 ? 1 : 0。这是最基础的目标相关特征。
  • 账龄= 当前日期 - 放款日期。反映用户处于生命周期的哪个阶段。
  • 历史逾期次数= 该用户过去所有期数中逾期的次数。这是强特征。
  • 最大逾期天数= 该用户历史最大逾期天数。比平均逾期天数更有区分度。

构造这些字段的时候要注意时间窗口。比如"历史逾期次数"必须是当前期数之前的,不能包含当前期,否则又是标签泄露。我通常会用groupby加shift来实现,确保只用到历史信息。

5.3 输出底表前必须做的三项校验

底表输出前,我一定会做三项校验,缺一不可:

第一,行数和用户数校验。清洗后的行数应该和原始数据对得上,差异要有合理解释。用户数不能无故减少。

第二,目标变量分布校验。清洗前后目标变量的正负样本比例不能有剧烈变化。如果变化超过1个百分点,说明清洗过程可能引入了偏差。

第三,关键字段的空值率校验。清洗后关键字段(用户ID、目标变量、核心特征)的空值率必须为0,非关键字段的空值率要在可接受范围内。

这三项校验做完,底表才能交给特征工程环节。我见过太多人跳过校验,结果特征工程做完发现样本对不上,回头查清洗日志查半天。

6. 几个我踩过的坑和对应的处理技巧

6.1 日期格式不统一:一个字段三种格式是常态

还款数据里的日期字段经常是灾难现场。同一个"还款日期"字段,有的记录是"2023-01-15",有的是"2023/1/15",还有的是"15-Jan-2023"。更麻烦的是有些系统用"20230115"这种数字格式。

我的处理方式是写一个健壮的日期解析函数,按优先级尝试多种格式,解析失败的记录单独标记出来人工检查。不要用pd.to_datetime一把梭,它遇到混合格式会直接报错或者静默转成NaT,后者更危险,因为你不知道哪些转失败了。

def parse_date(date_str): formats = ['%Y-%m-%d', '%Y/%m/%d', '%d-%b-%Y', '%Y%m%d'] for fmt in formats: try: return pd.to_datetime(date_str, format=fmt) except: continue return pd.NaT

解析完之后,一定要统计NaT的比例。如果超过1%,说明还有没覆盖的格式,需要继续排查。

6.2 金额字段的精度问题:浮点数比较是个陷阱

还款金额涉及钱,精度问题特别重要。浮点数直接比较相等几乎一定会出问题,比如0.1 + 0.2 != 0.3。我在EDA阶段就会把金额字段统一转成以"分"为单位的整数,或者用Decimal类型,避免后续计算出问题。

另外,金额字段的舍入规则也要确认。有的系统四舍五入,有的系统直接截断,这会导致对账时差几分钱。EDA阶段发现这种问题,比建模阶段发现要好得多。

6.3 样本时间穿越:EDA阶段就要把时间线画清楚

时间穿越是还款预测里最隐蔽的坑。举个简单的例子:你用2023年12月的数据预测2023年11月的还款行为,这就是穿越。EDA阶段必须把每个字段的"产生时间"和"可用时间"标清楚。

我的做法是画一条时间线,把放款日、账单日、还款日、统计日都标上去,然后逐个字段确认它是在哪个时点产生的。只有产生时间早于预测时点的字段才能用。这个工作很繁琐,但能救命。

6.4 类别字段的编码陷阱:LabelEncoder不是随便用的

EDA阶段虽然不做最终编码,但要对类别字段的编码方式有个预判。LabelEncoder会给类别赋一个整数,但这个整数是有大小关系的,如果类别本身无序(比如职业类型),模型可能会误以为"职业5 > 职业3"。对于无序类别,后续应该用OneHot或者Target Encoding。

有序类别(比如学历、还款状态)可以用LabelEncoder,但顺序必须按业务逻辑来,不能按频次或者字母序。我在EDA阶段就会把每个类别字段的编码方式记下来,特征工程阶段直接照着做。

7. 关于还款预测EDA,我个人的几条实操体会

第一,EDA的时间投入应该占整个项目的30%到40%。很多人觉得EDA就是看看分布,一两个小时搞定,实际上还款数据的EDA做扎实了,特征工程会顺很多。我做过对比,认真做EDA的项目,特征工程阶段返工次数能减少一半以上。

第二,所有清洗步骤必须可复现。我习惯把EDA过程写成脚本,每一步都有日志输出,清洗前后的行数、空值率、目标分布都记录下来。这样出了问题能快速定位,也方便交接。

第三,不要迷信自动化EDA工具。pandas-profiling、sweetviz这些工具能快速出报告,但它们不懂业务。还款数据里的"负数还款金额"、"缺失的还款日期"这些业务含义,工具是看不出来的。工具用来做初筛可以,关键判断还得靠人。

第四,EDA结论要写成文档,不能只留在notebook里。我通常会在EDA结束后输出一份数据质量报告,包含字段清单、缺失情况、异常值处理记录、衍生字段定义、以及已知的数据问题。这份文档在后续建模、上线、监控阶段都会被反复引用。

第五,和业务方确认口径这件事,越早做越好。我见过项目做到一半发现目标变量定义错了,所有工作重来。EDA阶段就把业务口径对齐,后面能省大量时间。确认的时候最好有书面记录,口头确认容易扯皮。

还款预测这个方向,数据质量的重要性怎么强调都不过分。模型再 fancy,数据不干净,结果就是垃圾进垃圾出。把EDA这一步做扎实,后面的特征工程和建模才有意义。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询