缓存最近邻

Beginner

This tutorial is from open-source community. Access the source code

简介

本实验展示了如何在 KNeighborsClassifier 中使用 k 近邻之前预先计算它们。KNeighborsClassifier 可以在内部计算最近邻,但预先计算它们有几个好处,例如更精细的参数控制、多次使用的缓存或自定义实现。在这里,我们使用管道的缓存属性来缓存 KNeighborsClassifier 多次拟合之间的最近邻图。

虚拟机提示

虚拟机启动完成后,点击左上角切换到笔记本标签,以访问 Jupyter Notebook 进行练习。

有时,你可能需要等待几秒钟让 Jupyter Notebook 完成加载。由于 Jupyter Notebook 的限制,操作的验证无法自动化。

如果你在学习过程中遇到问题,随时向 Labby 提问。课程结束后提供反馈,我们将立即为你解决问题。

导入库

在这一步中,我们将导入所有必要的库。

from tempfile import TemporaryDirectory
import matplotlib.pyplot as plt

from sklearn.neighbors import KNeighborsTransformer, KNeighborsClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import load_digits
from sklearn.pipeline import Pipeline

加载数据

在这一步中,我们将从 scikit-learn 中加载数字数据集。

X, y = load_digits(return_X_y=True)
n_neighbors_list = [1, 2, 3, 4, 5, 6, 7, 8, 9]

计算最近邻图

在这一步中,我们将使用 KNeighborsTransformer 计算最近邻图。

## 该变换器使用网格搜索中所需的最大邻居数来计算最近邻图。分类器模型会根据其自身的 n_neighbors 参数要求对最近邻图进行筛选。
graph_model = KNeighborsTransformer(n_neighbors=max(n_neighbors_list), mode="distance")

定义分类器模型

在这一步中,我们将定义 KNeighborsClassifier 模型。

classifier_model = KNeighborsClassifier(metric="precomputed")

缓存最近邻图

在这一步中,我们将利用管道的缓存属性,在 KNeighborsClassifier 的多次拟合之间缓存最近邻图。

## 请注意,我们给 `memory` 一个目录来缓存图计算,在调整分类器的超参数时,这个计算会被多次使用。
with TemporaryDirectory(prefix="sklearn_graph_cache_") as tmpdir:
    full_model = Pipeline(
        steps=[("graph", graph_model), ("classifier", classifier_model)], memory=tmpdir
    )

调整超参数

在这一步中,我们将使用 GridSearchCV 调整分类器的超参数。

    param_grid = {"classifier__n_neighbors": n_neighbors_list}
    grid_model = GridSearchCV(full_model, param_grid)
    grid_model.fit(X, y)

可视化结果

在这一步中,我们将可视化网格搜索的结果。

## 绘制网格搜索的结果。
fig, axes = plt.subplots(1, 2, figsize=(8, 4))
axes[0].errorbar(
    x=n_neighbors_list,
    y=grid_model.cv_results_["mean_test_score"],
    yerr=grid_model.cv_results_["std_test_score"],
)
axes[0].set(xlabel="n_neighbors", title="Classification accuracy")
axes[1].errorbar(
    x=n_neighbors_list,
    y=grid_model.cv_results_["mean_fit_time"],
    yerr=grid_model.cv_results_["std_fit_time"],
    color="r",
)
axes[1].set(xlabel="n_neighbors", title="Fit time (with caching)")
fig.tight_layout()
plt.show()

总结

在这个实验中,我们学习了如何利用管道的缓存属性,在 KNeighborsClassifier 中使用 k 近邻之前预先计算它们。我们还学习了如何使用 GridSearchCV 调整分类器的超参数并可视化结果。