特征工程

第24课:编码与缩放

类别编码、数值缩放、One-Hot、Target编码、分布变换

1. 类别编码

One-Hot: 不引入序关系,但高基数→维度爆炸。标签编码: 有序类别(差→优)。

目标编码: 用类别目标均值替代(需CV内计算防泄露)。频率编码: 用出现频率。

树模型→标签/目标编码效果好。线性模型→One-Hot安全。

2. 数值缩放

方法异常值输出
StandardScaler敏感无界
MinMaxScaler极敏感[0,1]
RobustScaler稳健无界
MaxAbsScaler敏感[-1,1]

不需要缩放: 决策树、随机森林

3. Pipeline最佳实践

数据泄露: 必须只在训练集fit scaler→Scikit-learn Pipeline自动处理。

ColumnTransformer: 对不同列应用不同变换。

Python代码实现与验证

💡 代码说明:以下代码使用 Python / Scikit-learn 实现,已实机运行验证。

完整代码


import numpy as np
from sklearn.preprocessing import StandardScaler, MinMaxScaler, RobustScaler, OneHotEncoder, OrdinalEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.datasets import load_iris
np.random.seed(42)

X = np.random.randn(100,3)*[10,1,100]+[50,0,-200]
print("=== 缩放对比 ===")
for name,sc in [('Standard',StandardScaler()),('MinMax',MinMaxScaler()),('Robust',RobustScaler())]:
    Xs = sc.fit_transform(X)
    print("{}: mean={} std={}".format(name, Xs.mean(0).round(3), Xs.std(0).round(3)))

X_out = np.vstack([X,[[500,500,500]]])
print("\n=== 异常值影响 ===")
for name,sc in [('Standard',StandardScaler()),('MinMax',MinMaxScaler()),('Robust',RobustScaler())]:
    Xs = sc.fit_transform(X_out)[:-1]
    print("{}: mean={}".format(name, Xs.mean(0).round(3)))

print("\n=== 类别编码 ===")
oe = OrdinalEncoder(categories=[['差','中','良','优']])
data = np.array([['差'],['良'],['中'],['优'],['差']])
print("序数编码: {}".format(oe.fit_transform(data).ravel()))

ohe = OneHotEncoder(sparse_output=False)
dm = np.array([['A','X'],['B','Y'],['A','Z']])
enc = ohe.fit_transform(dm)
print("One-Hot: shape={} features={}".format(enc.shape, list(ohe.get_feature_names_out())))

iris = load_iris()
pipe = Pipeline([('s',StandardScaler()),('lr',LogisticRegression(max_iter=200))])
s = cross_val_score(pipe, iris.data, iris.target, cv=5)
print("\nPipeline CV: {:.4f}".format(s.mean()))

运行结果

=== 缩放对比 === Standard: mean=[0. 0. 0.] std=[1. 1. 1.] MinMax: mean=[0.499 0.55 0.416] std=[0.2 0.175 0.171] Robust: mean=[-0.114 0.033 -0.027] std=[0.836 0.712 0.751] === 异常值影响 === Standard: mean=[-0.098 -0.1 -0.053] MinMax: mean=[0.044 0.006 0.28 ] Robust: mean=[-0.118 0.029 -0.037] === 类别编码 === 序数编码: [0. 2. 1. 3. 0.] One-Hot: shape=(3, 5) features=['x0_A', 'x0_B', 'x1_X', 'x1_Y', 'x1_Z'] Pipeline CV: 0.9600
✅ 验证通过

深入理解:特征工程的精髓

"特征工程是决定模型上限的关键"

业界共识:好的特征工程比好的模型更重要。一个线性模型配上优秀特征可以超越复杂模型配普通特征。

特征工程流程

  1. 理解业务:领域知识是最好的特征来源
  2. EDA发现:从数据中发现模式→构造特征
  3. 变换:对数/Box-Cox处理偏态,分箱处理非线性
  4. 编码:类别→数值,选择合适编码方式
  5. 缩放:数值特征标准化/归一化
  6. 选择:删除无关/冗余特征
  7. 验证:交叉验证评估特征贡献

Kaggle竞赛中的特征工程技巧

常见特征工程错误

  1. 数据泄露:在特征构造中使用了未来信息
  2. 目标泄露:特征中包含了目标变量的信息
  3. 过拟合特征:在训练集上有效但测试集失效
  4. 忽略缺失模式:缺失本身可能是有价值的特征
  5. 不验证:没有用交叉验证确认特征的实际贡献

进阶特征工程技巧

Kaggle竞赛中的特征工程

在Kaggle竞赛中,特征工程是区分Top 1%和Top 10%的关键。以下是从顶级选手那里学到的技巧:

聚合特征:对时序数据,按实体ID聚合历史行为的统计量——均值、标准差、最小最大、趋势斜率、最近N次的均值变化。这些"在用户层面的历史摘要"往往是最强特征。
目标编码:高基数类别特征(如城市名2000+类)的杀手锏。关键:必须在5折CV内计算,使用平滑参数防止小样本类别不稳定。公式:enc = (count*mean + m*global_mean)/(count+m),m通常取10-100。
比率特征:两个相关特征的比值常常比原始特征更有信息量。贷款金额/年收入、月供/月收入、信用额度使用率等。这些比率捕捉了"相对"而非"绝对"信息。

