Sklearn 数据预处理

数据预处理是 Scikit-learn(sklearn)机器学习工作流中的关键步骤,用于清洗、转换和准备数据,以提高模型性能。以下是 Scikit-learn 中数据预处理的常用方法和工具,涵盖核心概念和代码示例,力求简洁明了。


1. 数据预处理的重要性

  • 提高模型性能:标准化、归一化等操作使特征尺度一致,优化模型收敛。
  • 处理数据问题:解决缺失值、异常值、分类变量等问题。
  • 特征工程:通过特征选择或降维减少噪声,提高效率。

Scikit-learn 的预处理工具位于 sklearn.preprocessing 模块,遵循统一的 fit()transform() 接口。


2. 常见数据预处理方法

2.1 标准化(Standardization)

将特征缩放到均值为 0、标准差为 1,适合假设数据服从正态分布的模型(如线性回归、SVM)。

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)  # 拟合并转换训练数据
X_test_scaled = scaler.transform(X_test)  # 仅转换测试数据

2.2 归一化(Normalization)

将特征缩放到指定范围(如 [0, 1]),适合需要固定范围的算法(如神经网络)。

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0, 1))
X_normalized = scaler.fit_transform(X)

2.3 处理缺失值(Imputation)

用均值、中位数或指定值填充缺失值。

from sklearn.impute import SimpleImputer
import numpy as np
X = np.array([[1, 2, np.nan], [3, np.nan, 5], [np.nan, 4, 6]])
imputer = SimpleImputer(strategy='mean')  # 用均值填充
X_imputed = imputer.fit_transform(X)
print(X_imputed)
# 输出示例:
# [[1.  2.  5.5]
#  [3.  3.  5. ]
#  [2.  4.  6. ]]

2.4 编码分类变量

  • LabelEncoder:将分类标签转为数值(用于目标变量 y)。
  from sklearn.preprocessing import LabelEncoder
  y = ['cat', 'dog', 'cat', 'bird']
  encoder = LabelEncoder()
  y_encoded = encoder.fit_transform(y)  # 输出: [1, 2, 1, 0]
  • OneHotEncoder:将分类特征转为独热编码(用于特征矩阵 X)。
  from sklearn.preprocessing import OneHotEncoder
  X = [['red'], ['blue'], ['green']]
  encoder = OneHotEncoder(sparse_output=False)
  X_encoded = encoder.fit_transform(X)
  print(X_encoded)
  # 输出示例:
  # [[0. 0. 1.]
  #  [1. 0. 0.]
  #  [0. 1. 0.]]

2.5 特征二值化(Binarization)

将数值特征转为 0/1,基于指定阈值。

from sklearn.preprocessing import Binarizer
X = [[1, 2, 3], [4, 0, 6]]
binarizer = Binarizer(threshold=2)
X_binarized = binarizer.transform(X)
print(X_binarized)  # >2 转为 1,否则为 0
# 输出: [[0 0 1]
#        [1 0 1]]

2.6 多项式特征(Polynomial Features)

生成特征的多项式组合,增加非线性关系。

from sklearn.preprocessing import PolynomialFeatures
X = [[1, 2], [3, 4]]
poly = PolynomialFeatures(degree=2)
X_poly = poly.fit_transform(X)
print(X_poly)  # 包含原始特征、平方、交叉项
# 输出: [[1. 1. 2. 1. 2. 4.]
#        [1. 3. 4. 9. 12. 16.]]

2.7 离散化(Discretization)

将连续特征分箱为离散值。

from sklearn.preprocessing import KBinsDiscretizer
X = [[1], [2], [3], [4]]
discretizer = KBinsDiscretizer(n_bins=3, encode='ordinal', strategy='uniform')
X_binned = discretizer.fit_transform(X)
print(X_binned)
# 输出示例: [[0.]
#             [1.]
#             [2.]
#             [2.]]

3. 特征选择

减少无关或冗余特征,提高模型效率。

  • SelectKBest:选择得分最高的 k 个特征。
  from sklearn.feature_selection import SelectKBest, f_classif
  selector = SelectKBest(score_func=f_classif, k=2)
  X_selected = selector.fit_transform(X, y)
  • VarianceThreshold:移除方差低于阈值的特征。
  from sklearn.feature_selection import VarianceThreshold
  selector = VarianceThreshold(threshold=0.1)
  X_filtered = selector.fit_transform(X)

4. 降维

通过降维减少特征数量,保留主要信息。

  • 主成分分析(PCA)
  from sklearn.decomposition import PCA
  pca = PCA(n_components=2)
  X_pca = pca.fit_transform(X)
  print(pca.explained_variance_ratio_)  # 每个主成分的方差解释比例

5. 使用 Pipeline 整合预处理

Pipeline 将预处理和模型训练步骤组合,避免数据泄漏。

from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('imputer', SimpleImputer(strategy='mean')),
    ('classifier', LogisticRegression())
])
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)

6. 完整示例(基于鸢尾花数据集)

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
import numpy as np

# 加载数据
iris = load_iris()
X, y = iris.data, iris.target

# 模拟缺失值
X[np.random.randint(0, 150, 10), np.random.randint(0, 4, 10)] = np.nan

# 拆分数据
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建 Pipeline
pipeline = Pipeline([
    ('imputer', SimpleImputer(strategy='mean')),
    ('scaler', StandardScaler()),
    ('classifier', LogisticRegression(random_state=42))
])

# 训练和预测
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print(f"Accuracy: {accuracy_score(y_test, y_pred):.2f}")

7. 注意事项

  • 训练/测试数据分离:对训练数据调用 fit_transform(),对测试数据仅调用 transform(),避免数据泄漏。
  • 选择合适的预处理:根据数据分布和模型需求选择标准化或归一化。
  • 处理分类变量:独热编码会增加特征维度,注意计算成本。
  • 缺失值策略:根据数据场景选择均值、中位数或常量填充。
  • 可解释性:降维和特征选择可能降低模型的可解释性,需权衡。

8. 资源

  • 官方文档:https://scikit-learn.org/stable/modules/preprocessing.html
  • 示例代码:https://scikit-learn.org/stable/auto_examples/preprocessing/index.html
  • 社区:在 X 平台搜索 #scikit-learn 获取最新讨论。

如果需要深入某个预处理方法(如 PCA 的数学原理或处理特定数据集的技巧),请告诉我,我可以提供更详细的代码或解释!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注