特征工程
好特征胜过好模型。数据和特征决定了机器学习的上限。
flowchart LR A[原始数据] --> B[数据清洗] B --> C[特征缩放] C --> D[特征编码] D --> E[特征选择] E --> F[模型训练]import pandas as pdimport numpy as np
df = pd.DataFrame({ "age": [25, np.nan, 35, 28, np.nan], "salary": [50000, 60000, np.nan, 55000, 70000], "city": ["北京", "上海", None, "北京", "深圳"],})
print(df.isnull().sum()) # 查看缺失情况
# 数值列:填充均值/中位数df["age"] = df["age"].fillna(df["age"].mean())df["salary"] = df["salary"].fillna(df["salary"].median())
# 类别列:填充众数df["city"] = df["city"].fillna(df["city"].mode()[0])# IQR 方法Q1, Q3 = df["salary"].quantile(0.25), df["salary"].quantile(0.75)IQR = Q3 - Q1lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQRdf_clean = df[(df["salary"] >= lower) & (df["salary"] <= upper)]print(f"过滤掉 {len(df) - len(df_clean)} 个异常值")不同特征的范围差异巨大,必须缩放到同一尺度:
from sklearn.preprocessing import StandardScaler, MinMaxScaler
X = np.array([[25, 50000], [30, 80000], [35, 120000]])
# 标准化:均值 0,标准差 1(适合大多数场景)scaler = StandardScaler()X_std = scaler.fit_transform(X)print(f"标准化后均值: {X_std.mean(axis=0)}, 标准差: {X_std.std(axis=0)}")
# 归一化:缩放到 [0, 1](适合需要固定范围时)scaler = MinMaxScaler()X_norm = scaler.fit_transform(X)print(f"归一化后范围: [{X_norm.min():.1f}, {X_norm.max():.1f}]")| 方法 | 适用场景 |
|---|---|
| 标准化 | 大多数模型(线性回归、神经网络) |
| 归一化 | 需要固定范围(图像像素、KNN) |
# One-Hot Encoding:每个类别变一列df = pd.DataFrame({"city": ["北京", "上海", "深圳", "北京"]})df_encoded = pd.get_dummies(df, columns=["city"])print(df_encoded)from sklearn.feature_selection import SelectKBest, f_classif
# 生成 10 个特征,只有 3 个真正有用X, y = make_classification(n_samples=200, n_features=10, n_informative=3, random_state=42)
# 选最好的 5 个特征selector = SelectKBest(score_func=f_classif, k=5)X_selected = selector.fit_transform(X, y)
for i, score in enumerate(selector.scores_): print(f"特征 {i}: {score:.1f}")特征工程清单
Section titled “特征工程清单”- 缺失值处理了吗?
- 异常值过滤了吗?
- 特征缩放到同一尺度了吗?
- 类别变量编码了吗?
- 无关特征删除了吗?
- 模型评估 — 评估特征工程的效果