4. 特征工程入门:特征构建、特征选择与特征缩放
特征工程是数据科学流程中最具创造性与业务价值的环节。原始数据往往包含噪声、冗余或不一致的字段,直接送入模型会导致过拟合、训练缓慢或泛化能力差。本章围绕三个核心任务展开:特征构建(从现有字段派生新信息)、特征选择(剔除无关或冗余特征)、特征缩放(统一量纲与分布形态)。
核心原则:特征工程的目标不是堆砌更多特征,而是为模型提供“干净、有区分度、尺度一致”的输入空间。好的特征工程可以显著提升聚类边界清晰度与评分模型的稳定性。
4.1 特征构建:从原始字段派生新信息
特征构建(Feature Construction)指通过数学变换、业务组合或时间聚合,从已有字段中生成新的特征。在分群评分场景中,常见的构建方式包括:
- 数值组合:如“消费金额 / 消费次数”得到客单价,“收入 - 支出”得到可支配余额。
- 时间窗口聚合:近30天登录次数、近7天交易笔数、历史最大单笔金额。
- 类别编码:将城市、职业等类别字段转化为频次编码、目标编码或WOE编码。
- 多项式与交互项:年龄²、年龄×收入,用于捕捉非线性关系。
| 构建类型 | 原始字段示例 | 派生特征示例 | 适用场景 |
|---|---|---|---|
| 比率组合 | 总消费、总次数 | 平均客单价 | 客户价值分层 |
| 时间窗口 | 交易时间、金额 | 近30天交易总额 | 行为评分卡 |
| 类别频次 | 所在城市 | 城市出现频次 | 高基数类别处理 |
| 多项式 | 年龄 | 年龄²、年龄³ | 非线性拟合 |
# 特征构建示例(Python)
import pandas as pd
import numpy as np
df = pd.DataFrame({
'total_spend': [1200, 850, 2300],
'trans_count': [12, 5, 18],
'age': [25, 34, 45],
'income': [5000, 8000, 12000]
})
# 比率组合
df['avg_order'] = df['total_spend'] / df['trans_count']
# 多项式
df['age_sq'] = df['age'] ** 2
# 交互项
df['income_age'] = df['income'] * df['age']
print(df[['avg_order', 'age_sq', 'income_age']])
实践建议:特征构建应优先从业务逻辑出发,而非盲目穷举。在分群评分沙盘模型中,先构建与“风险、价值、活跃度”强相关的派生特征,再通过后续选择方法进行筛选。
4.2 特征选择:过滤法、包裹法与嵌入法
特征选择(Feature Selection)旨在从原始+构建的特征集中选出最优子集。根据是否依赖后续模型,分为三大流派:
4.2.1 过滤法(Filter Method)
独立于任何机器学习模型,仅基于统计指标对特征排序或筛选。计算效率高,适合高维数据预处理。
- 方差阈值:剔除方差接近0的常数特征。
- 相关系数:计算特征与目标变量的Pearson或Spearman相关系数。
- 卡方检验:适用于分类目标与类别特征。
- 互信息:衡量特征与目标之间的依赖程度。
4.2.2 包裹法(Wrapper Method)
将特征子集的选择视为搜索问题,使用目标模型的性能作为评价指标。通常效果更好,但计算开销大。
- 递归特征消除(RFE):反复训练模型,剔除权重最小的特征。
- 前向选择:从空集开始,逐步加入使模型性能提升最大的特征。
- 后向消除:从全特征开始,逐步剔除最不重要的特征。
4.2.3 嵌入法(Embedded Method)
特征选择内嵌于模型训练过程中,兼具过滤法的效率与包裹法的准确性。
- L1正则化(Lasso):通过惩罚项将不重要特征的系数压缩为0。
- 树模型特征重要性:随机森林、XGBoost等模型天然输出特征重要性排序。
- SelectFromModel:基于重要性阈值自动筛选特征。
| 方法 | 是否依赖模型 | 计算开销 | 典型算法/指标 | 推荐场景 |
|---|---|---|---|---|
| 过滤法 | 否 | 低 | 方差、卡方、互信息 | 高维数据初筛 |
| 包裹法 | 是 | 高 | RFE、前向选择 | 特征数较少时 |
| 嵌入法 | 是 | 中 | Lasso、树重要性 | 兼顾效率与效果 |
# 特征选择示例(Python)
from sklearn.feature_selection import SelectKBest, chi2, RFE
from sklearn.ensemble import RandomForestClassifier
from sklearn.linear_model import LogisticRegression
# 过滤法:卡方检验
X = df[['age', 'income', 'avg_order']]
y = [0, 1, 0] # 示例标签
selector = SelectKBest(score_func=chi2, k=2)
X_selected = selector.fit_transform(X, y)
# 包裹法:RFE
model = LogisticRegression()
rfe = RFE(estimator=model, n_features_to_select=2)
rfe.fit(X, y)
print("RFE选中特征索引:", rfe.support_)
# 嵌入法:随机森林重要性
rf = RandomForestClassifier()
rf.fit(X, y)
print("特征重要性:", rf.feature_importances_)
注意:包裹法在特征维度超过100时可能非常耗时。建议先用过滤法将特征压缩到合理范围(如50维以内),再使用包裹法或嵌入法进行精细选择。
4.3 特征缩放:标准化与归一化
特征缩放(Feature Scaling)解决不同特征量纲差异过大的问题。在分群评分模型中,距离计算(如K-Means、KNN)和梯度下降优化对尺度极其敏感。两种主流方法对比如下:
| 方法 | 公式 | 输出范围 | 对异常值敏感度 | 适用算法 |
|---|---|---|---|---|
| 标准化(Z-score) | z = (x - μ) / σ | 无固定范围,均值为0,标准差为1 | 中等 | 线性回归、SVM、PCA、神经网络 |
| 归一化(Min-Max) | x' = (x - min) / (max - min) | [0, 1] | 高(异常值会压缩正常值区间) | KNN、K-Means、神经网络(输入层) |
# 特征缩放示例(Python)
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import numpy as np
data = np.array([[100, 0.5], [200, 0.8], [1500, 0.3], [300, 0.9]])
# 标准化
scaler_std = StandardScaler()
data_std = scaler_std.fit_transform(data)
print("标准化结果:\n", data_std)
# 归一化
scaler_mm = MinMaxScaler()
data_mm = scaler_mm.fit_transform(data)
print("归一化结果:\n", data_mm)
选择指南:如果数据服从正态分布或算法假设高斯分布(如线性判别分析),优先使用标准化。如果数据有明确边界(如像素值0-255)或使用距离度量,归一化更合适。在分群评分沙盘模型中,建议先尝试标准化,因为聚类算法对异常值鲁棒性更强。
4.4 特征工程在分群评分沙盘中的完整流程
将上述三个步骤串联起来,形成可复用的特征工程流水线:
- 数据清洗:处理缺失值、异常值、重复记录。
- 特征构建:基于业务逻辑生成派生特征(比率、窗口、交互项)。
- 特征选择:先用过滤法快速剔除低信息特征,再用嵌入法(如Lasso或树模型)精筛。
- 特征缩放:对数值型特征进行标准化或归一化,类别型特征进行One-Hot或目标编码。
- 验证:在验证集上评估特征子集的稳定性与模型性能。
沙盘实操建议:在本次课程的分群评分沙盘项目中,建议先构建20-30个候选特征,使用过滤法保留前15个,再通过随机森林重要性选择前8-10个,最后对所有数值特征进行标准化。此流程在保证模型性能的同时,可有效控制过拟合风险。