Python
R
Aprendizaje Supervisado
KNN
Autor/a

Joel Burbano

Fecha de publicación

28 de marzo de 2024

Introducción

El algoritmo de K Vecinos Más Cercanos (KNN) es uno de los métodos más simples y efectivos para clasificación y regresión en ciencia de datos. A pesar de su simplicidad, KNN puede ser muy poderoso, especialmente cuando se configuran adecuadamente los parámetros y se utiliza en los contextos apropiados.

¿Qué es K Vecinos Más Cercanos?

KNN es un algoritmo de aprendizaje supervisado que clasifica una muestra en función de las categorías de sus \(K\) vecinos más cercanos. Para la clasificación, asigna la categoría más común entre sus vecinos, y para la regresión, predice el valor promedio de los vecinos más cercanos.

Funcionamiento del KNN:

  1. Selección de K: Elige el número de vecinos más cercanos (\(K\)).

  2. Distancia: Calcula la distancia entre la muestra y todas las demás muestras en el conjunto de datos (comúnmente usando la distancia euclidiana).

  3. Vecinos: Identifica los \(K\) vecinos más cercanos a la muestra.

  4. Votación: Asigna la clase más común (clasificación) o el promedio de los valores (regresión) entre los \(K\) vecinos.

Ejemplo

Para ilustrar el uso de KNN, usaremos el dataset Iris.

Paso 1: Instalación de Librerías

Código
import pandas as pd 
pd.options.display.max_columns=None
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, classification_report
import matplotlib.pyplot as plt
import seaborn as sb
Código
library(class)
library(caret)
library(GGally)
library(ggplot2)

Paso 2: Cargar y Preprocesar los Datos

Código
data = pd.read_csv("Iris.csv")
data = data.drop(['Id'], axis = 1)
X = data.drop(['Species'], axis = 1)
y = data['Species']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.3, random_state = 42)

scaler = StandardScaler()

X_train = scaler.fit_transform(X_train)
X_test = scaler.fit_transform(X_test)
Código
data <- read.csv("Iris.csv")
data <- data[,-1]

any(is.na(data))
[1] FALSE
Código
X <- data[,-5]
y <- data$Species

set.seed(42)
trainIndex <- createDataPartition(y, p = .7, list = FALSE)
X_train <- X[trainIndex,]
X_test <- X[-trainIndex,]
y_train <- y[trainIndex]
y_test <- y[-trainIndex]

preProcValues <- preProcess(X_train, method = c("center", "scale"))
X_train <- predict(preProcValues, X_train)
X_test <- predict(preProcValues, X_test)

Paso 3: Entrenar el Modelo

Código
knn = KNeighborsClassifier(n_neighbors = 3)
knn.fit(X_train, y_train)
KNeighborsClassifier(n_neighbors=3)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
Código
knn_model <- knn(train = X_train, test = X_test, cl = y_train, k = 3)

Paso 4: Evaluar el Modelo

Código
y_pred = knn.predict(X_test)

accuracy = accuracy_score(y_test, y_pred)
print(f'Accuracy: {accuracy}')
Accuracy: 0.9111111111111111
Código
print('Confusion Matrix:\n', confusion_matrix(y_test, y_pred))
Confusion Matrix:
 [[19  0  0]
 [ 0  9  4]
 [ 0  0 13]]
Código
print('Classifcation Report:\n', classification_report(y_test, y_pred))
Classifcation Report:
                  precision    recall  f1-score   support

    Iris-setosa       1.00      1.00      1.00        19
Iris-versicolor       1.00      0.69      0.82        13
 Iris-virginica       0.76      1.00      0.87        13

       accuracy                           0.91        45
      macro avg       0.92      0.90      0.89        45
   weighted avg       0.93      0.91      0.91        45
Código
confusion <- confusionMatrix(knn_model, as.factor(y_test))
print(confusion)
Confusion Matrix and Statistics

                 Reference
Prediction        Iris-setosa Iris-versicolor Iris-virginica
  Iris-setosa              14               0              0
  Iris-versicolor           1              14              2
  Iris-virginica            0               1             13

Overall Statistics
                                          
               Accuracy : 0.9111          
                 95% CI : (0.7878, 0.9752)
    No Information Rate : 0.3333          
    P-Value [Acc > NIR] : 8.467e-16       
                                          
                  Kappa : 0.8667          
                                          
 Mcnemar's Test P-Value : NA              

Statistics by Class:

                     Class: Iris-setosa Class: Iris-versicolor
Sensitivity                      0.9333                 0.9333
Specificity                      1.0000                 0.9000
Pos Pred Value                   1.0000                 0.8235
Neg Pred Value                   0.9677                 0.9643
Prevalence                       0.3333                 0.3333
Detection Rate                   0.3111                 0.3111
Detection Prevalence             0.3111                 0.3778
Balanced Accuracy                0.9667                 0.9167
                     Class: Iris-virginica
Sensitivity                         0.8667
Specificity                         0.9667
Pos Pred Value                      0.9286
Neg Pred Value                      0.9355
Prevalence                          0.3333
Detection Rate                      0.2889
Detection Prevalence                0.3111
Balanced Accuracy                   0.9167

Paso 5: Visualización de Resultados

Código
sb.pairplot(data, hue = 'Species')

Código
plt.clf()

Código
ggpairs(data, aes(color = Species, alpha = 0.5)) +
  theme_bw()

Ventajas y Desventajas

Ventajas

  • Simplicidad: Fácil de entender e implementar.

  • No Paramétrico: No asume ninguna distribución de datos.

Desventajas

  • Costo Computacional: Requiere almacenar todos los datos de entrenamiento y calcular distancias para cada predicción.

  • Sensibilidad al Ruido: Afectado por la escala y por valores atípicos.

Conclusión

El algoritmo de K Vecinos Más Cercanos es una herramienta poderosa y fácil de usar para tareas de clasificación y regresión. A través de ejemplos prácticos en Python y R, hemos demostrado cómo implementar y evaluar este modelo en la práctica. Aunque tiene algunas limitaciones, KNN sigue siendo una opción valiosa para muchos problemas en ciencia de datos.