特征工程流程图
数据清洗 → 特征编码 → 特征转换 → 特征生成 → 特征选择 → 数据整合
↑ ↓
└─数据探索───┘
各步骤详解、注意事项及Scikit-learn函数
1. 数据清洗
- 目标:处理缺失值、异常值、重复数据。
- 注意事项:
- 缺失值填充需根据数据分布选择方法(均值、中位数、众数)。
- 异常值需结合业务逻辑判断是否删除或修正。
- Scikit-learn函数:
SimpleImputer
:填充缺失值。from sklearn.impute import SimpleImputer imputer = SimpleImputer(missing_values=np.nan, strategy='mean') # strategy: mean/median/most_frequent
2. 特征编码
- 目标:将分类特征(字符串或类别)转换为数值形式。
- 注意事项:
- 类别特征需区分有序(如等级)和无序(如颜色)。
- 避免“类别陷阱”(如One-Hot编码后最后一列冗余)。
- Scikit-learn函数:
LabelEncoder
:将标签编码为0,1,2,…。from sklearn.preprocessing import LabelEncoder encoder = LabelEncoder()
OneHotEncoder
:将无序分类特征转为二进制特征。from sklearn.preprocessing import OneHotEncoder encoder = OneHotEncoder(drop='first', sparse_output=False) # drop参数避免多重共线性
3. 特征转换
- 目标:缩放或变换特征分布(如标准化、归一化)。
- 注意事项:
- 标准化适合高斯分布数据,归一化适合非高斯分布或极端值。
- 需对训练集和测试集使用相同的转换参数(均值、方差)。
- Scikit-learn函数:
StandardScaler
:标准化(零均值,单位方差)。from sklearn.preprocessing import StandardScaler scaler = StandardScaler(with_mean=True, with_std=True)
MinMaxScaler
:归一化到[0,1]。from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler(feature_range=(0, 1))
4. 特征生成
- 目标:创建新特征(如多项式特征、交互项)。
- 注意事项:
- 过度生成可能导致维度爆炸,需结合模型复杂度。
- Scikit-learn函数:
PolynomialFeatures
:生成多项式特征。from sklearn.preprocessing import PolynomialFeatures poly = PolynomialFeatures(degree=2, include_bias=False) # degree为多项式阶数
5. 特征选择
- 目标:选择与目标变量相关性高的特征。
- 注意事项:
- 嵌入式方法(如Lasso回归)或包装法(如递归特征消除RFE)需结合模型。
- Scikit-learn函数:
SelectKBest
:基于统计检验选择前K个特征。from sklearn.feature_selection import SelectKBest, f_regression selector = SelectKBest(score_func=f_regression, k=3) # k为保留特征数
RFE
:递归特征消除。from sklearn.feature_selection import RFE from sklearn.linear_model import LinearRegression estimator = LinearRegression() selector = RFE(estimator, n_features_to_select=2)
6. 数据整合
- 目标:将不同预处理步骤组合为流水线(Pipeline)。
- 注意事项:
- 使用
ColumnTransformer
处理混合类型数据(数值+类别)。
- 使用
- Scikit-learn函数:
ColumnTransformer
:按列应用不同转换器。from sklearn.compose import ColumnTransformer numerical_cols = ['age', 'income'] categorical_cols = ['gender', 'education'] preprocessor = ColumnTransformer( transformers=[ ('num', StandardScaler(), numerical_cols), ('cat', OneHotEncoder(), categorical_cols) ])
完整实例:房价预测
import numpy as np
import pandas as pd
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.impute import SimpleImputer
from sklearn.ensemble import RandomForestRegressor
from sklearn.metrics import mean_squared_error
# 加载数据
data = fetch_california_housing(as_frame=True)
X = data.data
y = data.target
# 模拟缺失值(示例)
X['HouseAge'] = X['HouseAge'].mask(np.random.random(len(X)) < 0.1, np.nan)
# 分割数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义预处理流水线
numerical_cols = ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup']
categorical_cols = ['OceanProximity'] # 假设有一个分类特征
preprocessor = ColumnTransformer(
transformers=[
('num', Pipeline([
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
]), numerical_cols),
('cat', Pipeline([
('imputer', SimpleImputer(strategy='most_frequent')),
('encoder', OneHotEncoder(drop='if_binary'))
]), categorical_cols)
])
# 构建完整Pipeline(预处理 + 模型)
pipeline = Pipeline([
('preprocessor', preprocessor),
('regressor', RandomForestRegressor(n_estimators=100, random_state=42))
])
# 训练模型
pipeline.fit(X_train, y_train)
# 预测与评估
y_pred = pipeline.predict(X_test)
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse:.2f}")
关键注意事项
- Pipeline的重要性:将预处理步骤与模型训练组合为
Pipeline
,确保流程可重复且避免数据泄漏。 - 特征工程与模型选择:线性模型(如Logistic Regression)对特征缩放敏感,树模型(如Random Forest)则相对不敏感。
- 交叉验证:特征选择(如
SelectKBest
)应嵌入交叉验证中,避免过拟合。
通过以上流程,可以系统化地优化数据质量并提升模型性能。