数据泄露防范完整清单

  1. 目标泄露:特征包含目标信息——检查每个特征与目标的互信息
  2. 时间泄露:用了未来数据——特征构造时只用截止时间前的数据
  3. 组泄露:同组数据分布在训练和测试集——使用GroupKFold
  4. 预处理泄露:全数据fit scaler——用Pipeline自动处理
  5. 特征选择泄露:在CV外选特征——特征选择必须在CV内

缺失值处理策略决策树

交叉验证的常见错误

错误的交叉验证比没有交叉验证更危险——它给你虚假的信心。

补充:关键概念与面试要点

核心直觉

常见面试问题

  1. L1正则化为什么产生稀疏解?(几何:菱形与等高线在角上相交)
  2. 逻辑回归为什么用交叉熵而不用MSE?(MSE导致梯度消失)
  3. 随机森林为什么不容易过拟合?(Bagging降方差,特征随机降相关性)
  4. K-Means为什么收敛到局部最优?(目标函数非凸)
  5. PCA为什么需要中心化?(否则第一主成分指向均值方向)

补充:关键概念与面试要点

核心直觉

常见面试问题

  1. L1正则化为什么产生稀疏解?(几何:菱形与等高线在角上相交)
  2. 逻辑回归为什么用交叉熵而不用MSE?(MSE导致梯度消失)
  3. 随机森林为什么不容易过拟合?(Bagging降方差,特征随机降相关性)
  4. K-Means为什么收敛到局部最优?(目标函数非凸)
  5. PCA为什么需要中心化?(否则第一主成分指向均值方向)

补充:关键概念与面试要点

核心直觉

常见面试问题

  1. L1正则化为什么产生稀疏解?(几何:菱形与等高线在角上相交)
  2. 逻辑回归为什么用交叉熵而不用MSE?(MSE导致梯度消失)
  3. 随机森林为什么不容易过拟合?(Bagging降方差,特征随机降相关性)
  4. K-Means为什么收敛到局部最优?(目标函数非凸)
  5. PCA为什么需要中心化?(否则第一主成分指向均值方向)

补充:关键概念与面试要点

核心直觉

常见面试问题

  1. L1正则化为什么产生稀疏解?(几何:菱形与等高线在角上相交)
  2. 逻辑回归为什么用交叉熵而不用MSE?(MSE导致梯度消失)
  3. 随机森林为什么不容易过拟合?(Bagging降方差,特征随机降相关性)
  4. K-Means为什么收敛到局部最优?(目标函数非凸)
  5. PCA为什么需要中心化?(否则第一主成分指向均值方向)

补充:关键概念与面试要点

核心直觉

常见面试问题

  1. L1正则化为什么产生稀疏解?(几何:菱形与等高线在角上相交)
  2. 逻辑回归为什么用交叉熵而不用MSE?(MSE导致梯度消失)
  3. 随机森林为什么不容易过拟合?(Bagging降方差,特征随机降相关性)
  4. K-Means为什么收敛到局部最优?(目标函数非凸)
  5. PCA为什么需要中心化?(否则第一主成分指向均值方向)

补充:关键概念与面试要点

核心直觉

常见面试问题

  1. L1正则化为什么产生稀疏解?(几何:菱形与等高线在角上相交)
  2. 逻辑回归为什么用交叉熵而不用MSE?(MSE导致梯度消失)
  3. 随机森林为什么不容易过拟合?(Bagging降方差,特征随机降相关性)
  4. K-Means为什么收敛到局部最优?(目标函数非凸)
  5. PCA为什么需要中心化?(否则第一主成分指向均值方向)

补充:关键概念与面试要点

核心直觉

常见面试问题

  1. L1正则化为什么产生稀疏解?(几何:菱形与等高线在角上相交)
  2. 逻辑回归为什么用交叉熵而不用MSE?(MSE导致梯度消失)
  3. 随机森林为什么不容易过拟合?(Bagging降方差,特征随机降相关性)
  4. K-Means为什么收敛到局部最优?(目标函数非凸)
  5. PCA为什么需要中心化?(否则第一主成分指向均值方向)

补充:关键概念与面试要点

核心直觉

常见面试问题

  1. L1正则化为什么产生稀疏解?(几何:菱形与等高线在角上相交)
  2. 逻辑回归为什么用交叉熵而不用MSE?(MSE导致梯度消失)
  3. 随机森林为什么不容易过拟合?(Bagging降方差,特征随机降相关性)
  4. K-Means为什么收敛到局部最优?(目标函数非凸)
  5. PCA为什么需要中心化?(否则第一主成分指向均值方向)

📝 课后练习

  1. 实现本课核心算法并用Scikit-learn验证
  2. 调优关键超参数并记录性能变化
  3. 用交叉验证评估模型稳定性
  4. 与之前学过的方法对比分析
  5. 分析本课方法的失效条件
🔤
编码专家
掌握类别编码和数值缩放的最佳实践