Análisis de Componentes Vecinos

Beginner

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

Introducción

Esta práctica tiene como objetivo demostrar el uso del Análisis de Componentes Vecinos (Neighborhood Components Analysis - NCA) en el aprendizaje de una métrica de distancia que maximice la precisión de la clasificación de los vecinos más cercanos. Además, presenta una representación visual de esta métrica en comparación con el espacio de puntos original.

Consejos sobre la VM

Una vez que se haya iniciado la VM, haga clic en la esquina superior izquierda para cambiar a la pestaña Cuaderno y acceder a Jupyter Notebook para practicar.

En ocasiones, es posible que tenga que esperar unos segundos a que Jupyter Notebook termine de cargarse. La validación de las operaciones no se puede automatizar debido a las limitaciones de Jupyter Notebook.

Si tiene problemas durante el aprendizaje, no dude en consultar a Labby. Deje su retroalimentación después de la sesión y resolveremos rápidamente el problema para usted.

Generar puntos de datos

Comenzaremos generando un conjunto de datos de 9 muestras de 3 clases y representando los puntos en el espacio original. Para este ejemplo, nos centraremos en la clasificación del punto número 3.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from sklearn.neighbors import NeighborhoodComponentsAnalysis
from matplotlib import cm
from scipy.special import logsumexp

X, y = make_classification(
    n_samples=9,
    n_features=2,
    n_informative=2,
    n_redundant=0,
    n_classes=3,
    n_clusters_per_class=1,
    class_sep=1.0,
    random_state=0,
)

plt.figure(1)
ax = plt.gca()
for i in range(X.shape[0]):
    ax.text(X[i, 0], X[i, 1], str(i), va="center", ha="center")
    ax.scatter(X[i, 0], X[i, 1], s=300, c=cm.Set1(y[[i]]), alpha=0.4)

ax.set_title("Puntos originales")
ax.axes.get_xaxis().set_visible(False)
ax.axes.get_yaxis().set_visible(False)
ax.axis("equal")  ## para que los límites se muestren correctamente como círculos

Visualizar vecinos

Ahora visualizamos los enlaces entre los puntos de datos, con el grosor de un enlace entre el punto número 3 y otro punto siendo proporcional a su distancia.

def link_thickness_i(X, i):
    diff_embedded = X[i] - X
    dist_embedded = np.einsum("ij,ij->i", diff_embedded, diff_embedded)
    dist_embedded[i] = np.inf

    ## compute exponentiated distances (use the log-sum-exp trick to
    ## avoid numerical instabilities
    exp_dist_embedded = np.exp(-dist_embedded - logsumexp(-dist_embedded))
    return exp_dist_embedded


def relate_point(X, i, ax):
    pt_i = X[i]
    for j, pt_j in enumerate(X):
        thickness = link_thickness_i(X, i)
        if i!= j:
            line = ([pt_i[0], pt_j[0]], [pt_i[1], pt_j[1]])
            ax.plot(*line, c=cm.Set1(y[j]), linewidth=5 * thickness[j])


i = 3
relate_point(X, i, ax)
plt.show()

Aprender una incrustación

Ahora usaremos NCA (Neighborhood Components Analysis) para aprender una incrustación y representar los puntos después de la transformación. Luego tomamos la incrustación y encontramos los vecinos más cercanos.

nca = NeighborhoodComponentsAnalysis(max_iter=30, random_state=0)
nca = nca.fit(X, y)

plt.figure(2)
ax2 = plt.gca()
X_embedded = nca.transform(X)
relate_point(X_embedded, i, ax2)

for i in range(len(X)):
    ax2.text(X_embedded[i, 0], X_embedded[i, 1], str(i), va="center", ha="center")
    ax2.scatter(X_embedded[i, 0], X_embedded[i, 1], s=300, c=cm.Set1(y[[i]]), alpha=0.4)

ax2.set_title("Incrustación NCA")
ax2.axes.get_xaxis().set_visible(False)
ax2.axes.get_yaxis().set_visible(False)
ax2.axis("equal")
plt.show()

Resumen

En esta práctica, hemos demostrado cómo usar NCA (Neighborhood Components Analysis) para aprender una métrica de distancia que maximice la precisión de la clasificación de los vecinos más cercanos. Hemos visualizado los enlaces entre los puntos de datos y comparado el espacio de puntos original con el espacio transformado.