15. K vecinos más cercanos (KNN)

15.1 Una idea muy simple y muy poderosa

KNN, abreviatura de K Nearest Neighbors, es uno de los algoritmos más fáciles de entender cuando empezamos en Machine Learning. Su lógica es muy intuitiva: para predecir un caso nuevo, mira cuáles son los casos más parecidos que ya conoce.

En lugar de aprender una fórmula explícita, KNN toma decisiones comparando distancias entre ejemplos.

15.2 Cómo funciona KNN en palabras sencillas

Supongamos que queremos clasificar un nuevo cliente. KNN hace lo siguiente:

  • ubica ese cliente entre los datos conocidos;
  • busca los K vecinos más cercanos;
  • observa qué clase predomina entre esos vecinos;
  • asigna esa clase al caso nuevo.

Si la mayoría de los vecinos compró, KNN tenderá a predecir compra. Si la mayoría no compró, tenderá a predecir que no comprará.

15.3 Qué significa la letra K

La letra K indica cuántos vecinos se tomarán en cuenta.

Por ejemplo:

  • si k = 1, el modelo decide mirando solo el vecino más cercano;
  • si k = 3, decide según los tres vecinos más cercanos;
  • si k = 5, decide según los cinco vecinos más cercanos.

Ese valor es muy importante porque cambia el comportamiento del algoritmo.

15.4 Qué pasa si K es muy chico o muy grande

Elegir k demasiado pequeño puede volver al modelo muy sensible al ruido. Elegirlo demasiado grande puede hacer que pierda detalle local.

  • K muy chico: el modelo se vuelve inestable y puede reaccionar demasiado a casos atípicos.
  • K muy grande: el modelo se vuelve demasiado general y puede mezclar regiones que deberían distinguirse.

Por eso el valor de k suele elegirse probando varias opciones y evaluando cuál funciona mejor.

15.5 Por qué KNN depende tanto de la distancia

Como KNN decide a partir de qué puntos están más cerca, la distancia es el corazón del algoritmo. Eso tiene una consecuencia práctica muy importante: el escalado de variables suele ser clave.

Si una variable tiene números muy grandes y otra tiene números chicos, la grande puede dominar la distancia y sesgar la decisión. Por eso KNN suele combinarse con escalado, como vimos en un tema anterior.

15.6 Ejemplo muy claro: predecir compra de un cliente

Vamos a usar dos variables:

  • cantidad de páginas vistas;
  • minutos dentro del sitio.

La variable objetivo será compra. Entrenaremos un KNN y luego predeciremos el comportamiento de un nuevo visitante.

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

clientes = pd.DataFrame({
    "paginas_vistas": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 5, 8],
    "minutos_sitio": [1, 1, 2, 2, 3, 4, 5, 5, 6, 7, 3, 4],
    "compra": [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1]
})

X = clientes[["paginas_vistas", "minutos_sitio"]]
y = clientes["compra"]

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

modelo = Pipeline([
    ("escalador", StandardScaler()),
    ("knn", KNeighborsClassifier(n_neighbors=3))
])

modelo.fit(X_train, y_train)

y_pred = modelo.predict(X_test)
print("Valores reales:", y_test.values)
print("Predicciones:", y_pred)
print("Exactitud:", accuracy_score(y_test, y_pred))

nuevo_cliente = pd.DataFrame({
    "paginas_vistas": [7],
    "minutos_sitio": [4]
})

prediccion = modelo.predict(nuevo_cliente)[0]
probabilidad = modelo.predict_proba(nuevo_cliente)[0, 1]

print("Predicción para el nuevo cliente:", prediccion)
print(f"Probabilidad de compra: {probabilidad:.3f}")

Salida resumida esperada:

Valores reales: [...]
Predicciones: [...]
Exactitud: ...
Predicción para el nuevo cliente: ...
Probabilidad de compra: ...

15.7 Qué está pasando en el ejemplo

El modelo observa los clientes del entrenamiento y, cuando recibe un nuevo visitante, busca cuáles son los más parecidos en términos de páginas vistas y tiempo en el sitio.

Como usamos n_neighbors=3, la decisión final se toma mirando los tres vecinos más cercanos.

15.8 Por qué usamos Pipeline y StandardScaler

En este ejemplo incluimos escalado dentro de un Pipeline. Eso es importante por dos razones:

  • asegura que entrenamiento, prueba y nuevos casos reciban la misma transformación;
  • evita que variables con escalas distintas deformen la distancia.

Con KNN, esta práctica no es opcional en muchos casos: suele marcar una diferencia real en el rendimiento.

15.9 Explicación detallada del código

  • KNeighborsClassifier(n_neighbors=3): crea el clasificador KNN usando tres vecinos.
  • StandardScaler(): pone las variables en una escala comparable.
  • Pipeline([...]): combina escalado y clasificación en un solo flujo.
  • modelo.fit(...): guarda los ejemplos de entrenamiento ya preparados.
  • modelo.predict(...): asigna clase según los vecinos más cercanos.
  • modelo.predict_proba(...): estima la probabilidad de cada clase según la composición del vecindario.

15.10 Ventajas de KNN

  • Es fácil de entender e implementar.
  • No necesita un entrenamiento complejo.
  • Puede capturar fronteras de decisión no lineales.
  • Sirve muy bien como modelo inicial para comparar.

15.11 Limitaciones de KNN

  • Puede volverse lento si hay muchos datos, porque compara con muchos ejemplos al predecir.
  • Es sensible al escalado de las variables.
  • Puede sufrir con muchas dimensiones o con ruido.
  • La elección de k influye mucho en el resultado.

15.12 Errores frecuentes

  • No escalar los datos: es uno de los errores más comunes con KNN.
  • Elegir K sin validar: conviene probar varios valores y medir.
  • Confiar en pocas variables mal elegidas: KNN depende totalmente de la geometría de los datos.
  • Usarlo sin revisar el tamaño del dataset: en grandes volúmenes puede ser costoso al momento de predecir.

15.13 Qué deberías retener

  • KNN clasifica un caso nuevo mirando sus vecinos más cercanos.
  • El valor de k controla cuánto se suaviza la decisión.
  • El escalado suele ser fundamental para que funcione bien.
  • Es un algoritmo ideal para entender cómo influye la distancia en Machine Learning.
  • Es simple, útil y muy didáctico, aunque no siempre sea la mejor opción para datasets grandes.