Skip to content

特征工程

好特征胜过好模型。数据和特征决定了机器学习的上限。

flowchart LR
A[原始数据] --> B[数据清洗]
B --> C[特征缩放]
C --> D[特征编码]
D --> E[特征选择]
E --> F[模型训练]
import pandas as pd
import 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 - Q1
lower, upper = Q1 - 1.5 * IQR, Q3 + 1.5 * IQR
df_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}")
  • 缺失值处理了吗?
  • 异常值过滤了吗?
  • 特征缩放到同一尺度了吗?
  • 类别变量编码了吗?
  • 无关特征删除了吗?