机器学习特征工程实战:数据预处理与特征选择技巧
引言
在机器学习项目中,数据和特征决定了模型性能的上限,而算法和参数只是逼近这个上限。特征工程作为连接原始数据与机器学习算法的桥梁,是提升模型效果的关键环节。本文将从数据预处理与特征选择两个核心维度,结合常见面试题,分享实战技巧。
一、数据预处理:为模型准备“干净食材”
数据预处理是特征工程的第一步,旨在将原始数据转化为适合机器学习模型处理的格式。
1.1 缺失值处理
缺失值是现实数据中的常见问题。处理方式需根据缺失机制和数据分布决定。
面试题:如何处理数据集中的缺失值?有哪些常用方法?
解答与技巧:
- 删除: 若缺失样本比例极低(如<5%)或特征缺失严重(如>50%),可考虑删除。但需警惕引入偏差。
- 填充: 最常用的方法。
- 数值特征:可用均值、中位数、众数或基于其他特征的预测值填充。
- 分类特征:常用众数或新类别(如“Unknown”)填充。
- 高级方法: 使用KNN、模型预测(如随机森林)进行填充。
代码示例:使用Pandas和SimpleImputer进行缺失值填充
import pandas as pd
import numpy as np
from sklearn.impute import SimpleImputer
# 模拟含有缺失值的数据
np.random.seed(42)
data = pd.DataFrame({
'age': [25, np.nan, 35, 40, np.nan, 28],
'income': [50000, 60000, np.nan, 80000, 45000, np.nan],
'city': ['Beijing', 'Shanghai', np.nan, 'Beijing', 'Guangzhou', 'Shanghai']
})
print("原始数据:")
print(data)
# 数值列用中位数填充
num_imputer = SimpleImputer(strategy='median')
data[['age', 'income']] = num_imputer.fit_transform(data[['age', 'income']])
# 分类列用众数填充
cat_imputer = SimpleImputer(strategy='most_frequent')
data['city'] = cat_imputer.fit_transform(data[['city']])
print("\n填充后数据:")
print(data)
1.2 异常值检测与处理
异常值可能代表重要信息,也可能是噪声,需谨慎处理。
常用检测方法:
- 3σ原则/Z-score: 适用于近似正态分布的数据。
- IQR(四分位距)法: 更稳健,不依赖分布假设。
代码示例:使用IQR方法检测异常值
# 接续上例数据
Q1 = data['income'].quantile(0.25)
Q3 = data['income'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
outliers = data[(data['income'] < lower_bound) | (data['income'] > upper_bound)]
print(f"收入异常值:\n{outliers}")
# 处理方式:盖帽法(Capping)
data['income_capped'] = data['income'].clip(lower=lower_bound, upper=upper_bound)
1.3 数据标准化与归一化
许多算法(如SVM、KNN、神经网络)要求输入数据处于同一尺度。
- 标准化(Z-score): 使数据均值为0,标准差为1。对异常值有一定鲁棒性。
- 归一化(Min-Max): 将数据缩放到[0, 1]区间。对异常值敏感。
提示: 在数据探索阶段,使用 dblens SQL编辑器 可以快速对数据库中的原始数据进行统计描述(如计算均值、标准差、最大最小值),帮助判断该使用哪种缩放方法。其直观的界面和高效查询能力,能极大提升数据理解阶段的效率。
二、特征选择:去芜存菁的艺术
特征选择旨在从所有特征中选出对目标变量预测最有用的子集,以降低维度、减少过拟合、提升模型可解释性。
2.1 过滤法(Filter)
基于特征的统计属性进行排序和选择,独立于任何机器学习算法。
面试题:说出三种常用的过滤式特征选择方法及其原理。
解答与技巧:
- 方差选择法: 移除方差低于阈值的特征(认为变化小的特征信息量少)。
- 相关系数法: 计算特征与目标变量的相关系数(如皮尔逊相关系数用于回归,卡方检验用于分类),选择相关性高的。
- 互信息法: 衡量特征与目标变量之间的相互依赖程度,能捕捉非线性关系。
代码示例:使用SelectKBest基于卡方检验选择特征
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest, chi2
# 加载鸢尾花数据集
X, y = load_iris(return_X_y=True)
print(f"原始特征形状:{X.shape}")
# 选择卡方检验得分最高的2个特征(适用于分类问题)
selector = SelectKBest(score_func=chi2, k=2)
X_new = selector.fit_transform(X, y)
print(f"选择后特征形状:{X_new.shape}")
print(f"特征得分:{selector.scores_}")
print(f"选择的特征索引:{selector.get_support(indices=True)}")
2.2 包裹法(Wrapper)
将特征选择过程与特定学习算法结合,通过模型性能来评价特征子集。经典方法是递归特征消除(RFE)。
代码示例:使用RFE与逻辑回归进行特征选择
from sklearn.linear_model import LogisticRegression
from sklearn.feature_selection import RFE
model = LogisticRegression(max_iter=200)
rfe = RFE(estimator=model, n_features_to_select=2, step=1)
X_rfe = rfe.fit_transform(X, y)
print(f"RFE选择后特征形状:{X_rfe.shape}")
print(f"特征排名(1表示被选中):{rfe.ranking_}")
2.3 嵌入法(Embedded)
特征选择过程嵌入到模型训练过程中。最常见的是使用带正则化的模型(如Lasso/L1正则化)。
代码示例:使用Lasso回归进行特征选择
from sklearn.linear_model import Lasso
from sklearn.preprocessing import StandardScaler
# 回归问题示例,假设我们有一个目标变量y_reg
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
lasso = Lasso(alpha=0.01) # alpha是正则化强度
lasso.fit(X_scaled, y_reg) # y_reg是模拟的连续目标变量
# 系数为零的特征被认为是不重要的
selected_features = np.where(lasso.coef_ != 0)[0]
print(f"Lasso选择的特征索引:{selected_features}")
技巧分享: 在构建复杂特征池或进行特征重要性分析时,管理和记录每次实验的特征组合至关重要。推荐使用 QueryNote(https://note.dblens.com)来记录你的特征工程实验过程。它不仅能保存SQL查询和Python代码,还能关联结果和思路,形成可复现的特征实验笔记,是数据科学家和算法工程师进行高效迭代的得力工具。
三、高级技巧与注意事项
3.1 分箱(Binning)
将连续特征离散化为多个区间,可以处理非线性关系、平滑噪声、减少异常值影响。
3.2 交互特征与多项式特征
通过组合现有特征(如相乘、相加)来创建新特征,可能揭示更复杂的关系。但需警惕维度爆炸。
3.3 注意事项
- 数据泄露: 所有预处理和特征选择步骤都应在训练集上拟合,然后应用到验证集和测试集。
- 领域知识: 结合业务理解创造的特征(领域特征)往往威力巨大。
- 迭代性: 特征工程是一个迭代过程,需根据模型反馈不断调整。
总结
特征工程是机器学习项目中耗时最长、最需要创造力和经验的环节。本文系统梳理了数据预处理(缺失值、异常值、标准化)和特征选择(过滤法、包裹法、嵌入法)的核心技巧与常见面试题。记住,没有一成不变的“银弹”,最佳实践往往源于对数据的深刻理解、不断的实验迭代以及合适的工具辅助。
通过结合像 dblens SQL编辑器 这样的高效数据探查工具和 QueryNote 这样的实验管理工具,你可以更系统、更高效地完成特征工程任务,为构建高性能的机器学习模型打下坚实基础。
本文来自博客园,作者:DBLens数据库开发工具,转载请注明原文链接:https://www.cnblogs.com/dblens/p/19553452
浙公网安备 33010602011771号