1. 什么是特征工程?
特征工程是指通过对原始数据进行处理和转换,创建出能够更好地描述问题本质的特征(Feature),从而提高机器学习模型性能的过程。简单来说,它是将“原始数据”变成“对模型更有用、更容易理解的数据”的艺术与科学。
特征的定义
特征是数据集中的一个变量(或列),通常用来描述数据的某种属性。例如,在一个预测房价的数据集中,房子的面积、卧室数量、所在城市等都是特征。
特征工程的目标
- 提高模型性能:通过创建更有信息量的特征,帮助模型更好地捕捉数据中的模式。
- 降低模型复杂性:好的特征可以让简单的模型(如线性回归)表现得更好,减少对复杂模型的依赖。
- 增强模型的泛化能力:通过去除噪声、处理异常值等操作,使模型在未见过的数据上表现更好。
- 适应模型需求:不同模型对特征的要求不同(例如,树模型对特征缩放不敏感,但神经网络需要归一化),特征工程需要为特定模型优化。
2. 为什么特征工程重要?
特征工程是机器学习 pipeline 中最耗时但又最关键的步骤之一。以下是它的重要性:
-
原始数据通常不适合直接建模:
- 原始数据可能包含噪声、缺失值、冗余信息或不一致的格式。
- 例如,日期字段(如“2023-10-01”)对模型无意义,需要提取出“年份”“月份”或“是否是周末”等特征。
-
特征决定模型的上限:
- 再强大的算法(如深度神经网络)也依赖于输入特征的质量。Garbage in, garbage out(垃圾输入,垃圾输出)。
- 一个精心设计的特征可以让简单的逻辑回归模型击败复杂的深度学习模型。
-
领域知识的体现:
- 特征工程是将领域知识(Domain Knowledge)融入模型的过程。例如,在医疗数据中,医生可能知道“血压”和“心率”的组合比单个指标更有意义。
-
减少过拟合:
- 通过特征选择或降维,去除无关或冗余的特征,降低模型过拟合的风险。
3. 特征工程的完整流程
特征工程通常包括以下几个步骤:
-
数据探索与理解:
- 分析数据的分布、缺失值、异常值、相关性等。
- 工具:Pandas、Matplotlib、Seaborn 等。
- 例如,检查房价数据中是否有异常值(如面积为负值)。
-
数据清洗:
- 处理缺失值、异常值、重复值等。
- 例如,用均值填补缺失的年龄数据,或删除异常的房价记录。
-
特征创建:
- 通过数学变换、组合、分解等方式创建新特征。
- 例如,从“出生日期”提取“年龄”,或将“收入”和“支出”组合成“净收入”。
-
特征转换:
- 对特征进行标准化、归一化、对数变换等,使其适合模型。
- 例如,将收入特征(范围可能是 0 到百万)归一化到 [0, 1] 区间。
-
特征选择:
- 选择对模型最重要的特征,减少维度和噪声。
- 例如,使用相关系数或树模型的特征重要性进行筛选。
-
特征编码:
- 将非数值型数据(如类别变量)转换为模型可以理解的数值形式。
- 例如,将“城市”字段编码为独热编码(One-Hot Encoding)。
-
验证与迭代:
- 通过交叉验证评估特征对模型性能的贡献,迭代优化特征。
4. 特征工程的常见技术
下面我将详细讲解特征工程中的常见技术,并附上代码示例(基于 Python 和 Pandas)。
4.1 数据清洗
处理缺失值
缺失值是数据集中的常见问题,可能导致模型无法正常训练。常见处理方法:
- 删除:如果缺失值比例很小,可以删除包含缺失值的行或列。
- 填补:
- 用均值、中位数、众数填补数值型特征。
- 用“未知”或最常见类别填补类别型特征。
- 使用模型(如 KNN 或回归)预测缺失值。
- 标记缺失值:为缺失值创建一个新的二元特征,表示“是否缺失”。
代码示例:
import pandas as pd
import numpy as np
# 示例数据集
data = pd.DataFrame({
'age': [25, np.nan, 30, 35, np.nan],
'city': ['Beijing', 'Shanghai', np.nan, 'Guangzhou', 'Shenzhen']
})
# 用均值填补年龄
data['age'].fillna(data['age'].mean(), inplace=True)
# 用“未知”填补城市
data['city'].fillna('Unknown', inplace=True)
print(data)
处理异常值
异常值可能扭曲模型的训练。常见方法:
- 基于统计方法:用标准差或 IQR(四分位距)检测异常值。
- 基于领域知识:根据业务逻辑定义异常值(如房价不能为负)。
- 处理方式:删除、替换(如用中位数)、或对异常值单独建模。
代码示例:
# 检测并替换异常值
Q1 = data['age'].quantile(0.25)
Q3 = data['age'].quantile(0.75)
IQR = Q3 - Q1
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
# 将异常值替换为中位数
data['age']

最低0.47元/天 解锁文章
290

被折叠的 条评论
为什么被折叠?



