scikit-learn (sklearn)

1. 定义

scikit-learn(导入名 sklearn)是 Python 最主流的传统机器学习库,提供分类、回归、聚类、降维、预处理、模型评估等一整套工具,API 高度统一。建在 NumPy / SciPy 之上。

定位区分:sklearn 管传统机器学习(线性回归、决策树、SVM、随机森林、KMeans 等);深度学习(神经网络)是 PyTorch / TensorFlow 的地盘。数据量不大、要快速出基线模型时,sklearn 是首选。

2. 核心设计:统一的 Estimator API

sklearn 最大的优点是所有模型接口一致,学会一个就会全部:

方法作用用在
.fit(X, y)训练(从数据学习)所有模型
.predict(X)预测分类/回归
.transform(X)变换数据预处理/降维
.fit_transform(X)训练 + 变换(合并)预处理常用
.score(X, y)评估(准确率/R² 等)所有模型

记住这套方法,换任何模型(换成 RandomForestClassifierSVC…)用法都一样,只改一行导入 + 实例化。

3. 数据约定

  • X:特征矩阵,形状 (n_samples, n_features) —— 每行一个样本,每列一个特征
  • y:标签/目标,形状 (n_samples,)
# X 必须是二维!单特征也要 reshape(-1, 1)
X = [[1], [2], [3]]      # 3 个样本,1 个特征
y = [2, 4, 6]            # 对应标签

4. 典型工作流(记住这个骨架)

from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
 
# 1. 切分训练/测试集
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42
)
 
# 2. 预处理(标准化)—— 只在训练集 fit,测试集只 transform!
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)      # 注意:用训练集学到的均值/方差
 
# 3. 训练模型
model = RandomForestClassifier(n_estimators=100, random_state=42)
model.fit(X_train, y_train)
 
# 4. 预测 + 评估
y_pred = model.predict(X_test)
print(accuracy_score(y_test, y_pred))

⚠️ 铁律:预处理只能在训练集上 fit,测试集只 transform。在全量数据上 fit 会导致”数据泄露 (data leakage)“,评估结果虚高。

5. 常用模块速览

模块用途常用类/函数
sklearn.linear_model线性模型LinearRegressionLogisticRegression
sklearn.tree决策树DecisionTreeClassifier
sklearn.ensemble集成方法RandomForestClassifierGradientBoosting
sklearn.svm支持向量机SVCSVR
sklearn.cluster聚类KMeansDBSCAN
sklearn.decomposition降维PCA
sklearn.preprocessing预处理StandardScalerMinMaxScalerOneHotEncoder
sklearn.model_selection切分/调参train_test_splitcross_val_scoreGridSearchCV
sklearn.metrics评估指标accuracy_scoref1_scoreconfusion_matrixmean_squared_error
sklearn.pipeline流水线Pipelinemake_pipeline

5.5 两个常用起手函数:fetch_openmltrain_test_split

几乎每个 sklearn 项目开头都会用到这两个——一个拿数据,一个切数据

fetch_openml:从 OpenML 在线下载数据集

from sklearn.datasets import fetch_openml
 
# 经典例子:下载 MNIST 手写数字(70000 张 28x28 图)
mnist = fetch_openml("mnist_784", version=1)
X, y = mnist.data, mnist.target        # X: 特征 (70000, 784),y: 标签
 
# 常用参数
fetch_openml("mnist_784", version=1, as_frame=False)   # 返回 numpy 数组而非 DataFrame
fetch_openml("iris", return_X_y=True)                  # 直接返回 (X, y) 元组,省得再拆
  • 是什么:从 OpenML(一个公开数据集平台)按名字/ID 下载现成数据集,免去自己找 CSV
  • sklearn.datasets 里的三类数据源
    函数前缀来源例子
    load_*sklearn 自带的小数据集(本地,秒开)load_iris()load_digits()
    fetch_*在线下载的较大数据集(首次要联网,之后缓存)fetch_openml()fetch_california_housing()
    make_*随机生成的合成数据(测试算法用)make_classification()make_blobs()
  • 返回值:默认是一个 Bunch 对象(类似字典),有 .data(特征 X)、.target(标签 y)、.feature_names 等;加 return_X_y=True 直接给 (X, y)
  • as_frame 参数:默认可能返回 pandas DataFrame;要 numpy 数组喂给某些模型时设 as_frame=False

