特征工程是数据挖掘、机器学习流程中的核心环节,其质量直接决定模型的最终效果 ------数据和特征决定了模型的上限,算法和调参只是逼近这个上限的手段。
一、 什么是特征工程
特征工程是指从原始数据中提取、构造、筛选、转换出具有代表性、区分度和鲁棒性的特征,以此提升模型对数据规律的捕捉能力的一系列操作。
简单来说,原始数据往往是杂乱无章、维度冗余或不符合模型输入要求的,特征工程就是对原始数据进行 "加工",让数据变成模型能 "看懂" 且 "用好" 的形式。
- 核心目标:降低数据冗余、提升特征与目标变量的相关性、增强数据的可区分性、适配模型的输入规范。
- 重要性:对于结构相似的算法,基于优质特征训练的简单模型,效果往往优于基于劣质特征训练的复杂模型。
二、特征工程的内容
特征工程是一个系统性流程,贯穿于数据预处理之后、模型训练之前,主要包含以下 4 个核心阶段:
1.特征提取
这是特征工程的起点,目标是从不同类型的原始数据中提取出可量化的特征。原始数据类型不同,提取方式差异较大:
结构化数据:如数据库表、Excel 表格,本身以数值、类别等形式存储,提取过程以筛选、整合为主,例如从用户信息表中提取 "年龄""性别""消费金额" 等字段作为基础特征。
非结构化数据:如文本、图像、音频,需要通过专门的技术将其转化为结构化特征:
- 文本数据:提取词频(TF)、逆文档频率(IDF)、词嵌入(Word Embedding)等特征;
- 图像数据:提取边缘、纹理、颜色直方图,或通过 CNN 模型提取深层视觉特征;
- 音频数据:提取梅尔频率倒谱系数(MFCC)、短时能量、过零率等特征。
2.特征构造
也叫特征衍生,是在已有基础特征上,通过数学运算、业务逻辑组合生成新特征的过程,目的是挖掘数据中隐藏的非线性关系和业务规律。
基于数学运算:对数值特征进行加减乘除、对数变换、幂变换等,例如用 "消费总额 ÷ 消费次数" 构造 "单次平均消费额" 特征。
基于业务逻辑:结合行业知识生成特征,例如在风控场景中,用 "逾期次数 ÷ 总借款次数" 构造 "逾期率" 特征;在电商场景中,用 "浏览时长 × 收藏次数" 构造 "用户兴趣度" 特征。
基于统计聚合:对时序数据或分组数据进行统计,例如按用户分组计算 "近 30 天消费均值""最大消费金额" 等。
3.特征转换
将构造好的特征转换为适合模型输入的形式,解决数据分布、量纲、类型不匹配等问题,主要针对两类特征:
数值型特征:
- 量纲统一:如标准化(Z-Score)、归一化(Min-Max),解决不同特征数值范围差异大的问题(例如 "年龄" 范围是 0-100,"收入" 范围是 0-100000);
- 分布变换:如对数变换、Box-Cox 变换,将非正态分布的数据转化为近似正态分布,提升线性模型的效果。
类别型特征:
- 编码处理:如独热编码(One-Hot Encoding)、标签编码(Label Encoding)、目标编码(Target Encoding),将字符串或离散类别转化为数值形式,适配模型的数值输入要求。
4.特征选择
原始特征经过提取、构造后可能存在维度高、冗余、噪声大的问题,特征选择的目标是保留与目标变量相关性高、区分度强的特征,剔除无用特征。
核心作用:降低模型复杂度、减少过拟合风险、提升模型训练效率、增强模型可解释性。
选择依据:特征与目标的相关性、特征间的冗余度、特征对模型性能的贡献度。
三、特征工程的常用方法
1.特征提取常用方法
|-------|------------------------------|--------------------|
| 数据类型 | 常用方法 | 适用场景 |
| 结构化数据 | 字段筛选、数据清洗 | 直接从数据库 / 表格中提取基础特征 |
| 文本数据 | TF-IDF、Word2Vec、BERT 词嵌入 | 文本分类、情感分析、相似度计算 |
| 图像数据 | 颜色直方图、SIFT/SURF 特征、CNN 预训练模型 | 图像分类、目标检测、图像检索 |
| 音频数据 | MFCC、短时傅里叶变换(STFT) | 语音识别、声纹识别、音频分类 |
2.特征构造常用方法
(1)数值特征组合
- 算术运算:特征间加减乘除(如
人均消费=总消费/消费次数); - 统计聚合:分组统计(
max/min/mean/std/count)、滑动窗口统计(时序数据的移动平均)。
(2)类别特征交叉
- 特征组合:将多个类别特征拼接,例如
城市+商品类别生成新的组合特征,捕捉交叉规律。
(3)业务规则衍生
- 基于行业知识构造,例如金融风控中的
负债率=负债总额/资产总额、电商中的复购率=复购次数/购买次数。
3.特征转换常用方法
(1)数值特征转换
- 标准化(Z-Score) :
,将特征转化为均值为 0、方差为 1 的分布,适用于线性回归、SVM、神经网络等对量纲敏感的模型;
- 归一化(Min-Max) :
,将特征缩放到 [0,1] 区间,适用于需要归一化输入的模型(如多层感知机)或距离相关算法(如 KNN);
- 分布变换:对数变换(处理右偏分布数据,如用户消费金额)、Box-Cox 变换(自动选择最优变换参数)。
(2)类别特征转换
独热编码:为每个类别生成一个二进制特征,适用于无顺序的类别(如颜色:红、蓝、绿),避免模型误认为类别存在大小关系;
标签编码 :将类别映射为连续整数(如猫=0,狗=1,兔=2),适用于有顺序的类别(如成绩:低 = 0,中 = 1,高 = 2);
目标编码:用类别对应的目标变量均值作为编码值,适用于类别基数大的场景(如用户 ID),但需注意防止过拟合。
4.特征选择常用方法
特征选择方法可分为三大类:
(1)过滤法(Filter)
核心思想:按照特征的统计指标独立筛选,不依赖模型,计算速度快;
常用方法:
- 相关性分析:皮尔逊相关系数(数值特征)、卡方检验(类别特征)、互信息(衡量特征与目标的依赖关系);
- 方差阈值:剔除方差过小的特征(如特征值几乎无变化的常量特征)。
(2)包裹法(Wrapper)
核心思想:将特征选择看作搜索问题,用模型性能评估特征子集的优劣,选择最优子集;
常用方法:递归特征消除(RFE)------ 从全特征开始,逐步剔除对模型贡献最小的特征,直到达到指定特征数。
优缺点:效果好,但计算成本高,适用于小样本、低维度数据。
(3)嵌入法(Embedded)
核心思想:特征选择与模型训练同步进行,模型在训练过程中自动学习特征的重要性;
常用方法:
- L1 正则化(Lasso):通过惩罚项让部分特征的系数变为 0,实现特征筛选;
- 树模型特征重要性:决策树、随机森林、XGBoost 等模型可输出特征的重要性得分,据此筛选特征。
优缺点:兼顾过滤法的高效和包裹法的准确性,是工业界常用方法。
四、特征工程实操步骤
1.前置准备
数据准备:导入原始数据集,完成基础清洗(处理缺失值、异常值、重复值)
python
import pandas as pd; df = pd.read_csv("data.csv");
df.drop_duplicates(inplace=True)
明确目标 :区分目标变量 (如分类任务的label、回归任务的price)和特征变量(其余字段)
2.特征提取(从原始数据中获取基础特征)
结构化数据字段筛选,选择与业务相关字段:
python
features = df[["age","income","gender"]]
文本特征提取(TF-IDF),用sklearn实现:
python
from sklearn.feature_extraction.text import TfidfVectorizer<br>tfidf = TfidfVectorizer()<br>text_feat = tfidf.fit_transform(df["text"])
图像特征提取(颜色直方图),用OpenCV计算:
python
import cv2<br>img = cv2.imread("img.jpg")<br>hist = cv2.calcHist([img],[0],None,[256],[0,256])
3.特征构造(衍生新特征)
数值特征算术组合,构造比率 / 乘积特征:
python
df["avg_income"] = df["total_income"] / df["work_years"]
分组统计聚合,按用户分组计算均值 / 最大值:
python
df["user_month_mean"] = df.groupby("user_id")["month_amt"].transform("mean")
类别特征交叉,拼接两个类别特征:
python
df["city_product"] = df["city"] + "_" + df["product_type"]
时序滑动窗口统计,计算近 3 期移动平均:
python
df["rolling_3d"] = df["amt"].rolling(window=3).mean()
4.特征转换(适配模型输入要求)
(1)数值特征转换
|--------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 方法 | 适用场景 | Python 实现 |
| 标准化(Z-Score) | 线性回归、SVM、神经网络 | from sklearn.preprocessing import StandardScaler<br>scaler = StandardScaler()<br>df[["age","income"]] = scaler.fit_transform(df[["age","income"]]) |
| 归一化(Min-Max) | KNN、多层感知机 | from sklearn.preprocessing import MinMaxScaler<br>scaler = MinMaxScaler()<br>df[["amt"]] = scaler.fit_transform(df[["amt"]]) |
| 对数变换 | 右偏分布数据(如消费金额) | df["log_amt"] = np.log1p(df["amt"])(log1p 避免 0 值报错) |
(2)类别特征转换
独热编码:
无顺序类别(颜色、城市)
python
from sklearn.preprocessing import OneHotEncoder<br>ohe = OneHotEncoder(sparse_output=False)<br>cat_feat = ohe.fit_transform(df[["gender"]])
标签编码:
有顺序类别(成绩等级)
python
from sklearn.preprocessing import LabelEncoder<br>le = LabelEncoder()<br>df["grade_code"] = le.fit_transform(df["grade"])
目标编码:
高基数类别(用户 ID、商品 ID),用category_encoders库:
python
from category_encoders import TargetEncoder<br>te = TargetEncoder()<br>df["user_te"] = te.fit_transform(df["user_id"], df["target"])
5.特征选择(筛选最优特征子集)
(1)过滤法
皮尔逊相关系数,计算特征与目标的相关性:
python
corr = df.corr()["target"].sort_values(ascending=False)
方差阈值,剔除低方差特征:
python
from sklearn.feature_selection import VarianceThreshold<br>vt = VarianceThreshold(threshold=0.1)<br>selected_feat = vt.fit_transform(df[features])
(2)包裹法
递归特征消除(RFE)
python
from sklearn.feature_selection import RFE<br>from sklearn.linear_model import LinearRegression<br>rfe = RFE(estimator=LinearRegression(), n_features_to_select=5)<br>selected = rfe.fit_transform(X, y)
(3)嵌入法
L1 正则化(Lasso)
python
from sklearn.linear_model import Lasso<br>lasso = Lasso(alpha=0.1)<br>lasso.fit(X, y)
树模型特征重要性
python
from sklearn.ensemble import RandomForestRegressor<br>rf = RandomForestRegressor()<br>rf.fit(X, y)<br>importance = pd.Series(rf.feature_importances_, index=X.columns)
注意事项
- 特征工程需结合业务知识,避免盲目构造无意义特征;
- 转换和选择步骤需遵循 "先划分训练集和测试集,再在训练集上拟合转换器 / 选择器,最后用其转换测试集" 的原则,防止数据泄露;
- 高基数类别特征慎用独热编码,否则会导致维度爆炸。