特征工程入门:特征提取、特征选择、特征变换
特征工程,说白了就是让数据变得更好用。我做了这么多年算法,见过不少项目在模型上死磕调参,结果效果还不如别人把特征好好洗一遍。你想想看,模型能学到什么,很大程度上取决于你喂给它的特征长什么样。
这个章节咱们就聊三个最基本的动作:提取、选择、变换。它们分别解决不同的问题——「有没有」、「好不好」、「对不对」。我把这三步串联起来,就是一套完整的特征加工流程。
一、特征提取
特征提取,就是从原始数据里「挖」出新特征。原始数据往往不是直接能用的格式。比如一段文本、一个时间戳、一串日志。你需要把它们转成数值。我早期做电商推荐时,用户行为日志全是字符串,根本喂不进模型。后来学会把「浏览时长」「点击次数」「加购间隔」这些信息抽出来,模型效果一下子就上去了。
常见场景我列一下:
| 数据类型 | 提取方法 | 典型输出 |
|---|---|---|
| 文本 | TF-IDF / Word2Vec | 高维稀疏向量 |
| 时间戳 | 分解为年/月/日/星期/小时 | 多个数值列 |
| 图像 | 边缘检测 / 颜色直方图 | 特征向量 |
| 日志序列 | 滑动窗口统计量 | 均值、方差、趋势 |
举个例子。假设你有一个时间戳字段 2024-12-01 14:35:20,直接扔给模型它看不懂。我一般会这么拆:
import pandas as pd
ts = pd.to_datetime('2024-12-01 14:35:20')
features = {
'year': ts.year,
'month': ts.month,
'day': ts.day,
'hour': ts.hour,
'weekday': ts.weekday(),
'is_weekend': 1 if ts.weekday() >= 5 else 0,
'quarter': ts.quarter
}
二、特征选择
特征多了,不一定就好。我见过一个团队把特征做到 2000 维,结果模型训练慢,还过拟合。特征选择的任务,就是帮你砍掉冗余、噪声和不相关的特征。
常用的方法分三类。我习惯把它们列成一个对比表,方便选型:
| 方法 | 核心思路 | 优缺点 |
|---|---|---|
| 过滤法 | 统计指标筛选(卡方、互信息、方差) | 快,但忽略特征间交互 |
| 包裹法 | 用模型效果评估特征子集(RFE) | 效果好,计算成本高 |
| 嵌入法 | 模型自带特征权重(L1正则、树模型重要性) | 折中方案,推荐优先试 |
举个例子,使用卡方检验过滤文本分类特征:
from sklearn.feature_selection import SelectKBest, chi2
from sklearn.feature_extraction.text import CountVectorizer
# 假设已有文本数据 X_text 和标签 y
vec = CountVectorizer(max_features=2000)
X_bow = vec.fit_transform(X_text)
selector = SelectKBest(chi2, k=300)
X_selected = selector.fit_transform(X_bow, y)
三、特征变换
特征变换,就是改变特征的「数值形态」或「空间结构」。目的很明确:让模型更容易拟合。说白了,就是消除量纲影响、处理长尾分布、或者降维。
我平时用得最多的几个:
- 归一化(Min-Max Scaling): 把数据压缩到 [0,1] 区间。适合边界明确的场景。
- 标准化(Z-score): 转化为均值为0、标准差为1。适合大多数树模型以外的场景。
- 对数变换: 拉近长尾分布。我处理用户消费金额时经常用。
- PCA: 线性降维,保留主要信息。
代码实现很简单:
from sklearn.preprocessing import StandardScaler, MinMaxScaler
import numpy as np
data = np.array([[100], [200], [300], [1000], [5000]])
# 标准化
scaler = StandardScaler()
std_data = scaler.fit_transform(data)
# 对数变换(先取log再标准化)
log_data = np.log1p(data)
log_std = scaler.fit_transform(log_data)
四、三步协同流程
前面三个步骤,在实际项目里不是串行走一遍就完事的。它们之间会互相影响。比如说,你做了特征选择之后发现效果不好,可能需要回到提取阶段再挖一些新特征。或者变换之后方差变小了,原来能选上的特征又被筛掉了。
我自己的习惯是这样组合:
- 粗提取 —— 先快速从原始数据里拿到一批基础特征,不要太完美,够用就行。
- 初筛 —— 用过滤法或树模型重要性做一次快速筛选,把明显没用的砍掉。
- 变换+精筛 —— 对剩余特征做标准化或对数变换,再用包裹法或嵌入法做二次选择。
- 迭代 —— 看模型表现,决定是否回到第一步。
这个流程我在好几个项目里实践过,稳得很。尤其是遇到特征量超过 1000 的数据集,这套方法能把时间从半天压缩到一小时以内。