Algoritmo de vecinos más cercanos en Python y Scikit-Learn

    El algoritmo de K-vecinos más cercanos (KNN) es un tipo de algoritmos de Machine Learning supervisados. KNN es extremadamente fácil de implementar en su forma más básica y, sin embargo, realiza tareas de clasificación bastante complejas. Es un algoritmo de aprendizaje perezoso ya que no tiene una fase de entrenamiento especializada. Más bien, usa todos los datos para entrenar mientras clasifica un nuevo punto de datos o instancia. KNN es un algoritmo de aprendizaje no paramétrico, lo que significa que no asume nada sobre los datos subyacentes. Esta es una característica extremadamente útil ya que la mayoría de los datos del mundo real realmente no siguen ningún supuesto teórico, por ejemplo, separabilidad lineal, distribución uniforme, etc.

    En este artículo, veremos cómo se puede implementar KNN con la biblioteca Scikit-Learn de Python. Pero antes de eso, exploremos primero la teoría detrás de KNN y veamos cuáles son algunos de los pros y los contras del algoritmo.

    Teoría

    La intuición detrás del algoritmo KNN es uno de los más simples de todos los algoritmos de Machine Learning supervisados. Simplemente calcula la distancia de un nuevo punto de datos a todos los demás puntos de datos de entrenamiento. La distancia puede ser de cualquier tipo, por ejemplo, euclidiana o Manhattan, etc. A continuación, selecciona los puntos de datos K más cercanos, donde K puede ser cualquier número entero. Finalmente, asigna el punto de datos a la clase a la que pertenecen la mayoría de los K puntos de datos.

    Veamos este algoritmo en acción con la ayuda de un ejemplo simple. Suponga que tiene un conjunto de datos con dos variables, que cuando se trazan, se parece al de la siguiente figura.

    Su tarea es clasificar un nuevo punto de datos con ‘X’ en la clase “Azul” o la clase “Roja”. Los valores de las coordenadas del punto de datos son x = 45 e y = 50. Suponga que el valor de K es 3. El algoritmo KNN comienza calculando la distancia del punto X a todos los puntos. Luego encuentra los 3 puntos más cercanos con la menor distancia al punto X. Esto se muestra en la figura siguiente. Se han rodeado los tres puntos más cercanos.

    El paso final del algoritmo KNN es asignar un nuevo punto a la clase a la que pertenecen la mayoría de los tres puntos más cercanos. En la figura de arriba podemos ver que los dos de los tres puntos más cercanos pertenecen a la clase “Rojo” mientras que uno pertenece a la clase “Azul”. Por lo tanto, el nuevo punto de datos se clasificará como “Rojo”.

    Pros y contras de KNN

    En esta sección presentaremos algunos de los pros y los contras de utilizar el algoritmo KNN.

    Pros

  • Es extremadamente fácil de implementar.
  • Como se dijo anteriormente, es aprendizaje perezoso algoritmo y, por lo tanto, no requiere entrenamiento antes de realizar predicciones en tiempo real. Esto hace que el algoritmo KNN sea mucho más rápido que otros algoritmos que requieren entrenamiento, por ejemplo, SVM, regresión lineal, etc.
  • Dado que el algoritmo no requiere entrenamiento antes de hacer predicciones, se pueden agregar nuevos datos sin problemas.
  • Solo hay dos parámetros necesarios para implementar KNN, es decir, el valor de K y la función de distancia (por ejemplo, Euclidiana o Manhattan, etc.)
  • Contras

  • El algoritmo KNN no funciona bien con datos de alta dimensión porque con un gran número de dimensiones, se vuelve difícil para el algoritmo calcular la distancia en cada dimensión.
  • El algoritmo KNN tiene un alto costo de predicción para grandes conjuntos de datos. Esto se debe a que en grandes conjuntos de datos el costo de calcular la distancia entre el nuevo punto y cada punto existente es mayor.
  • Por último, el algoritmo KNN no funciona bien con características categóricas ya que es difícil encontrar la distancia entre dimensiones con características categóricas.
  • Implementación del algoritmo KNN con Scikit-Learn

    En esta sección, veremos cómo se puede utilizar la biblioteca Scikit-Learn de Python para implementar el algoritmo KNN en menos de 20 líneas de código. Las instrucciones de descarga e instalación de la biblioteca de aprendizaje Scikit están disponibles en aquí.

    Nota: El código proporcionado en este tutorial se ha ejecutado y probado con el cuaderno Python Jupyter.

    El conjunto de datos

    Vamos a utilizar el famoso conjunto de datos de iris para nuestro ejemplo KNN. El conjunto de datos consta de cuatro atributos: ancho de sépalo, largo de sépalo, ancho de pétalo y largo de pétalo. Estos son los atributos de tipos específicos de plantas de iris. La tarea consiste en predecir la clase a la que pertenecen estas plantas. Hay tres clases en el conjunto de datos: Iris-setosa, Iris-versicolor e Iris-virginica. Más detalles del conjunto de datos están disponibles aquí.

    Importación de bibliotecas

    import numpy as np
    import matplotlib.pyplot as plt
    import pandas as pd
    

    Importar el conjunto de datos

    Para importar el conjunto de datos y cargarlo en nuestro marco de datos de pandas, ejecute el siguiente código:

    url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"
    
    # Assign colum names to the dataset
    names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'Class']
    
    # Read dataset to pandas dataframe
    dataset = pd.read_csv(url, names=names)
    

    Para ver cómo se ve realmente el conjunto de datos, ejecute el siguiente comando:

    dataset.head()
    

    Al ejecutar el script anterior, se mostrarán las primeras cinco filas de nuestro conjunto de datos como se muestra a continuación:

    Longitud del sépalo Ancho del sépalo Longitud del pétalo Ancho del pétalo Clase

    0

    1

    2

    3

    4

    5.13,51.40,2Iris-setosa
    4.93,01.40,2Iris-setosa
    4.73.21.30,2Iris-setosa
    4.63.11,50,2Iris-setosa
    5,03.61.40,2Iris-setosa

    Preprocesamiento

    El siguiente paso es dividir nuestro conjunto de datos en sus atributos y etiquetas. Para hacerlo, use el siguiente código:

    X = dataset.iloc[:, :-1].values
    y = dataset.iloc[:, 4].values
    

    los X variable contiene las primeras cuatro columnas del conjunto de datos (es decir, atributos) mientras y contiene las etiquetas.

    Prueba de tren dividida

    Para evitar un ajuste excesivo, dividiremos nuestro conjunto de datos en divisiones de entrenamiento y de prueba, lo que nos da una mejor idea de cómo se desempeñó nuestro algoritmo durante la fase de prueba. De esta manera, nuestro algoritmo se prueba en datos no vistos, como lo haría en una aplicación de producción.

    Para crear divisiones de entrenamiento y prueba, ejecute el siguiente script:

    from sklearn.model_selection import train_test_split
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20)
    

    El script anterior divide el conjunto de datos en un 80% de datos de tren y un 20% de datos de prueba. Esto significa que de un total de 150 registros, el conjunto de entrenamiento contendrá 120 registros y el conjunto de prueba contiene 30 de esos registros.

    Escala de funciones

    Antes de realizar predicciones reales, siempre es una buena práctica escalar las características para que todas puedan evaluarse de manera uniforme. Wikipedia explica el razonamiento bastante bien:

    Dado que el rango de valores de los datos sin procesar varía ampliamente, en algunos algoritmos de Machine Learning, las funciones objetivas no funcionarán correctamente sin la normalización. Por ejemplo, la mayoría de los clasificadores calculan la distancia entre dos puntos por la distancia euclidiana. Si una de las características tiene una amplia gama de valores, la distancia se regirá por esta característica en particular. Por lo tanto, el rango de todas las características debe normalizarse de modo que cada característica contribuya aproximadamente de manera proporcional a la distancia final.

    El algoritmo de descenso de gradiente (que se utiliza en el entrenamiento de redes neuronales y otros algoritmos de Machine Learning) también converge más rápido con las características normalizadas.

    El siguiente script realiza el escalado de características:

    from sklearn.preprocessing import StandardScaler
    scaler = StandardScaler()
    scaler.fit(X_train)
    
    X_train = scaler.transform(X_train)
    X_test = scaler.transform(X_test)
    

    Entrenamiento y predicciones

    Es extremadamente sencillo entrenar el algoritmo KNN y hacer predicciones con él, especialmente cuando se usa Scikit-Learn.

    from sklearn.neighbors import KNeighborsClassifier
    classifier = KNeighborsClassifier(n_neighbors=5)
    classifier.fit(X_train, y_train)
    

    El primer paso es importar el KNeighborsClassifier clase de la sklearn.neighbors biblioteca. En la segunda línea, esta clase se inicializa con un parámetro, es decir n_neigbours. Este es básicamente el valor de K. No hay un valor ideal para K y se selecciona después de la prueba y la evaluación; sin embargo, para empezar, 5 parece ser el valor más comúnmente utilizado para el algoritmo KNN.

    El paso final es hacer predicciones sobre nuestros datos de prueba. Para hacerlo, ejecute el siguiente script:

    y_pred = classifier.predict(X_test)
    

    Evaluar el algoritmo

    Para evaluar un algoritmo, la matriz de confusión, la precisión, la recuperación y la puntuación f1 son las métricas más utilizadas. los confusion_matrix y classification_report métodos del sklearn.metrics se puede utilizar para calcular estas métricas. Eche un vistazo al siguiente guión:

    from sklearn.metrics import classification_report, confusion_matrix
    print(confusion_matrix(y_test, y_pred))
    print(classification_report(y_test, y_pred))
    

    La salida del script anterior se ve así:

    [[11  0  0]
       0 13  0]
       0  1  6]]
                     precision   recall   f1-score   support
    
        Iris-setosa       1.00     1.00       1.00        11
    Iris-versicolor       1.00     1.00       1.00        13
     Iris-virginica       1.00     1.00       1.00         6
    
        avg / total       1.00     1.00       1.00        30
    

    Los resultados muestran que nuestro algoritmo KNN pudo clasificar los 30 registros en el conjunto de prueba con una precisión del 100%, lo cual es excelente. Aunque el algoritmo funcionó muy bien con este conjunto de datos, no espere los mismos resultados con todas las aplicaciones. Como se señaló anteriormente, KNN no siempre se desempeña tan bien con características categóricas o de alta dimensionalidad.

    Comparación de la tasa de error con el valor K

    En la sección de entrenamiento y predicción dijimos que no hay forma de saber de antemano qué valor de K produce los mejores resultados en el primer intento. Elegimos aleatoriamente 5 como el valor K y resulta en una precisión del 100%.

    Una forma de ayudarlo a encontrar el mejor valor de K es trazar la gráfica del valor de K y la tasa de error correspondiente para el conjunto de datos.

    En esta sección, trazaremos el error medio de los valores predichos del conjunto de prueba para todos los valores de K entre 1 y 40.

    Para hacerlo, primero calculemos la media de error para todos los valores predichos donde K varía entre 1 y 40. Ejecute el siguiente script:

    error = []
    
    # Calculating error for K values between 1 and 40
    for i in range(1, 40):
        knn = KNeighborsClassifier(n_neighbors=i)
        knn.fit(X_train, y_train)
        pred_i = knn.predict(X_test)
        error.append(np.mean(pred_i != y_test))
    

    El script anterior ejecuta un ciclo de 1 a 40. En cada iteración, se calcula el error medio para los valores predichos del conjunto de prueba y el resultado se agrega al error lista.

    El siguiente paso es trazar el error valores frente a valores K. Ejecute el siguiente script para crear el gráfico:

    plt.figure(figsize=(12, 6))
    plt.plot(range(1, 40), error, color="red", linestyle="dashed", marker="o",
             markerfacecolor="blue", markersize=10)
    plt.title('Error Rate K Value')
    plt.xlabel('K Value')
    plt.ylabel('Mean Error')
    

    El gráfico de salida se ve así:

    De la salida podemos ver que el error medio es cero cuando el valor de K está entre 5 y 18. Le aconsejaría que juegue con el valor de K para ver cómo afecta la precisión de las predicciones.

    Recursos

    ¿Quiere obtener más información sobre Scikit-Learn y otros algoritmos útiles de Machine Learning? Recomiendo consultar algunos recursos más detallados, como un curso en línea:

    Si bien leer publicaciones de blog como esta es un gran comienzo, la mayoría de las personas generalmente aprenden mejor con las imágenes, los recursos y las explicaciones de cursos como los vinculados anteriormente.

    Conclusión

    KNN es un algoritmo de clasificación simple pero poderoso. No requiere entrenamiento para hacer predicciones, que suele ser una de las partes más difíciles de un algoritmo de Machine Learning. El algoritmo KNN se ha utilizado ampliamente para encontrar similitudes de documentos y reconocimiento de patrones. También se ha empleado para desarrollar sistemas de recomendación y para la reducción de dimensionalidad y los pasos de preprocesamiento para visión por computadora, en particular tareas de reconocimiento facial.

    A partir de aquí, le recomendaría que implemente el algoritmo KNN para un conjunto de datos de clasificación diferente. Varíe el tamaño de la prueba y del entrenamiento junto con el valor K para ver cómo difieren sus resultados y cómo puede mejorar la precisión de su algoritmo. Hay disponible una buena colección de conjuntos de datos de clasificación aquí para que juegues.

    ¿A qué otras aplicaciones ha aplicado el algoritmo KNN? ¿Cómo te fue? ¡Háznoslo saber en los comentarios!

    .

    Etiquetas:

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *