10. Escalado y normalización de datos

10.1 Por qué este tema importa

Muchos algoritmos de Machine Learning trabajan midiendo distancias o combinando variables con escalas muy distintas. Si una columna tiene valores pequeños y otra tiene valores muy grandes, la columna grande puede dominar el cálculo, aunque no sea la más importante.

Por ejemplo:

  • edad: puede moverse entre 18 y 70;
  • ingresos: puede moverse entre 300 y 5000.

Si dejamos ambos datos tal como están, un algoritmo basado en distancias podría prestar mucha más atención a ingresos que a edad, simplemente porque sus números son más grandes.

10.2 Escalado y normalización no son exactamente lo mismo

En la práctica muchas veces se usan como sinónimos, pero conviene distinguir:

  • Escalado: ajustar una variable para que sus valores queden en una escala comparable con otras.
  • Normalización: transformar los datos siguiendo una regla concreta, por ejemplo llevarlos a un rango fijo o a una distribución centrada.

En Scikit-learn, dos transformaciones muy conocidas son:

  • StandardScaler: centra cada variable en media 0 y desviación estándar 1.
  • MinMaxScaler: lleva los valores a un rango dado, normalmente entre 0 y 1.

En este tema usaremos StandardScaler, porque es uno de los más habituales y muy útil para comenzar.

10.3 Cuándo suele hacer falta escalar

El escalado suele ser importante cuando el algoritmo depende de distancias o magnitudes comparables. Algunos casos típicos:

  • K vecinos más cercanos (KNN)
  • Máquinas de soporte vectorial (SVM)
  • Regresión logística
  • KMeans
  • PCA

En cambio, modelos basados en árboles, como DecisionTree o RandomForest, normalmente no dependen tanto del escalado.

10.4 Ejemplo muy claro: KNN con y sin escalado

Vamos a usar un problema sencillo: predecir si un cliente compra un producto a partir de su edad y sus ingresos. Entrenaremos un modelo KNN sin escalar y otro con StandardScaler.

La idea es comparar ambos enfoques y observar por qué el escalado ayuda.

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

clientes = pd.DataFrame({
    "edad": [22, 25, 27, 30, 32, 35, 40, 45, 50, 55, 28, 38],
    "ingresos": [300, 320, 340, 500, 650, 700, 900, 1200, 1500, 1800, 360, 820],
    "compra": [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1]
})

X = clientes[["edad", "ingresos"]]
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 sin escalado
knn_sin_escalar = KNeighborsClassifier(n_neighbors=3)
knn_sin_escalar.fit(X_train, y_train)
y_pred_sin = knn_sin_escalar.predict(X_test)

# Modelo con escalado
modelo_escalado = Pipeline([
    ("escalador", StandardScaler()),
    ("knn", KNeighborsClassifier(n_neighbors=3))
])
modelo_escalado.fit(X_train, y_train)
y_pred_con = modelo_escalado.predict(X_test)

print("Exactitud sin escalado:", accuracy_score(y_test, y_pred_sin))
print("Exactitud con escalado:", accuracy_score(y_test, y_pred_con))

nuevo_cliente = pd.DataFrame({
    "edad": [36],
    "ingresos": [780]
})

pred_sin = knn_sin_escalar.predict(nuevo_cliente)[0]
pred_con = modelo_escalado.predict(nuevo_cliente)[0]

print("Predicción sin escalado:", pred_sin)
print("Predicción con escalado:", pred_con)

Salida resumida esperada:

Exactitud sin escalado: ...
Exactitud con escalado: ...
Predicción sin escalado: ...
Predicción con escalado: ...

10.5 Qué está pasando en este ejemplo

El modelo KNN busca los vecinos más cercanos a cada caso. Para hacerlo, calcula distancias usando las variables de entrada. Si una columna tiene valores mucho mayores que otra, dominará la distancia.

En nuestro ejemplo:

  • edad se mueve en decenas;
  • ingresos se mueve en cientos o miles.

Sin escalado, la diferencia en ingresos pesa mucho más que la diferencia en edad. Con escalado, ambas variables pasan a ser comparables y el algoritmo puede aprovechar mejor las dos.

10.6 Explicación detallada del código

  • KNeighborsClassifier(n_neighbors=3): crea un clasificador que toma la decisión según los tres vecinos más cercanos.
  • knn_sin_escalar.fit(...): entrena el modelo usando los datos tal como vienen.
  • Pipeline([...]): encadena el escalado y el modelo en un único flujo.
  • StandardScaler(): transforma cada variable para que quede centrada y comparable con las demás.
  • modelo_escalado.fit(...): primero escala los datos y luego entrena KNN.
  • accuracy_score(...): compara las predicciones con los valores reales.

10.7 Por qué conviene usar Pipeline

Si escalamos “a mano”, es fácil cometer errores: por ejemplo, escalar entrenamiento de una forma y datos nuevos de otra. Pipeline evita ese problema porque garantiza el mismo flujo en todas las etapas:

  • entrenamiento;
  • evaluación;
  • predicción sobre casos nuevos.

Además, el código queda más corto, más limpio y más fácil de mantener.

10.8 Cuándo elegir StandardScaler o MinMaxScaler

No existe una única respuesta válida para todos los casos, pero estas reglas ayudan:

  • StandardScaler: suele ser una muy buena opción general cuando queremos variables centradas y comparables.
  • MinMaxScaler: es útil cuando queremos acotar todo a un rango fijo, por ejemplo entre 0 y 1.

Lo importante al comenzar no es memorizar una receta rígida, sino entender la idea: evitar que una variable domine a las demás solo por su escala.

10.9 Errores comunes

  • Escalar antes de separar entrenamiento y prueba: eso puede introducir fuga de información.
  • Escalar unas columnas sí y otras no sin criterio: conviene saber por qué se transforma cada variable.
  • Olvidar aplicar el mismo escalado a datos nuevos: el modelo espera la misma transformación que usó al entrenar.
  • Creer que siempre mejora todo: algunos algoritmos, especialmente los basados en árboles, no necesitan escalado.

10.10 Qué deberías retener

  • El escalado evita que una variable domine a otra solo por tener números más grandes.
  • Algoritmos como KNN, SVM, KMeans, PCA y regresión logística suelen beneficiarse del escalado.
  • StandardScaler es una herramienta muy útil para empezar.
  • Pipeline es la forma más segura de aplicar escalado y modelo juntos.
  • No todos los modelos lo necesitan, pero cuando el algoritmo depende de distancias, conviene probarlo.