当前位置: 首页 > news >正文

详解 scikit-learn 数据预处理工具:从理论到实践

在机器学习工作流程中,数据预处理是连接原始数据与模型训练的关键桥梁。高质量的预处理能够显著提升模型性能,而 scikit-learn 库提供了一套全面且高效的预处理工具集,帮助开发者轻松应对各种数据转换需求。本文将系统介绍 scikit-learn 中 17 种常用预处理工具的原理与实践应用,通过实例代码展示其具体用法。

数据预处理的重要性

现实世界中的原始数据往往存在各种 "缺陷":数值特征量纲不一、类别特征非数值化、存在缺失值、特征分布不符合模型假设等。这些问题会导致模型收敛困难、预测偏差甚至失效。数据预处理通过标准化、编码、转换等操作,将原始数据转化为适合模型处理的形式,主要体现在以下几个方面:

  • 消除量纲影响,使不同特征具有可比性
  • 将非数值信息转化为模型可理解的数值形式
  • 处理缺失值,提高数据完整性
  • 优化特征分布,适应模型假设
  • 创造新特征,增强数据表达能力

实验数据准备

为全面展示各类预处理工具的效果,我们构造了包含多种数据类型的异构数据集:

import numpy as np
import pandas as pddata = {'num': [10, 20, 30],  # 整数特征'cat': ['low', 'medium', 'high'],  # 类别特征'int': [2, 5, 8],  # 整数特征'float': [0.5, 0.8, 1.2],  # 浮点特征'multi_label': [['red', 'blue'], ['blue'], ['green']],  # 多标签特征'missing': [3, 5, None]  # 含缺失值特征
}
df = pd.DataFrame(data)

数值特征预处理工具

数值特征是机器学习中最常见的数据类型,scikit-learn 提供了多种工具用于数值特征的标准化、缩放和转换。

1. preprocessing.scale()

scale()函数用于对数据进行标准化处理,将特征转换为均值为 0、标准差为 1 的分布,计算公式为:
(x - mean(x)) / std(x)

from sklearn.preprocessing import scale
scaled_data = scale(df[['num', 'int', 'float']])

该函数直接返回标准化后的数组,适用于快速预处理,但不支持后续对新数据的转换(无transform方法)。

2. MinMaxScaler

MinMaxScaler 将特征缩放到指定范围(默认 [0,1]),计算公式为:
(x - min(x)) / (max(x) - min(x))

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
minmax_data = scaler.fit_transform(df[['num', 'int', 'float']])

这种缩放方式对异常值敏感,适用于已知数据边界的场景,如像素值(0-255)处理。

3. StandardScaler

StandardScaler 与scale()功能类似,都是进行标准化处理,但提供了完整的fit-transform接口,便于管道化操作和新数据处理:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
std_scaled = scaler.fit_transform(df[['num', 'int', 'float']])

标准化后的数据均值为 0,标准差为 1,使不同量纲的特征具有可比性,是最常用的缩放方法之一。

4. MaxAbsScaler

MaxAbsScaler 通过特征的最大绝对值进行缩放,计算公式为:x / max(abs(x))

from sklearn.preprocessing import MaxAbsScaler
scaler = MaxAbsScaler()
maxabs_data = scaler.fit_transform(df[['num', 'int', 'float']])

缩放后的数据范围在 [-1, 1] 之间,适用于稀疏数据,因为它不会改变数据的稀疏结构。

5. RobustScaler

RobustScaler 对异常值具有较强的鲁棒性,使用中位数和四分位距进行缩放:
(x - median) / (Q3 - Q1)

from sklearn.preprocessing import RobustScaler
scaler = RobustScaler()
robust_data = scaler.fit_transform(df[['num', 'int', 'float']])

当数据中存在异常值时,RobustScaler 比 StandardScaler 表现更好,常见于金融、风控等领域。

6. QuantileTransformer

QuantileTransformer 通过将数据映射到均匀分布或正态分布来转换特征,能够有效处理偏态分布数据:

from sklearn.preprocessing import QuantileTransformer
scaler = QuantileTransformer()
quantile_data = scaler.fit_transform(df[['num', 'int', 'float']])

这种方法对异常值不敏感,适用于需要将数据转换为特定分布的场景,如 Gaussian 过程模型。

7. PowerTransformer

