4、特征工程:特征构造、WOE编码、IV值筛选、分箱技术
好,咱们进入正题。特征工程这步,说白了就是给模型“喂”什么数据。你想想看,原始数据就像一堆没洗的菜,直接下锅肯定不行。我做了这么多年风控,见过太多人拿着原始字段就往模型里塞,结果模型跑出来一塌糊涂。嗯,这里面的门道,我今天跟你好好聊聊。
4.1 特征构造——从原始数据里“挖”出金子
特征构造,就是根据业务理解,把原始字段组合、变换成更有预测能力的特征。我个人习惯,拿到数据后先不急着建模,而是花大量时间思考:哪些信息能反映客户的还款意愿和能力?
举个例子,原始数据里有“月收入”和“月还款额”,单独看都挺重要。但如果你构造一个“收入负债比 = 月还款额 / 月收入”,这个特征往往比单个字段强得多。我在项目中遇到过,一个客户的月收入很高,但负债也高得吓人,光看收入会误判,但收入负债比直接暴露了风险。
常见的特征构造方法包括:
- 聚合统计:比如客户近3个月、6个月的逾期次数、平均逾期天数。我建议按时间窗口切分,别只看全量。
- 比率类:收入负债比、首付比例、贷款成数。这些是汽车金融的“灵魂特征”。
- 交叉组合:比如“年龄 × 贷款期限”,年轻客户贷长期限,风险往往更高。
- 时序特征:比如“最近一次逾期距今的天数”,这个特征对预测短期违约特别有效。
4.2 WOE编码——把分类变量“翻译”成模型能懂的语言
WOE(Weight of Evidence,证据权重)编码,是评分卡模型里处理分类变量的标准方法。你可能会问:为什么不直接用one-hot编码?嗯,one-hot在逻辑回归里有个问题——它假设每个类别独立,但实际中类别之间是有序的。比如“学历”这个字段,博士和小学的违约率肯定不一样,但one-hot编码会忽略这种顺序。
WOE编码的核心思想很简单:用“好客户占比 / 坏客户占比”的对数来替换原始类别。公式长这样:
WOE_i = ln( (好客户在i组的占比) / (坏客户在i组的占比) )
我举个例子,假设“婚姻状况”这个字段:
| 婚姻状况 | 好客户数 | 坏客户数 | 好客户占比 | 坏客户占比 | WOE值 |
|---|---|---|---|---|---|
| 已婚 | 800 | 50 | 0.40 | 0.25 | 0.47 |
| 未婚 | 600 | 80 | 0.30 | 0.40 | -0.29 |
| 离异 | 600 | 70 | 0.30 | 0.35 | -0.15 |
你看,已婚的WOE是正的,说明这个组别“好客户”更集中;未婚和离异是负的,风险相对更高。模型拿到WOE值后,就能直接理解每个类别的风险倾向了。
4.3 IV值筛选——找出真正有用的特征
IV(Information Value,信息量)值,是用来衡量特征预测能力的指标。说白了,就是告诉你这个特征到底有没有用。我一般把IV值分成几个档次:
| IV值范围 | 预测能力 | 我的建议 |
|---|---|---|
| < 0.02 | 无预测能力 | 直接扔掉 |
| 0.02 - 0.10 | 弱 | 可以保留,但别太依赖 |
| 0.10 - 0.30 | 中等 | 不错,值得保留 |
| 0.30 - 0.50 | 强 | 核心特征,必须保留 |
| > 0.50 | 极强 | 小心过拟合,建议检查 |
IV值的计算公式其实和WOE紧密相关:
IV = Σ ( (好客户占比 - 坏客户占比) × WOE_i )
你想想看,如果一个特征里每个分组的WOE都很大,而且好客户和坏客户的分布差异也大,那IV值自然就高。我习惯在特征筛选时,先算一遍所有特征的IV值,把低于0.02的直接剔除。这样能省下不少建模时间。
4.4 分箱技术——把连续变量“离散化”
分箱,就是把连续变量(比如年龄、收入)切成几个区间。为什么要这么做?因为逻辑回归模型喜欢离散变量,而且分箱后能捕捉非线性关系。比如“年龄”和违约率的关系,可能不是线性的——年轻人违约率高,中年人低,老年人又高。如果不分箱,模型很难学到这种“U型”关系。
常用的分箱方法有:
- 等距分箱:按数值范围均匀切分。比如年龄0-20、20-40、40-60、60-80。简单,但容易导致某些箱里样本太少。
- 等频分箱:让每个箱里的样本数量差不多。比如按年龄排序后,每20%的样本分一箱。这样能保证每个箱都有足够样本,但边界可能不直观。
- 最优分箱:基于目标变量(是否违约)来切分,让每个箱里的违约率差异最大化。这是我最推荐的方法。
我举个例子,用Python的scorecardpy库做最优分箱:
import scorecardpy as sc
# 假设df是数据框,'age'是年龄字段,'target'是目标变量(0好客户,1坏客户)
bins = sc.woebin(df, y='target', x='age', bin_num_limit=5)
# 查看分箱结果
print(bins['age'])
输出结果大概长这样:
| 分箱区间 | 好客户数 | 坏客户数 | 违约率 | WOE |
|---|---|---|---|---|
| [18, 25) | 200 | 40 | 16.7% | -0.35 |
| [25, 35) | 500 | 60 | 10.7% | 0.12 |
| [35, 50) | 600 | 30 | 4.8% | 0.68 |
| [50, 65] | 300 | 20 | 6.3% | 0.45 |
你看,最优分箱自动把年龄切成了4段,而且每个箱的违约率差异很明显。年轻人和老年人的违约率偏高,中年人最低。这种分箱结果,模型用起来就舒服多了。
4.5 本章知识体系
下面这张图,是我梳理的特征工程核心流程。你可以看到,从原始数据到最终建模,特征工程是承上启下的关键一步。
从图上你能看到,特征构造和分箱技术是并行的——你可以先构造新特征,再分箱;也可以先分箱,再构造。我个人习惯是先分箱,因为分箱后的离散变量更容易做交叉组合。但具体顺序,还得看你的数据和业务场景。
好了,特征工程这部分就聊到这儿。记住一句话:好的特征工程,能让模型事半功倍;坏的特征工程,再牛的算法也救不了。你想想看,是不是这个理?