特征预处理
作为机器学习初学者,理解特征预处理就像学做菜前必须学会的"洗菜、切配、腌制"——它直接决定了最终模型的口感(性能)。我会用最生活化的比喻+代码示例带你轻松掌握这个必备技能。
一、为什么要特征预处理?
原始数据的问题:
-
有的食材(特征)用"克"做单位,有的用"斤" → 量纲不统一
-
洋葱味道太冲,盖过其他食材 → 数值差异过大
-
有些食材已经变质 → 存在缺失值或异常值
预处理的目标:让所有特征站在同一起跑线上,公平竞争。
二、数值型特征处理
1. 标准化(Standardization)
作用:把数据变成均值为0、标准差1的正态分布
公式:
x′=x−均值标准差x′=标准差x−均值
类比:把所有人的身高减去平均身高,再除以"高矮的波动程度"
from sklearn.preprocessing import StandardScalerdata = [[170], [180], [160]]
scaler = StandardScaler()
print(scaler.fit_transform(data))
输出:
[[ 0. ][ 1. ][-1. ]]
2. 归一化(Normalization)
作用:把数据压缩到[0,1]或[-1,1]区间
公式:
x′=x−最小值最大值−最小值x′=最大值−最小值x−最小值
类比:把考试成绩从0-100分换算成0-1分
from sklearn.preprocessing import MinMaxScalerdata = [[100], [80], [60]]
scaler = MinMaxScaler()
print(scaler.fit_transform(data))
输出:
[[1. ][0.5][0. ]]
3. 处理异常值
方法:
-
截断(Clipping):设定上下限
np.clip(data, a_min=10, a_max=90)
-
鲁棒缩放(Robust Scaling):用中位数和四分位距
from sklearn.preprocessing import RobustScaler
三、类别型特征处理
1. 独热编码(One-Hot Encoding)
作用:把类别变成二进制向量
类比:把"颜色"(红/绿/蓝)变成三个开关
import pandas as pddf = pd.DataFrame({"颜色": ["红", "绿", "蓝"]})
print(pd.get_dummies(df))
输出:
颜色_红 颜色_绿 颜色_蓝
0 1 0 0
1 0 1 0
2 0 0 1
2. 标签编码(Label Encoding)
作用:给类别分配数字编号(注意:可能引入虚假大小关系)
from sklearn.preprocessing import LabelEncoderle = LabelEncoder()
df["颜色编码"] = le.fit_transform(df["颜色"])
四、缺失值处理
常见方法:
方法 | 代码示例 | 适用场景 |
---|---|---|
删除缺失样本 | df.dropna() | 缺失值很少时 |
用均值/中位数填充 | df.fillna(df.mean()) | 数值型数据 |
用众数填充 | df.fillna(df.mode()[0]) | 类别型数据 |
预测填充 | 用其他特征预测缺失值 | 缺失值与其他特征相关 |
五、时间型特征处理
df["日期"] = pd.to_datetime(df["日期"])
df["年份"] = df["日期"].dt.year
df["是否周末"] = df["日期"].dt.weekday > 4
六、特征选择技巧
1. 过滤式(Filter)
-
方差阈值:删除方差接近0的特征
from sklearn.feature_selection import VarianceThreshold
-
相关性筛选:选择与目标值相关性高的特征
2. 嵌入式(Embedded)
-
用L1正则化让模型自动选择特征
from sklearn.linear_model import Lasso
七、完整预处理流水线
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputerpipeline = Pipeline([('imputer', SimpleImputer(strategy='median')), # 缺失值填充('scaler', StandardScaler()), # 标准化('selector', VarianceThreshold(threshold=0.1)) # 特征选择
])
X_processed = pipeline.fit_transform(X)
八、避坑指南
-
❌ 不要先切分数据集再预处理:会导致数据泄露(应该先切分,再分别预处理)
-
✅ 分类变量很多时:优先用
Target Encoding
代替One-Hot -
📊 可视化验证:预处理前后用箱线图对比分布变化
九、实战案例:预测房价
-
数值特征:
面积
→ 标准化 -
类别特征:
地段
→ One-Hot编码 -
时间特征:
建造年份
→ 计算房龄 -
异常值:
面积>1000㎡
→ 截断处理
# 完整示例
df["房龄"] = 2023 - df["建造年份"]
df["面积"] = np.clip(df["面积"], 0, 500)
记住:数据和特征决定了模型的上限,而预处理就是逼近这个上限的关键步骤!下一步可以用Kaggle的House Prices数据集练习完整流程。