PowerTransformer 应用幂变换使数据更接近正态分布,支持 Box-Cox 和 Yeo-Johnson 两种变换:

from sklearn.preprocessing import PowerTransformer
scaler = PowerTransformer()
power_data = scaler.fit_transform(df[['num', 'int', 'float']])

幂变换特别适用于处理偏态分布的数据,如收入、房价等具有长尾分布特征的数据。

8. Normalizer

Normalizer 对样本进行归一化,使每个样本的 L1 或 L2 范数为 1,计算公式为:

  • L1 范数:x / sum(abs(x))
  • L2 范数:x / sqrt(sum(x^2))
    from sklearn.preprocessing import Normalizer
    scaler = Normalizer(norm='l2')
    normalized_data = scaler.fit_transform(df[['num', 'int', 'float']])

    归一化适用于需要关注样本向量方向而非大小的场景,如文本分类(词袋模型)、推荐系统等。

    类别特征编码工具

    机器学习模型通常要求输入为数值形式,因此需要将类别特征转换为数值表示,scikit-learn 提供了多种类别编码工具。

    9. OrdinalEncoder

    OrdinalEncoder 将类别特征转换为有序整数,适用于具有内在顺序的类别特征(序数特征):

    from sklearn.preprocessing import OrdinalEncoder
    encoder = OrdinalEncoder(categories=[['low', 'medium', 'high']])
    df['cat_encoded'] = encoder.fit_transform(df[['cat']])

    使用时需注意指定categories参数以确保正确的顺序映射,如本例中将 'low'→0,'medium'→1,'high'→2。

    10. LabelEncoder

    LabelEncoder 与 OrdinalEncoder 功能类似,但适用于目标变量(y)的编码:

    from sklearn.preprocessing import LabelEncoder
    encoder = LabelEncoder()
    df['cat_label_encoded'] = encoder.fit_transform(df['cat'])

    注意:不推荐使用 LabelEncoder 对特征进行编码,尤其是无序类别特征,可能会引入错误的顺序关系。

    11. MultiLabelBinarizer

    MultiLabelBinarizer 用于处理多标签特征,将每个样本的多个标签转换为二进制指示向量:

    from sklearn.preprocessing import MultiLabelBinarizer
    mlb = MultiLabelBinarizer(classes=['red', 'blue', 'green'])
    multi_label_df = pd.DataFrame(mlb.fit_transform(df['multi_label']),columns=mlb.classes_,index=df.index
    )
    df = pd.concat([df, multi_label_df], axis=1)

    这种编码方式适用于一个样本可能属于多个类别的场景,如文本的多主题分类。

    12. OneHotEncoder

    OneHotEncoder 将无序类别特征转换为独热编码(one-hot encoding),每个类别生成一个二进制特征:

    from sklearn.preprocessing import OneHotEncoder
    encoder = OneHotEncoder(sparse=False)
    onehot_data = encoder.fit_transform(df[['cat']])
    onehot_df = pd.DataFrame(onehot_data, columns=encoder.get_feature_names_out(['cat']))

    独热编码避免了为无序类别引入虚假顺序关系的问题,但会增加特征维度(维度灾难),适用于类别数量较少的场景。

    其他预处理工具

    除了上述主要用于数值和类别特征的工具外,scikit-learn 还提供了一些处理特殊需求的预处理工具。

    13. KBinsDiscretizer

    KBinsDiscretizer 将连续特征离散化为有限数量的区间( bins ):

    from sklearn.preprocessing import KBinsDiscretizer
    discretizer = KBinsDiscretizer(n_bins=3, encode='ordinal')
    binned_data = discretizer.fit_transform(df[['num']])
    df['binned'] = binned_data

    离散化可以捕捉特征的非线性关系,降低模型对异常值的敏感度,常见于决策树类模型的预处理。

    14. FunctionTransformer

    FunctionTransformer 允许用户自定义转换函数,灵活处理各种特殊转换需求:

    from sklearn.preprocessing import FunctionTransformer
    def custom_func(x):return x + 1
    transformer = FunctionTransformer(custom_func)
    custom_data = transformer.transform(df[['num', 'int']])

    这种方式扩展性强,可用于实现对数转换、指数转换、倒数转换等任意自定义操作。

    15. Binarizer

    Binarizer 根据阈值将连续特征转换为二进制特征(0 或 1):

    from sklearn.preprocessing import Binarizer
    binarizer = Binarizer(threshold=20)
    df['num_binarized'] = binarizer.fit_transform(df[['num']])

    二值化适用于需要将特征简化为 "是 / 否" 或 "有 / 无" 的场景,如将收入划分为高 / 低两个等级。

    16. PolynomialFeatures

    PolynomialFeatures 用于生成多项式特征和交互特征,增强模型对非线性关系的捕捉能力:

    from sklearn.preprocessing import PolynomialFeatures
    poly = PolynomialFeatures(degree=2, include_bias=False)
    poly_features = poly.fit_transform(df[['num', 'int']])
    poly_df = pd.DataFrame(poly_features, columns=poly.get_feature_names_out(['num', 'int']))

    对于 degree=2,会生成原始特征(num, int)、平方特征(num², int²)和交互特征(num×int),适用于线性模型处理非线性问题。

    17. SimpleImputer(缺失值处理)

    SimpleImputer 用于处理缺失值,支持多种填充策略(均值、中位数、众数等):

    from sklearn.impute import SimpleImputer
    imputer_new = SimpleImputer(strategy='mean')
    df['missing_imputed'] = imputer_new.fit_transform(df[['missing']])

    缺失值处理是数据预处理的重要步骤,合理的填充策略能够减少信息损失,常见的填充策略包括统计量填充、模型预测填充等。

    预处理工具选择指南

    面对众多预处理工具,如何选择合适的工具是实际应用中的关键问题,以下是一些选择建议:

  • 数值缩放:优先考虑 StandardScaler;数据含异常值时用 RobustScaler;需要固定范围时用 MinMaxScaler
  • 类别编码:有序类别用 OrdinalEncoder;无序类别用 OneHotEncoder;多标签用 MultiLabelBinarizer
  • 分布转换:偏态分布用 PowerTransformer;需要特定分布用 QuantileTransformer
  •  

    实际应用中,预处理通常不是单一操作,而是多种工具的组合,scikit-learn 的 Pipeline 工具可以将多个预处理步骤和模型训练整合为一个流程,提高代码的可维护性和可复现性。

  • 特征创建:需要非线性特征用 PolynomialFeatures;自定义转换用 FunctionTransformer
  • 缺失值:根据数据类型选择合适的填充策略,数值型常用均值 / 中位数,类别型常用众数