坑:fetch_openml 第一次要联网下载(大数据集可能几十 MB,慢),之后会缓存到本地 ~/scikit_learn_data/y 拿到的标签常是字符串(如 '5'),做数值比较前可能要 y.astype(int)

train_test_split:把数据切成训练集和测试集

from sklearn.model_selection import train_test_split
 
X_train, X_test, y_train, y_test = train_test_split(
    X, y,
    test_size=0.2,        # 测试集占 20%(也可用 train_size)
    random_state=42,      # 固定随机种子,保证每次切法一样(可复现)
    shuffle=True,         # 切分前先打乱(默认 True)
    stratify=y            # 按 y 的类别比例分层抽样(分类任务强烈推荐)
)
  • 是什么:把数据集随机切成训练集(用来学)和测试集(用来评估没见过的数据),是防止过拟合评估的基本功
  • 返回顺序固定X_train, X_test, y_train, y_test(先 X 后 y,先 train 后 test),顺序别记错
  • 关键参数
    参数作用
    test_size测试集比例(如 0.2)或绝对数量(如 100
    random_state随机种子,固定它结果才可复现;不设每次切的都不同
    shuffle切分前是否打乱,默认 True(时间序列数据要设 False)
    stratify=y分层抽样:让训练/测试集里各类别比例和原数据一致

stratify=y 很重要:类别不平衡时(比如 90% A 类、10% B 类),不分层可能导致测试集里几乎没有 B 类,评估失真。分类任务默认加上 stratify=y

两者连起来的典型开头

from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
 
X, y = fetch_openml("mnist_784", version=1, return_X_y=True, as_frame=False)
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)
# 接下来:预处理 → 训练模型 → 评估(见第 4 节工作流)

6. Pipeline(把预处理和模型串起来,防泄露)

from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC
 
pipe = make_pipeline(StandardScaler(), SVC())
pipe.fit(X_train, y_train)      # 预处理 + 训练一步到位
pipe.predict(X_test)            # 预测时自动先 transform 再 predict

Pipeline 的价值:把”标准化 + 模型”打包成一个对象,交叉验证/调参时每一折都在训练子集上重新 fit 预处理,从根源上避免数据泄露。

7. 交叉验证与调参

from sklearn.model_selection import cross_val_score, GridSearchCV
 
# 交叉验证:更可靠的评估
scores = cross_val_score(model, X, y, cv=5)   # 5 折
print(scores.mean())
 
# 网格搜索调超参数
param_grid = {"n_estimators": [50, 100, 200], "max_depth": [3, 5, None]}
grid = GridSearchCV(RandomForestClassifier(), param_grid, cv=5)
grid.fit(X_train, y_train)
print(grid.best_params_)        # 最优参数组合

8. 常见坑

  • X 不是二维:单特征忘了 reshape(-1, 1),报 Expected 2D array
  • 数据泄露:在全量数据(含测试集)上 fit 预处理或调参,评估虚高——用 Pipeline + 只在训练集 fit 规避
  • 分类标签是字符串:多数模型能处理,但某些需要先 LabelEncoder;特征里的类别列要 OneHotEncoder
  • 不设 random_state:结果不可复现;train_test_split、模型都传 random_state 固定
  • 类别不平衡还看准确率:99% 负样本时全预测负也有 99% 准确率——看 f1_scoreconfusion_matrix 才靠谱
  • 拿 sklearn 做深度学习MLPClassifier 只是玩具级;真神经网络用 PyTorch,见 torch.md
  • 忘了特征缩放:SVM、KNN、线性模型对量纲敏感,务必 StandardScaler;树模型则不需要

9. 延伸阅读 / 关联概念

  • NumPy / pandas — sklearn 的输入通常是 NumPy 数组或 DataFrame;见 numpy-basics.mdpandas-loc-iloc.md
  • 矩阵运算 — 很多模型底层是矩阵运算;见 matrix-operations.md
  • PyTorch — 深度学习场景的分工对象;见 torch.md
  • train/test split & 交叉验证 — 模型评估的基本功,防止过拟合评估
  • 数据泄露 (Data Leakage) — 机器学习最隐蔽也最致命的错误,Pipeline 是主要防线
  • 官方文档:https://scikit-learn.org/stable/