第四节:交叉特征与组合特征——特征笛卡尔积、多项式特征在风控评分卡中的应用
各位同学,咱们今天聊点硬核的。
前面几节课,我们讲了单变量特征怎么构造、怎么筛选。但说实话,在真实的风控场景里,单个特征的力量往往有限。你想想看,一个人的收入高,就一定还款能力强吗?不一定。但如果他收入高、同时负债率低、而且工作年限长——这三个条件组合在一起,那还款能力就靠谱多了。
这就是交叉特征和组合特征的价值所在。
4.1 为什么需要交叉特征?
我刚开始做评分卡的时候,犯过一个低级错误。当时我用了「年龄」和「收入」两个单独的特征,模型AUC只有0.72。后来我加了一个简单的交叉项「年龄×收入」,AUC直接跳到0.78。为什么?
因为线性模型无法自动学习特征之间的交互关系。逻辑回归也好,线性SVM也好,它们只能看到每个特征的独立贡献。但风控场景里,很多风险信号是组合出现的:
- 「高额度 + 短期借款」= 资金链紧张
- 「低年龄 + 高消费」= 过度消费倾向
- 「多次逾期 + 近期无还款」= 恶意逃废债
这些组合模式,单靠原始特征根本抓不住。
核心观点:交叉特征的本质,是把特征空间从「线性可加」扩展到「非线性交互」。在风控评分卡中,这往往是提升模型区分度的关键一步。
4.2 特征笛卡尔积:最暴力的组合方式
特征笛卡尔积,说白了就是把两个离散特征的所有取值组合都列出来。比如「学历」有3个取值(高中、本科、研究生),「职业」有5个取值(工人、白领、自由职业、学生、退休),笛卡尔积就会生成3×5=15个新特征。
我在项目中遇到过这样一个案例:某消费金融平台,原始特征只有「婚姻状况」和「居住城市」。单独看,这两个特征对逾期的预测能力都很弱。但当我做了笛卡尔积后,发现「已婚+一线城市」这个组合的逾期率只有2.3%,而「未婚+三线城市」的逾期率高达11.7%。
这就是组合特征的威力。
代码实现:特征笛卡尔积
import pandas as pd
from sklearn.preprocessing import LabelEncoder
def create_cartesian_features(df, col1, col2):
"""
生成两个离散特征的笛卡尔积
"""
# 编码原始特征
le1 = LabelEncoder()
le2 = LabelEncoder()
df[col1 + '_enc'] = le1.fit_transform(df[col1])
df[col2 + '_enc'] = le2.fit_transform(df[col2])
# 生成组合特征:使用哈希技巧避免维度爆炸
df[col1 + '_x_' + col2] = df[col1 + '_enc'] * 10000 + df[col2 + '_enc']
return df
# 示例
df = pd.DataFrame({
'education': ['本科', '研究生', '高中', '本科', '研究生'],
'occupation': ['白领', '自由职业', '工人', '学生', '白领']
})
df = create_cartesian_features(df, 'education', 'occupation')
print(df[['education', 'occupation', 'education_x_occupation']])
避坑指南:我曾经在一个项目中,对10个离散特征做了全量笛卡尔积,结果特征维度从20直接膨胀到5000+。模型训练时间从5分钟变成了3小时,而且过拟合严重。记住:笛卡尔积要慎用,建议先做特征筛选,只对强相关的特征做组合。
4.3 多项式特征:连续变量的交互艺术
对于连续变量,笛卡尔积就不太适用了。这时候我们需要多项式特征——说白了,就是特征之间的乘法和幂运算。
比如你有两个连续特征x1和x2,多项式特征可以生成:
- x1², x2²(平方项,捕捉非线性关系)
- x1×x2(交互项,捕捉协同效应)
- x1²×x2, x1×x2²(高阶交互)
你想想看,在风控场景里,「收入²」这个特征意味着什么?它放大了高收入人群和低收入人群之间的差异。而「收入×负债率」这个交互项,则能识别出「高收入但高负债」这种高风险组合。
代码实现:多项式特征
from sklearn.preprocessing import PolynomialFeatures
import numpy as np
# 原始特征
X = np.array([[5000, 0.3], # 收入5000,负债率30%
[15000, 0.5], # 收入15000,负债率50%
[8000, 0.2]]) # 收入8000,负债率20%
# 生成2阶多项式特征
poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(X)
# 查看特征名称
feature_names = poly.get_feature_names_out(['income', 'debt_ratio'])
print("原始特征:", X)
print("多项式特征:\n", X_poly)
print("特征名称:", feature_names)
个人经验:我一般只用2阶多项式。3阶以上不仅计算量大,而且容易引入噪声。记住一个原则:在风控领域,简单模型+好特征,往往比复杂模型+差特征更靠谱。
4.4 风控评分卡中的实际应用策略
好了,理论讲完了,咱们聊聊实战。在评分卡项目中,我一般按以下步骤操作:
- 先做单变量分析:筛选出IV值大于0.02的特征
- 再做相关性分析:找出相关性低于0.7的特征对
- 最后做交叉组合:只对筛选后的特征做笛卡尔积或多项式
为什么要分三步走?因为直接对所有特征做组合,维度会爆炸。我见过一个团队,200个特征直接做2阶多项式,生成了2万个特征——结果模型直接跑崩了。
一个真实的评分卡案例
去年我帮某银行做信用卡评分卡,原始特征有30个。经过单变量筛选后剩下12个,再做相关性分析后剩下8个。然后我对这8个特征做了2阶多项式,生成了36个新特征。
最终模型效果:
| 特征集 | KS值 | AUC | 特征数量 |
|---|---|---|---|
| 原始特征 | 0.32 | 0.71 | 30 |
| 筛选后特征 | 0.38 | 0.75 | 8 |
| 筛选+多项式 | 0.45 | 0.81 | 44 |
看到了吗?加了多项式特征后,KS值从0.38提升到0.45,提升了18%。这在风控领域是非常显著的提升。
4.5 核心知识体系
下面这张图,是我自己总结的交叉特征与组合特征的知识体系,你保存下来,以后做项目时对照着看:
4.6 避坑指南与最佳实践
最后,我把自己踩过的坑总结一下,你直接拿去用:
我曾经犯过的三个错误:
- 错误一:对缺失值多的特征做组合。结果组合后的特征缺失率高达80%,根本没法用。建议先填充缺失值,再做组合。
- 错误二:在训练集和测试集上分别做多项式变换。这会导致特征分布不一致。正确做法是:在训练集上拟合变换器,然后transform测试集。
- 错误三:组合特征后不做WOE编码就直接入模。对于评分卡来说,所有特征最好都做WOE转换,保持单调性。
我的个人习惯:每次做特征组合前,先问自己三个问题:
- 这个组合有没有业务含义?——没有业务解释性的特征,再好看也不要
- 组合后的维度会不会爆炸?——超过原始特征3倍,就要考虑降维
- 组合特征和原始特征的相关性如何?——如果相关性太高,说明没带来新信息
好了,交叉特征和组合特征就讲到这里。记住一句话:好的特征组合,能让你的评分卡模型从「及格」变成「优秀」。但也要记住,不是组合越多越好,关键是找到那些有业务含义、能提升区分度的组合。
嗯,这节课的内容就这些。你回去之后,找一份真实的风控数据,按照我讲的三步走策略,亲手做一遍特征组合。相信我,做完之后你对特征工程的理解会上一个台阶。