http://www.dtcms.com/a/340303.html

相关文章:

  • 5.4 4pnpm 使用介绍
  • 给你的Unity编辑器添加实现类似 Odin 的 条件显示字段 (ShowIf/HideIf) 功能
  • Scikit-learn 预处理函数分类详解
  • pnpm : 无法加载文件 C:\Program Files\nodejs\pnpm.ps1,因为在此系统上禁止运行脚本。
  • 在 React 中,​父子组件之间的通信(传参和传方法)
  • scikit-learn/sklearn学习|变量去中心化和标准化
  • 2.3 Flink的核心概念解析
  • 详解flink java table api基础(三)
  • Flink Stream API - 顶层Operator接口StreamOperator源码超详细讲解
  • OSPF 典型组网
  • CISP-PTE之路--10文
  • 公有地址和私有地址
  • 【GPT入门】第51课 将hf模型转换为GGUF
  • 深入(流批【牛批】框架)Flink的机制
  • 【Java后端】Spring Boot 全局异常处理最佳实践
  • ssl代理
  • 一会儿能ping通一会ping不通解决方案
  • JavaScript手录18-ajax:异步请求与项目上线部署
  • AI 自动化编程 trae 体验 页面添加富编辑器
  • (5)软件包管理器 yum | Vim 编辑器 | Vim 文本批量化操作 | 配置 Vim
  • 深度解析:RESTful API中的404错误 - 不是所有404都是Bug
  • Vue 3项目中的路由管理和状态管理系统
  • 【Day 31】Linux-LNMP
  • MySQL基础操作
  • SpringBoot + MyBatis-Plus 使用 listObjs 报 ClassCastException 的原因与解决办法
  • Rabbit 实战指南-学习笔记
  • HTML+CSS:浮动详解
  • 3D文档控件Aspose.3D实用教程:使用 C# 构建 OBJ 到 U3D 转换器
  • awk 基础用法示例
  • 测试DuckDB插件对不同格式xlsx文件的读写效率