信用评分模型概述与训练数据的重要性
做信用评分模型这些年,我最大的体会就一句话——模型是皮,数据是骨。算法再花哨,数据一塌糊涂,出来的分数就是废纸一张。今天咱们先聊聊基础,也聊聊为什么我敢说“训练数据准备”才是整个评分项目的命门。
我理解的信用评分模型
说白了,信用评分模型就是一把尺子。银行、消费金融公司用这把尺子量一下申请人,看他还钱的可能性有多大。分数越高,违约概率越低。听起来简单,但背后的逻辑其实挺深的。
一个典型的评分模型,输入是用户的各种信息——年龄、收入、负债、征信记录、历史还款行为……输出是一串数字,比如300到850分。这中间发生了什么?模型在学习“什么样的人容易违约”。
嗯,注意这里有个关键点:模型自己不会思考。它全靠你喂给它的数据来“猜”规律。数据里有什么,它就学什么。数据里有偏见,它也跟着学偏见。我在一家互金公司就见过真实案例——因为训练数据里女性用户比例极低,模型直接给了女性群体更低的分数,后来被监管约谈。这锅,算法背不动,数据才是根源。
| 维度 | 含义 | 我的常见踩坑点 |
|---|---|---|
| 完整性 | 字段缺失率 | 收入字段缺了30%,直接填充均值?那等于造假 |
| 准确性 | 值与真实情况一致 | 用户填“年薪100万”,实际流水只有10万——你怎么处理? |
| 一致性 | 不同数据源对齐 | 征信报告和内部系统逾期天数差3天,该信谁? |
| 时效性 | 数据反映当前状态 | 用三年前的收入预测现在的还款能力?别闹了 |
训练数据——模型的“燃料”
你想想看,一架飞机加错了油,飞行员技术再好也飞不起来。模型也一样。我习惯把训练数据比作燃料,模型就是发动机。燃料杂质越多,发动机报废得越快。
信用评分领域对数据的要求尤其苛刻。为什么?因为评分结果直接影响人家能不能贷到款、利率是多少。这背后是钱,甚至是用户的生活。模型错了,可能让一个本不该被拒绝的人背上一生征信污点。
一个好的训练数据集,至少得满足四样:
- 样本够大——我见过很多项目用几千条样本就上模型,结果上线后跟抽风一样。信用模型通常需要10万+样本,尤其是坏样本(违约客户)至少500个以上才能稳定。
- 正负样本均衡——信用场景坏样本通常很少(比如2%~5%)。直接训练,模型会变成“全好人”机器。我曾经试过欠采样+集成,效果才勉强能看。
- 特征真实可回溯——你用了“近3个月查询次数”,那得保证数据源能追溯,不然监管问起来你解释不清。
- 时间窗口对齐——观察期和表现期必须明确。我用过一批样本,表现期只设了3个月,结果后来发现很多客户在6个月后才逾期… 那批模型直接重做。
现实中的坑
讲个真事。某年我做一款现金贷评分卡,合作方给了一份“完美”的样本——样本量50万,坏账率5%,特征40多个。我心里一乐,觉得这波稳了。结果模型上线后AUC只有0.62,跟瞎猜差不多。
排查了两周才发现:训练数据里的“收入”字段,合作方用了一种特殊的插补方式——把所有低收入用户默认填了当地平均工资。模型学了什么呢?它学的是“低收入人群看起来收入也不错”,于是给这些用户打了高分。贷出去的款,后面全逾期了。
所以你看,数据准备阶段哪怕一个看似无害的“缺失值填充”操作,都可能导致模型整个跑偏。避坑指南:永远假设数据有雷,然后逐个字段去做交叉验证。
# 一个简单的数据质量检查脚本,我个人习惯放在项目入口
import pandas as pd
df = pd.read_csv('raw_data.csv')
# 字段完整性
null_ratio = df.isnull().mean()
print('字段缺失率:', null_ratio[null_ratio > 0.1])
# 分布合理性(比如收入不可能是负数)
for col in ['income', 'loan_amount']:
abnormal = df[df[col] < 0]
if len(abnormal):
print(f'{col} 存在负值 {len(abnormal)} 条')
这段代码看起来很基础,但我就靠它抓出过好几次数据源跑偏的问题。别觉得简单不屑于写,刚入行那会我也觉得这种检查太初级,后来吃过亏才老实了。
上面这张图是我整理出来的标准流程。你仔细看,数据清洗占了整个链路的前端,而且有个反馈回路——模型上线后出问题了,别急着改模型,先回来看数据。这个原则我反复讲给团队听,但总有人犯懒,结果绕了一大圈才发现是数据源变了。
简单总结一下第一章的核心:训练数据准备不是“脏活累活”,而是信用评分模型最核心的竞争力。后面29章,我们会一步步拆解怎么做好这件事。先把这个认知焊死在脑子里,后面的操作才有意义。