4. 特征工程基础:特征选择、特征编码与特征缩放

特征工程是将原始数据转化为模型能够高效学习的数值特征的过程。在逾期预测模型中,原始数据通常包含用户ID、性别、职业、收入、历史逾期次数、申请时间戳等字段。这些字段不能直接输入逻辑回归或XGBoost模型,必须经过特征选择、特征编码和特征缩放三个核心步骤。

核心原则:特征工程的质量直接决定模型性能的上限。好的特征工程可以降低模型复杂度、提升泛化能力、加速训练收敛。

4.1 特征选择

特征选择是从原始特征集合中筛选出对预测目标最有价值的子集。在逾期预测场景中,特征数量可能从几十到几百不等,但并非所有特征都有用。冗余或无关特征会引入噪声、增加过拟合风险、降低模型可解释性。

4.1.1 特征选择方法对比

方法类别 典型算法 适用场景 优点 缺点
过滤法 方差阈值、卡方检验、互信息、相关系数 特征数量大,快速初筛 计算快,独立于模型 忽略特征间交互
包裹法 递归特征消除(RFE)、前向/后向搜索 特征数较少,追求最优子集 考虑特征组合效果 计算开销大,易过拟合
嵌入法 L1正则化(Lasso)、树模型特征重要性 模型训练与选择同步 效率与效果平衡 依赖模型选择

4.1.2 逾期预测中的特征选择实践

  • 缺失率过滤:删除缺失率超过80%的特征,如部分用户未填写的“配偶收入”。
  • 方差过滤:删除方差接近0的特征,如“是否同意隐私协议”(几乎全为1)。
  • 相关性分析:删除相关系数 > 0.95 的冗余特征对,如“月收入”与“年收入/12”。
  • 树模型重要性排序:使用LightGBM训练一轮,保留重要性排名前30的特征。
实战建议:在逾期预测项目中,推荐采用“过滤法初筛 + 嵌入法精选”的组合策略。先用缺失率和方差快速剔除无效特征,再用Lasso或树模型重要性做最终选择。
特征选择流程(逾期预测场景) 原始特征池 100+ 特征 过滤法 缺失率/方差/相关性 嵌入法 L1正则/树重要性 特征子集 20~30 特征 逾期预测特征选择示例 • 过滤法:删除“用户ID”(方差低)、“配偶收入”(缺失率85%)、“月收入与年收入”(相关性0.98) • 嵌入法:使用Lasso回归,将“职业编码”、“教育程度”等系数压缩为0,自动剔除 • 最终保留:历史逾期次数、近6月查询次数、收入负债比、信贷产品类型、年龄等25个特征 • 效果:模型AUC从0.72提升至0.78,训练时间减少40%

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())
特征编码方式对比 标签编码(有序类别) 学历 编码值 本科 → 0 硕士 → 1 博士 → 2 保留序数关系:博士 > 硕士 > 本科 输出:1 列 独热编码(无序类别) 职业 教 医 工 教师 → [1, 0, 0] 医生 → [0, 1, 0] 工程师 → [0, 0, 1] 无序关系:各职业地位平等 输出:K 列(K=类别数)

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每次推理时,对输入数据执行完全相同的变换流程,确保训练与推理的特征分布一致。