4. 特征工程基础:特征选择、特征编码与特征缩放
特征工程是将原始数据转化为模型能够高效学习的数值特征的过程。在逾期预测模型中,原始数据通常包含用户ID、性别、职业、收入、历史逾期次数、申请时间戳等字段。这些字段不能直接输入逻辑回归或XGBoost模型,必须经过特征选择、特征编码和特征缩放三个核心步骤。
核心原则:特征工程的质量直接决定模型性能的上限。好的特征工程可以降低模型复杂度、提升泛化能力、加速训练收敛。
4.1 特征选择
特征选择是从原始特征集合中筛选出对预测目标最有价值的子集。在逾期预测场景中,特征数量可能从几十到几百不等,但并非所有特征都有用。冗余或无关特征会引入噪声、增加过拟合风险、降低模型可解释性。
4.1.1 特征选择方法对比
| 方法类别 | 典型算法 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|---|
| 过滤法 | 方差阈值、卡方检验、互信息、相关系数 | 特征数量大,快速初筛 | 计算快,独立于模型 | 忽略特征间交互 |
| 包裹法 | 递归特征消除(RFE)、前向/后向搜索 | 特征数较少,追求最优子集 | 考虑特征组合效果 | 计算开销大,易过拟合 |
| 嵌入法 | L1正则化(Lasso)、树模型特征重要性 | 模型训练与选择同步 | 效率与效果平衡 | 依赖模型选择 |
4.1.2 逾期预测中的特征选择实践
- 缺失率过滤:删除缺失率超过80%的特征,如部分用户未填写的“配偶收入”。
- 方差过滤:删除方差接近0的特征,如“是否同意隐私协议”(几乎全为1)。
- 相关性分析:删除相关系数 > 0.95 的冗余特征对,如“月收入”与“年收入/12”。
- 树模型重要性排序:使用LightGBM训练一轮,保留重要性排名前30的特征。
实战建议:在逾期预测项目中,推荐采用“过滤法初筛 + 嵌入法精选”的组合策略。先用缺失率和方差快速剔除无效特征,再用Lasso或树模型重要性做最终选择。
4.2 特征编码
机器学习模型只能处理数值输入。逾期预测数据中的类别型特征(如职业、学历、地区、产品类型)必须转换为数值形式。错误的编码方式会引入虚假的序数关系或维度灾难。
4.2.1 独热编码 vs 标签编码
| 编码方式 | 原理 | 输出维度 | 适用特征 | 逾期预测示例 |
|---|---|---|---|---|
| 标签编码 | 将类别映射为整数 0,1,2,… | 1 列 | 有序类别(如学历:小学→0,中学→1,大学→2) | 信用等级:A→0, B→1, C→2 |
| 独热编码 | 为每个类别创建二进制列 | K 列(K为类别数) | 无序类别(如职业、地区、产品类型) | 职业:教师→[1,0,0],医生→[0,1,0],工程师→[0,0,1] |
4.2.2 编码选择决策规则
- 有序类别 → 标签编码:如“教育程度”、“收入等级”、“信用评分段”。
- 无序类别且类别数 < 10 → 独热编码:如“性别”、“婚姻状况”、“产品类型”。
- 无序类别且类别数 ≥ 10 → 目标编码或频数编码:如“城市”(300+城市)、“职业”(50+职业),避免维度爆炸。
常见陷阱:对无序类别使用标签编码(如职业:教师=0,医生=1,工程师=2)会引入虚假的数值大小关系,模型可能错误地认为“工程师 > 医生 > 教师”,严重影响决策树分裂和线性模型权重。
4.2.3 代码示例:特征编码
import pandas as pd
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
# 原始数据
data = pd.DataFrame({
'职业': ['教师', '医生', '工程师', '教师', '医生'],
'学历': ['本科', '硕士', '本科', '博士', '硕士'],
'逾期标签': [0, 0, 1, 0, 1]
})
# 标签编码(适用于有序类别:学历)
le = LabelEncoder()
data['学历_编码'] = le.fit_transform(data['学历'])
# 映射关系:本科→0, 博士→1, 硕士→2
# 独热编码(适用于无序类别:职业)
ohe = OneHotEncoder(sparse_output=False)
职业_encoded = ohe.fit_transform(data[['职业']])
职业_df = pd.DataFrame(职业_encoded, columns=ohe.get_feature_names_out(['职业']))
data = pd.concat([data, 职业_df], axis=1)
print(data.head())
4.3 特征缩放
特征缩放是将不同量纲、不同取值范围的特征统一到相近的尺度。逾期预测数据中,“月收入”取值范围为0~100000,“年龄”为18~80,“历史逾期次数”为0~20。如果不做缩放,梯度下降类模型(逻辑回归、神经网络)会偏向量级大的特征,树模型虽然不受影响,但后续集成或特征融合时仍需统一尺度。
4.3.1 标准化 vs 归一化
| 方法 | 公式 | 输出范围 | 对异常值敏感度 | 适用模型 |
|---|---|---|---|---|
| 标准化(Z-score) | x' = (x - μ) / σ | 无固定范围,均值为0,标准差为1 | 中等 | 逻辑回归、SVM、神经网络、PCA |
| 归一化(Min-Max) | x' = (x - min) / (max - min) | [0, 1] | 高(受极值影响大) | KNN、神经网络(输入层)、图像像素 |
4.3.2 逾期预测中的缩放选择
- 逻辑回归 / 神经网络:优先使用标准化。逾期特征常包含异常值(如极少数用户月收入100万),标准化对异常值鲁棒性更好。
- KNN / 距离计算:优先使用归一化,确保各特征对距离贡献相等。
- 树模型(XGBoost / LightGBM):不需要特征缩放,但特征融合或后续使用SHAP解释时建议标准化。
- 实时API部署:必须保存训练集的μ、σ(标准化)或min、max(归一化)参数,在API推理时对输入数据做相同的变换。
部署要点:在实时API中,特征缩放参数(μ, σ, min, max)应作为模型artifact的一部分持久化。推荐使用
sklearn.pipeline.Pipeline 将缩放器与模型打包,避免推理时参数不一致。
4.3.3 代码示例:特征缩放与Pipeline
from sklearn.preprocessing import StandardScaler, MinMaxScaler
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
import joblib
# 示例特征:月收入、年龄、历史逾期次数
X_train = [[5000, 28, 0], [15000, 35, 2], [8000, 42, 1], [200000, 55, 5]]
y_train = [0, 0, 1, 1]
# 构建Pipeline:标准化 → 逻辑回归
pipeline = Pipeline([
('scaler', StandardScaler()), # 训练时计算μ, σ
('classifier', LogisticRegression())
])
pipeline.fit(X_train, y_train)
# 保存完整Pipeline(包含缩放参数)
joblib.dump(pipeline, '逾期模型_pipeline.pkl')
# API推理时加载并使用
# loaded_pipeline = joblib.load('逾期模型_pipeline.pkl')
# 新样本自动应用相同的标准化变换
# new_sample = [[12000, 30, 1]]
# prediction = loaded_pipeline.predict(new_sample)
4.4 本章小结
| 步骤 | 核心操作 | 逾期预测典型应用 | 常见错误 |
|---|---|---|---|
| 特征选择 | 过滤法 + 嵌入法组合 | 从100+特征筛选至25个核心特征 | 仅依赖单一方法,忽略特征交互 |
| 特征编码 | 有序→标签编码,无序→独热/目标编码 | 职业独热编码,学历标签编码,城市目标编码 | 无序类别使用标签编码引入虚假序数 |
| 特征缩放 | 标准化(推荐)或归一化 | 收入、年龄、查询次数统一到均值为0、标准差为1 | 推理时未使用训练集的缩放参数 |
实时部署提醒:特征工程的所有变换参数(选择哪些特征、编码映射表、缩放μ/σ)必须在训练阶段确定并持久化。实时API每次推理时,对输入数据执行完全相同的变换流程,确保训练与推理的特征分布一致。