[机器学习]sklearn.preprocessing

438 阅读3分钟

在Scikit-learn中,preprocessing模块是数据预处理的核心工具,用于将原始数据转换为适合机器学习模型的形式。

下面我详细介绍它的作用、常用功能和具体使用方法。

一、主要作用

1. 特征缩放(Feature Scaling)

  • 消除特征间的量纲差异
  • 提高模型收敛速度和性能
  • 对距离敏感的算法(如SVM、KNN、神经网络)尤为重要

2. 处理分类特征

  • 将文本/类别转换为数值
  • 多种编码方式应对不同场景

3. 其他预处理

  • 生成多项式特征
  • 离散化连续特征
  • 处理异常值

二、常用功能及代码示例

1. 标准化(StandardScaler)

from sklearn.preprocessing import StandardScaler
import numpy as np

# 创建数据
X = np.array([[1, 2], [3, 4], [5, 6]])

# 标准化:均值为0,方差为1
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

print("原始数据均值:", scaler.mean_)
print("缩放后数据:\n", X_scaled)

2. 归一化(MinMaxScaler)

from sklearn.preprocessing import MinMaxScaler

# 归一化到[0,1]区间
scaler = MinMaxScaler()
X_normalized = scaler.fit_transform(X)

# 或指定范围
scaler = MinMaxScaler(feature_range=(-1, 1))

3. 鲁棒缩放(RobustScaler)

适用于有异常值的数据:

from sklearn.preprocessing import RobustScaler

scaler = RobustScaler()
X_robust = scaler.fit_transform(X)

4. 分类特征编码

One-Hot编码

from sklearn.preprocessing import OneHotEncoder
import pandas as pd

data = pd.DataFrame({'color': ['红', '蓝', '绿', '蓝', '红']})

encoder = OneHotEncoder(sparse_output=False)
encoded = encoder.fit_transform(data[['color']])
print(encoded)

标签编码(用于有序分类):

from sklearn.preprocessing import LabelEncoder

le = LabelEncoder()
labels = ['低', '中', '高', '中', '低']
encoded_labels = le.fit_transform(labels)
print(encoded_labels)  # [0 1 2 1 0]

5. 多项式特征生成

from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly.fit_transform(X)
print(f"原始特征数: {X.shape[1]}, 多项式后: {X_poly.shape[1]}")

三、实际应用示例

完整的数据预处理流程:

from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.impute import SimpleImputer

# 示例数据
import pandas as pd
data = pd.DataFrame({
    'age': [25, 30, 35, None, 40],
    'salary': [50000, 60000, None, 70000, 80000],
    'city': ['北京', '上海', '北京', '广州', '上海']
})

# 定义数值和分类列
numeric_features = ['age', 'salary']
categorical_features = ['city']

# 创建预处理管道
numeric_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='median')),
    ('scaler', StandardScaler())
])

categorical_transformer = Pipeline(steps=[
    ('imputer', SimpleImputer(strategy='constant', fill_value='missing')),
    ('onehot', OneHotEncoder(handle_unknown='ignore'))
])

preprocessor = ColumnTransformer(
    transformers=[
        ('num', numeric_transformer, numeric_features),
        ('cat', categorical_transformer, categorical_features)
    ])

# 应用预处理
processed_data = preprocessor.fit_transform(data)
print("处理后数据维度:", processed_data.shape)

四、重要注意事项

  1. 避免数据泄露
# 正确做法:只在训练集上fit
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)  # 使用训练集的参数
  1. 选择适当的缩放方法

    • 正态分布数据 → StandardScaler
    • 有异常值的数据 → RobustScaler
    • 图像/需要固定范围的数据 → MinMaxScaler
  2. 管道(Pipeline)使用

from sklearn.pipeline import make_pipeline
from sklearn.svm import SVC

pipeline = make_pipeline(
    StandardScaler(),
    SVC(kernel='rbf')
)

五、总结

sklearn.preprocessing模块是机器学习工作流中不可或缺的部分。正确的预处理通常比选择复杂模型更重要。建议:

  1. 先进行探索性数据分析(EDA)了解数据分布
  2. 根据数据特性和模型需求选择预处理方法
  3. 使用Pipeline确保预处理的一致性
  4. 始终分开训练集和测试集的预处理

预处理对模型性能有显著影响,花时间做好预处理是提升模型效果最有效的方式之一。