{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n# Comparing Nearest Neighbors with and without Neighborhood Components Analysis\n\nAn example comparing nearest neighbors classification with and without\nNeighborhood Components Analysis.\n\nIt will plot the class decision boundaries given by a Nearest Neighbors\nclassifier when using the Euclidean distance on the original features, versus\nusing the Euclidean distance after the transformation learned by Neighborhood\nComponents Analysis. The latter aims to find a linear transformation that\nmaximises the (stochastic) nearest neighbor classification accuracy on the\ntraining set.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "# Authors: The scikit-learn developers\n# SPDX-License-Identifier: BSD-3-Clause\n\nimport matplotlib.pyplot as plt\nfrom matplotlib.colors import ListedColormap\n\nfrom sklearn import datasets\nfrom sklearn.inspection import DecisionBoundaryDisplay\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.neighbors import KNeighborsClassifier, NeighborhoodComponentsAnalysis\nfrom sklearn.pipeline import Pipeline\nfrom sklearn.preprocessing import StandardScaler\n\nn_neighbors = 1\n\ndataset = datasets.load_iris()\nX, y = dataset.data, dataset.target\n\n# we only take two features. We could avoid this ugly\n# slicing by using a two-dim dataset\nX = X[:, [0, 2]]\n\nX_train, X_test, y_train, y_test = train_test_split(\n X, y, stratify=y, test_size=0.7, random_state=42\n)\n\nh = 0.05 # step size in the mesh\n\n# Create color maps\ncmap_light = ListedColormap([\"#FFAAAA\", \"#AAFFAA\", \"#AAAAFF\"])\ncmap_bold = ListedColormap([\"#FF0000\", \"#00FF00\", \"#0000FF\"])\n\nnames = [\"KNN\", \"NCA, KNN\"]\n\nclassifiers = [\n Pipeline(\n [\n (\"scaler\", StandardScaler()),\n (\"knn\", KNeighborsClassifier(n_neighbors=n_neighbors)),\n ]\n ),\n Pipeline(\n [\n (\"scaler\", StandardScaler()),\n (\"nca\", NeighborhoodComponentsAnalysis()),\n (\"knn\", KNeighborsClassifier(n_neighbors=n_neighbors)),\n ]\n ),\n]\n\nfor name, clf in zip(names, classifiers):\n clf.fit(X_train, y_train)\n score = clf.score(X_test, y_test)\n\n _, ax = plt.subplots()\n DecisionBoundaryDisplay.from_estimator(\n clf,\n X,\n cmap=cmap_light,\n alpha=0.8,\n ax=ax,\n response_method=\"predict\",\n plot_method=\"pcolormesh\",\n shading=\"auto\",\n )\n\n # Plot also the training and testing points\n plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold, edgecolor=\"k\", s=20)\n plt.title(\"{} (k = {})\".format(name, n_neighbors))\n plt.text(\n 0.9,\n 0.1,\n \"{:.2f}\".format(score),\n size=15,\n ha=\"center\",\n va=\"center\",\n transform=plt.gca().transAxes,\n )\n\nplt.show()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.21" } }, "nbformat": 4, "nbformat_minor": 0 }