Escalado y Transformación de Datos#
Objetivos#
Comprender por qué las diferencias de escala entre variables pueden afectar el desempeño de muchos algoritmos de Machine Learning.
Entender el funcionamiento matemático de los métodos de escalado más comunes: MinMaxScaler, StandardScaler y RobustScaler.
Visualizar cómo el escalado modifica la distribución y magnitud de los datos.
Identificar cuándo utilizar cada tipo de escalador según la distribución de los datos y la presencia de outliers.
Aplicar correctamente el escalado en un flujo de trabajo de Machine Learning evitando data leakage.
Prerrequisitos#
Conocimiento básico del flujo de trabajo en Machine Learning (datos de entrenamiento y prueba) Conceptos Básicos de Machine Learning.
Transformaciones y Feature Engineering Avanzado (Recomendado).
Manipulación básica de datos con Pandas (
DataFrame, selección de columnas).Conceptos básicos de estadística descriptiva: media, mediana, desviación estándar.
Visualización básica de datos con
MatplotliboSeaborn(histogramas y scatter plots).
Configuración del Entorno#
Ejecución en Google Colab. Clonando repositorio...
1. El Problema de las Escalas Dispares#
Supongamos que queremos predecir el precio de una casa. Las variables son:
Cantidad de habitaciones: Rango de
1a5.Tamaño del terreno: Rango de
100a10000metros cuadrados.
Muchos algoritmos de Machine Learning (como KNN, que mide distancias geométricas, o Regresión Lineal/Logística, que usa Descenso de Gradiente) son muy sensibles a la magnitud de los números. Si no escalamos los datos, el algoritmo pensará que una diferencia de 10 metros cuadrados es muchísimo más importante que una diferencia de 2 habitaciones (porque matemáticamente 10 > 2), lo cual es falso en la realidad inmobiliaria.
El objetivo del escalado es poner a todas las características (features) en igualdad de condiciones matemáticas, sin destruir las relaciones de distancia proporcionales entre los puntos.
2. Tipos de Escaladores en Scikit-Learn#
Vamos a explorar los tres escaladores más comunes, generando un dataset sintético para visualizar exactamente qué hacen matemáticamente:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler
# Generar un dataset de "ingresos" (con un outlier muy grande) y "edad"
np.random.seed(42)
edad = np.random.normal(40, 10, 100) # Media 40, Desviación 10
ingreso = np.random.normal(50000, 15000, 100)
# Introducimos un par de outliers extremos en el ingreso
ingreso[0] = 250000
ingreso[1] = -10000 # Error de carga de datos hipotético
df = pd.DataFrame({'Edad': edad, 'Ingreso': ingreso})
fig, ax = plt.subplots(figsize=(6, 4))
sns.scatterplot(x='Edad', y='Ingreso', data=df)
plt.title("Datos Originales (Note las escalas de los ejes y los Outliers)")
plt.show()
A) Normalización: MinMaxScaler#
La normalización comprime (o expande) los datos para que encajen exactamente en un rango definido, usualmente [0, 1].
La fórmula es:
¿Cuándo usarlo?
Cuando se necesita que todas las características estén estrictamente acotadas (ej. para algoritmos de Visión Computacional donde los píxeles van de 0 a 255).
Cuando la distribución de los datos no es Gaussiana (no tiene forma de campana).
La Debilidad: Es extremadamente sensible a outliers. Como usa el Max y el Min, un solo valor atípico arruinará la escala para todos los demás datos.
# Aplicar MinMaxScaler
minmax = MinMaxScaler()
df_minmax = pd.DataFrame(minmax.fit_transform(df), columns=df.columns)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
sns.scatterplot(x='Edad', y='Ingreso', data=df, ax=ax1).set_title('Original')
sns.scatterplot(x='Edad', y='Ingreso', data=df_minmax, ax=ax2).set_title('MinMaxScaler [0, 1]')
plt.show()
Observar la gráfica de MinMaxScaler. Toda la masa de datos “normales” de ingreso quedó comprimida en una línea estrecha cerca del 0.2, porque el algoritmo se vio forzado a estirar el eje Y hasta el 1.0 solo para acomodar al outlier de 250.000. El MinMaxScaler no maneja bien los outliers.
B) Estandarización: StandardScaler (Z-Score)#
La estandarización re-centra los datos para que tengan una media (\(\mu\)) de 0 y una desviación estándar (\(\sigma\)) de 1. La fórmula es:
¿Cuándo usarlo?
Es el estándar por defecto (pun intended) en la mayoría de modelos (Regresión Logística, SVM, Redes Neuronales).
Asume empíricamente que los datos tienen una distribución normal (Gaussiana).
std_scaler = StandardScaler()
df_std = pd.DataFrame(std_scaler.fit_transform(df), columns=df.columns)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
sns.histplot(df['Ingreso'], kde=True, ax=ax1).set_title('Distribución Original (Ingreso)')
sns.histplot(df_std['Ingreso'], kde=True, ax=ax2).set_title('StandardScaler (Ingreso)')
plt.show()
print(f"Media del Ingreso Estandarizado: {df_std['Ingreso'].mean():.4f}")
print(f"Desviación Estándar del Ingreso Estandarizado: {df_std['Ingreso'].std():.4f}")
Media del Ingreso Estandarizado: -0.0000
Desviación Estándar del Ingreso Estandarizado: 1.0050
La forma de la distribución es idéntica, pero el eje X ahora mide “a cuántas desviaciones estándar estoy de la media”. El outlier de 250k ahora tiene un valor Z de ~7, lo que estadísticamente nos grita: “Soy una anomalía”.
C) RobustScaler: El Salvador contra Outliers#
Si recordamos el EDA inicial, la media es muy sensible a outliers. Por lo tanto, el StandardScaler (que usa la media) se ve ligeramente sesgado si hay anomalías masivas.
El RobustScaler utiliza estadísticos robustos: usa la Mediana en lugar de la media, y el Rango Intercuartílico (IQR) en lugar de la desviación estándar.
robust = RobustScaler()
df_robust = pd.DataFrame(robust.fit_transform(df), columns=df.columns)
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(18, 5))
sns.scatterplot(x='Edad', y='Ingreso', data=df_minmax, ax=ax1).set_title('MinMaxScaler (Comprimido)')
sns.scatterplot(x='Edad', y='Ingreso', data=df_std, ax=ax2).set_title('StandardScaler (Sesgado)')
sns.scatterplot(x='Edad', y='Ingreso', data=df_robust, ax=ax3).set_title('RobustScaler (Estructura Preservada)')
# Límites fijados, para visualizar mejor cómo queda la "masa" central de datos
ax3.set_ylim(-3, 3)
plt.show()
Observar que el RobustScaler ignora al outlier para calcular la escala, centrando la masa principal de datos perfectamente alrededor del 0. (Hemos cortado el eje Y en la gráfica para evidenciarlo; el outlier sigue existiendo “allá arriba”, pero ya no arruina la escala del resto).
3. Resumen y Mejores Prácticas#
Escalar SIEMPRE si se usa KNN, SVM, PCA, K-Means o Redes Neuronales.
Los Árboles no lo necesitan: Random Forest y XGBoost basan sus cortes en reglas lógicas (
Si X > 10), por lo que son completamente inmunes a las escalas dispares.Flujo de Trabajo:
Si no hay outliers extremos ->
StandardScaler.Si los límites deben ser estrictos ->
MinMaxScaler.Si hay outliers y se quiere mantener la distribución de la “masa” ->
RobustScaler.
Cuidado con la Fuga de Datos (Data Leakage): Al igual que con las imputaciones, el escalador debe hacer
.fit()SOLO en los datos de entrenamiento para aprender la media/min/max. Luego, se usa.transform()en los datos de validación/prueba. Hacer unfiten todo el dataset contamina el modelo con información del futuro. Lo vemos bien más adelante…
Referencias#
Géron, A. (2022). Hands-On Machine Learning with Scikit-Learn, Keras, and TensorFlow. O’Reilly Media.
Conexiones y Próximos Pasos#
➡️ Siguiente: Ahora que nuestros datos están en la misma escala, podemos aplicar algoritmos geométricos para comprimir la información en Reducción de Dimensionalidad (PCA).
Entorno de Ejecución#
| Package | Version |
|---|---|
| Python | 3.12.12 |
| Platform | Linux-6.6.113+-x86_64-with-glibc2.35 |
| IPython | 7.34.0 |
| ipywidgets | 7.7.1 |
| joblib | 1.5.3 |
| matplotlib | 3.10.0 |
| numpy | 2.0.2 |
| pandas | 2.2.2 |
| scipy | 1.16.3 |
| seaborn | 0.13.2 |
| sklearn | 1.5.3 |
| statsmodels | 0.14.6 |