Scikit-learn 中文教程

第二部分:Scikit-learn 核心基础
第 3 章 Scikit-learn 核心设计与 API 体系
第 4 章 数据集模块与数据划分
第三部分:数据预处理与特征工程
第 5 章 数据预处理核心模块(sklearn.preprocessing)
第 6 章 特征工程:提取、选择与构建
第四部分:模型评估与验证
第 7 章 模型评估指标(按任务类型划分)
第 8 章 模型验证与超参数调优
第五部分:Scikit-learn 核心算法模块
第 9 章 有监督学习:分类算法
第 10 章 有监督学习:回归算法
第 11 章 无监督学习:聚类与密度算法
第 12 章 半监督学习与其他常用算法
第八部分:性能优化与问题解决
第 18 章 Scikit-learn 性能优化
第 19 章 Scikit-learn 常见问题与解决方案

19.1 数据处理类问题

Scikit-learn教程:数据处理类问题——数据泄露、类别不平衡与特征维度灾难

Scikit-learn 中文教程

本章节深入讲解Scikit-learn中数据处理类常见问题,包括数据泄露的Pipeline和交叉验证解决方案、类别不平衡的分层抽样和加权损失处理方法,以及特征维度灾难的特征选择和降维技巧,适合机器学习新手学习。

推荐工具
PyCharm专业版开发必备

功能强大的Python IDE,提供智能代码补全、代码分析、调试和测试工具,提高Python开发效率。特别适合处理列表等数据结构的开发工作。

了解更多

数据处理类问题:预防常见陷阱

在机器学习项目中,数据处理是关键步骤,但容易遇到各种问题。本章节将介绍三种常见的数据处理类问题:数据泄露、类别不平衡和特征维度灾难,并提供简单易懂的解决方案,使用Scikit-learn工具实现。

1. 数据泄露

原因

数据泄露是指在模型训练过程中,测试集数据或信息意外地参与到预处理或调优阶段,导致模型在测试集上表现过好,但在新数据上泛化能力差。常见原因包括:

  • 对整体数据(包括测试集)进行归一化或标准化。
  • 使用测试集信息选择特征或调整超参数。

解决方案:Pipeline + 交叉验证

为了避免数据泄露,可以使用Scikit-learn的Pipeline工具将预处理步骤和模型训练封装在一起,确保预处理只基于训练集进行。结合交叉验证,可以进一步评估模型性能,防止过拟合。

示例代码:使用Pipeline和交叉验证处理数据。

from sklearn.pipeline import Pipeline
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
from sklearn.datasets import make_classification

# 生成示例数据
X, y = make_classification(n_samples=100, n_features=20, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建Pipeline:先标准化,再训练SVM模型
pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('svm', SVC(kernel='linear'))
])

# 使用交叉验证评估模型
scores = cross_val_score(pipeline, X_train, y_train, cv=5)
print(f"交叉验证得分: {scores.mean():.2f} (+/- {scores.std():.2f})")

# 在测试集上评估
pipeline.fit(X_train, y_train)
test_score = pipeline.score(X_test, y_test)
print(f"测试集准确率: {test_score:.2f}")

2. 类别不平衡

原因

类别不平衡是指训练数据中不同类别的样本数量差异很大,例如正样本远少于负样本。这会导致模型偏向多数类,忽略少数类,影响预测性能。常见于欺诈检测、医疗诊断等场景。

解决方案:分层抽样、重采样、加权损失

Scikit-learn提供了多种方法来处理类别不平衡问题。

  • 分层抽样:在交叉验证或训练集划分时保持类别比例,避免数据偏差。
  • 重采样:通过过采样(如SMOTE)或欠采样(如随机欠采样)调整样本分布。
  • 加权损失:在模型中设置class_weight参数,为少数类分配更高权重。

示例代码:使用重采样和加权损失处理类别不平衡。

from sklearn.utils import resample
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.metrics import classification_report

# 生成不平衡数据
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=2, 
                           n_clusters_per_class=1, weights=[0.9, 0.1], random_state=42)

# 方法1:重采样(过采样少数类)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# 分离多数类和少数类
X_majority = X_train[y_train == 0]
X_minority = X_train[y_train == 1]
y_majority = y_train[y_train == 0]
y_minority = y_train[y_train == 1]

# 过采样少数类
X_minority_upsampled, y_minority_upsampled = resample(X_minority, y_minority, 
                                                       n_samples=len(X_majority), random_state=42)
# 合并数据
X_train_balanced = np.vstack((X_majority, X_minority_upsampled))
y_train_balanced = np.hstack((y_majority, y_minority_upsampled))

# 训练模型
model1 = LogisticRegression()
model1.fit(X_train_balanced, y_train_balanced)
predictions1 = model1.predict(X_test)
print("重采样后模型报告:")
print(classification_report(y_test, predictions1))

# 方法2:加权损失
model2 = LogisticRegression(class_weight='balanced')  # 自动加权
model2.fit(X_train, y_train)
predictions2 = model2.predict(X_test)
print("加权损失模型报告:")
print(classification_report(y_test, predictions2))

3. 特征维度灾难

原因

特征维度灾难指的是特征数量过多,导致模型复杂度增加、计算成本高、容易过拟合,甚至可能因噪声特征降低性能。这在高维数据(如图像或文本)中常见。

解决方案:特征选择、降维

Scikit-learn提供了多种特征处理和降维工具来应对这一问题。

  • 特征选择:通过统计方法(如SelectKBest)选择最相关特征,减少冗余。
  • 降维:使用PCA等算法将高维数据映射到低维空间,保留主要信息。

示例代码:使用特征选择和降维处理高维数据。

from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.metrics import accuracy_score

# 生成高维数据
X, y = make_classification(n_samples=200, n_features=50, n_informative=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 方法1:特征选择(选择前10个特征)
selector = SelectKBest(score_func=f_classif, k=10)
X_train_selected = selector.fit_transform(X_train, y_train)
X_test_selected = selector.transform(X_test)

model1 = RandomForestClassifier(random_state=42)
model1.fit(X_train_selected, y_train)
predictions1 = model1.predict(X_test_selected)
accuracy1 = accuracy_score(y_test, predictions1)
print(f"特征选择后准确率: {accuracy1:.2f}")

# 方法2:降维(使用PCA降至5维)
pca = PCA(n_components=5)
X_train_pca = pca.fit_transform(X_train)
X_test_pca = pca.transform(X_test)

model2 = RandomForestClassifier(random_state=42)
model2.fit(X_train_pca, y_train)
predictions2 = model2.predict(X_test_pca)
accuracy2 = accuracy_score(y_test, predictions2)
print(f"降维后准确率: {accuracy2:.2f}")

总结

本章节介绍了Scikit-learn中数据处理类的三个常见问题:数据泄露、类别不平衡和特征维度灾难。通过使用Pipeline和交叉验证、分层抽样和重采样、以及特征选择和降维等方法,可以有效预防这些陷阱,提升模型性能和泛化能力。对于机器学习新手,建议在实际项目中应用这些技巧,并结合Scikit-learn文档深入学习。

开发工具推荐
Python开发者工具包

包含虚拟环境管理、代码格式化、依赖管理、测试框架等Python开发全流程工具,提高开发效率。特别适合处理复杂数据结构和算法。

获取工具包