scikit-learn 是 Python 机器学习的基础库,API 设计统一,文档详尽,适合入门和快速原型开发。本文用一个完整的分类任务串起 sklearn 的核心工作流。
加载数据集
sklearn 内置了不少经典数据集,方便学习和实验:
from sklearn.datasets import load_iris, load_wine, load_digits
from sklearn.model_selection import train_test_split
# 加载 Iris 数据集
iris = load_iris()
X, y = iris.data, iris.target
print(f"特征形状: {X.shape}") # (150, 4)
print(f"类别: {iris.target_names}") # ['setosa' 'versicolor' 'virginica']
print(f"特征名: {iris.feature_names}")
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
print(f"训练集: {X_train.shape[0]}, 测试集: {X_test.shape[0]}")
stratify=y 确保训练集和测试集中各类别比例与原始数据一致。
数据预处理
大多数算法对特征的尺度敏感,标准化是必要步骤:
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train) # 在训练集上 fit
X_test_scaled = scaler.transform(X_test) # 在测试集上只 transform
重要原则:fit 只能在训练集上做。如果在全量数据上 fit 再 split,就会把测试集的信息泄漏到预处理步骤中(data leakage)。
其他常用预处理:
MinMaxScaler:缩放到 [0, 1]LabelEncoder:标签编码OneHotEncoder:独热编码
分类模型
sklearn 所有模型都遵循统一的 API:fit() 训练,predict() 预测,score() 评估。
决策树
from sklearn.tree import DecisionTreeClassifier
dt = DecisionTreeClassifier(max_depth=3, random_state=42)
dt.fit(X_train_scaled, y_train)
y_pred = dt.predict(X_test_scaled)
print(f"决策树准确率: {dt.score(X_test_scaled, y_test):.4f}")
决策树容易过拟合,通过 max_depth、min_samples_split 等参数控制复杂度。
随机森林
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_estimators=100, max_depth=5, random_state=42)
rf.fit(X_train_scaled, y_train)
print(f"随机森林准确率: {rf.score(X_test_scaled, y_test):.4f}")
# 特征重要性
import numpy as np
importances = rf.feature_importances_
indices = np.argsort(importances)[::-1]
for i in range(X.shape[1]):
print(f" {iris.feature_names[indices[i]]}: {importances[indices[i]]:.4f}")
随机森林是多棵决策树的集成,通过 bagging 和特征随机选择来降低过拟合。实际项目中它是一个很强的 baseline。
模型评估
准确率只是最基本的指标,还需要更细致的分析:
from sklearn.metrics import (
accuracy_score, classification_report, confusion_matrix
)
y_pred = rf.predict(X_test_scaled)
# 准确率
print(f"Accuracy: {accuracy_score(y_test, y_pred):.4f}")
# 详细报告:每个类别的 precision / recall / f1
print(classification_report(y_test, y_pred, target_names=iris.target_names))
# 混淆矩阵
cm = confusion_matrix(y_test, y_pred)
print("Confusion Matrix:")
print(cm)
混淆矩阵的对角线是预测正确的数量,非对角线是错误的。通过它可以看出模型在哪些类别上容易混淆。
可视化混淆矩阵
import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay
fig, ax = plt.subplots(figsize=(6, 5))
ConfusionMatrixDisplay.from_predictions(
y_test, y_pred,
display_labels=iris.target_names,
cmap='Blues',
ax=ax
)
plt.title('Confusion Matrix')
plt.tight_layout()
plt.savefig('confusion_matrix.png', dpi=100)
plt.close()
交叉验证
单次 train/test split 的结果可能有偏差,交叉验证更可靠:
from sklearn.model_selection import cross_val_score
# 5 折交叉验证
scores = cross_val_score(rf, X, y, cv=5, scoring='accuracy')
print(f"5-Fold CV accuracy: {scores.mean():.4f} (+/- {scores.std():.4f})")
print(f"每折结果: {scores}")
交叉验证将数据分成 k 份,每次用 k-1 份训练、1 份验证,循环 k 次。最终结果是 k 次的平均值,比单次划分更稳定。
用 Pipeline 避免数据泄漏
交叉验证中预处理和模型应该打包在一起,确保 scaler 只在训练折上 fit:
from sklearn.pipeline import Pipeline
pipeline = Pipeline([
('scaler', StandardScaler()),
('clf', RandomForestClassifier(n_estimators=100, random_state=42))
])
scores = cross_val_score(pipeline, X, y, cv=5, scoring='accuracy')
print(f"Pipeline CV accuracy: {scores.mean():.4f} (+/- {scores.std():.4f})")
Pipeline 是 sklearn 中非常推荐的用法——它把预处理和模型封装成一个整体,调用 fit / predict 时自动按步骤执行,杜绝了手动处理时可能出现的数据泄漏。
小结
sklearn 的核心工作流就是:加载数据 -> 预处理 -> 选模型 -> fit/predict -> 评估 -> 交叉验证。统一的 API 设计让切换不同算法几乎只需要换一行代码。下一步可以探索 GridSearchCV 做超参数调优,或者尝试更多模型(SVM、KNN、XGBoost 等)。