K-nearest neighbors (KNN) en Python

KNN es un algoritmo simple de aprendizaje automático supervisado (ML) que se puede usar para tareas de clasificación o regresión, y también se usa con frecuencia en la imputación de valores faltantes. Se basa en la idea de que las observaciones más cercanas a un punto de datos dado son las observaciones más «similares» en un conjunto de datos y, por lo tanto, podemos clasificar los puntos no previstos en función de los valores de los puntos existentes más cercanos. Al elegir K, el usuario puede seleccionar el número de observaciones cercanas para usar en el algoritmo.

Aquí, le mostraremos cómo implementar el algoritmo KNN para la clasificación y le mostraremos cómo los diferentes valores de K afectan los resultados.

¿Cómo funciona?

K es el número de vecinos más cercanos a utilizar. Para la clasificación, se utiliza un voto mayoritario para determinar en qué clase debe caer una nueva observación. Los valores más grandes de K a menudo son más resistentes a los valores atípicos y producen límites de decisión más estables que los valores muy pequeños (K=3 sería mejor que K=1, lo que podría producir resultados no deseados).

Ejemplo

Comience visualizando algunos puntos de datos:

import matplotlib.pyplot as plt

x = [4, 5, 10, 4, 3, 11, 14 , 8, 10, 12]
y = [21, 19, 24, 17, 16, 25, 24, 22, 21, 21]
classes = [0, 0, 1, 0, 0, 1, 1, 0, 1, 1]

plt.scatter(x, y, c=classes)
plt.show()

Ahora ajustamos el algoritmo KNN con K=1:

from sklearn.neighbors import KNeighborsClassifier

data = list(zip(x, y))
knn = KNeighborsClassifier(n_neighbors=1)

knn.fit(data, classes)

Y utilícelo para clasificar un nuevo punto de datos:

Ejemplo

new_x = 8
new_y = 21
new_point = [(new_x, new_y)]

prediction = knn.predict(new_point)

plt.scatter(x + [new_x], y + [new_y], c=classes + [prediction[0]])
plt.text(x=new_x-1.7, y=new_y-0.7, s=f"new point, class: {prediction[0]}")
plt.show()

Ahora hacemos lo mismo, pero con un valor K más alto que cambia la predicción:

Ejemplo

knn = KNeighborsClassifier(n_neighbors=5)

knn.fit(data, classes)

prediction = knn.predict(new_point)

plt.scatter(x + [new_x], y + [new_y], c=classes + [prediction[0]])
plt.text(x=new_x-1.7, y=new_y-0.7, s=f"new point, class: {prediction[0]}")
plt.show()

Ejemplo Explicado

Importa los módulos que necesites.

Puede obtener información sobre el módulo Matplotlib en nuestro «Tutorial de Matplotlib.

scikit-learn es una biblioteca popular para el aprendizaje automático en Python.

import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier

Cree matrices que se parezcan a las variables en un conjunto de datos. Tenemos dos características de entrada (x e y) y luego una clase de destino (clase). Las características de entrada que están preetiquetadas con nuestra clase de destino se utilizarán para predecir la clase de nuevos datos. Tenga en cuenta que si bien solo usamos dos funciones de entrada aquí, este método funcionará con cualquier cantidad de variables:

x = [4, 5, 10, 4, 3, 11, 14 , 8, 10, 12]
y = [21, 19, 24, 17, 16, 25, 24, 22, 21, 21]
classes = [0, 0, 1, 0, 0, 1, 1, 0, 1, 1]

Convierta las entidades de entrada en un conjunto de puntos:

data = list(zip(x, y))
print(data)

Resultado

[(4, 21), (5, 19), (10, 24), (4, 17), (3, 16), (11, 25), (14, 24), (8, 22), (10, 21), (12, 21)]

Usando las características de entrada y la clase objetivo, ajustamos un modelo KNN en el modelo usando 1 vecino más cercano:

knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(data, classes)

Luego, podemos usar el mismo objeto KNN para predecir la clase de puntos de datos nuevos e imprevistos. Primero creamos nuevas funciones x e y, y luego llamamos a knn.predict() en el nuevo punto de datos para obtener una clase de 0 o 1:

new_x = 8
new_y = 21
new_point = [(new_x, new_y)]
prediction = knn.predict(new_point)
print(prediction)

Resultado

[0]

Cuando trazamos todos los datos junto con el nuevo punto y clase, podemos ver que se ha etiquetado en azul con la clase 1. La anotación de texto es solo para resaltar la ubicación del nuevo punto:

plt.scatter(x + [new_x], y + [new_y], c=classes + [prediction[0]])
plt.text(x=new_x-1.7, y=new_y-0.7, s=f"new point, class: {prediction[0]}")
plt.show()

Sin embargo, cuando cambiamos el número de vecinos a 5, el número de puntos utilizados para clasificar nuestro nuevo punto cambia. Como resultado, también lo hace la clasificación del nuevo punto:

knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(data, classes)
prediction = knn.predict(new_point)
print(prediction)

Resultado

[1]

Cuando trazamos la clase del nuevo punto junto con los puntos anteriores, notamos que el color ha cambiado según la etiqueta de clase asociada:

plt.scatter(x + [new_x], y + [new_y], c=classes + [prediction[0]])
plt.text(x=new_x-1.7, y=new_y-0.7, s=f"new point, class: {prediction[0]}")
plt.show()