En 04-05, al estudiar K-NN, quedó anotada una amenaza con nombre propio: la maldición de la dimensionalidad. Y en este módulo la amenaza es directa, porque clustering significa distancias, y las distancias se degradan cuando las dimensiones se multiplican. El Análisis de Componentes Principales (PCA) es la respuesta clásica: una técnica no supervisada que comprime muchas features en pocas componentes nuevas, conservando el máximo posible de la varianza —es decir, de la información— original. En esta lección entenderás el problema que resuelve, la intuición geométrica de "rotar los ejes hacia donde están los datos", los conceptos de varianza explicada y acumulada, su conexión con la matriz de covarianza de 02-03, y su uso práctico en MercaFresh: visualizar en 2D los segmentos de 05-01 e interpretar qué significa cada componente a través de sus loadings.
Contenido
- La maldición de la dimensionalidad
- Intuición geométrica: rotar los ejes hacia la máxima varianza
- Componentes principales, varianza explicada y scree plot
- La conexión con la covarianza (02-03) y por qué estandarizar antes (03-05)
- PCA en scikit-learn sobre los clientes MercaFresh
- Visualización 2D de los segmentos de K-means
- Interpretar componentes: los loadings
- PCA como paso previo a modelos
- Limitaciones, y PCA vs. selección de features (03-06)
La maldición de la dimensionalidad
¿Qué pasa cuando las features pasan de 4 a 40 o a 400? Tres males se combinan:
- El espacio se vacía. Para cubrir un intervalo 1D con 10 puntos bien repartidos bastan 10; para cubrir con la misma densidad un cubo de 10 dimensiones harían falta $10^{10}$. Con dimensiones de sobra, todo dataset es una pizca de polvo en un espacio desierto: los puntos están lejos de todo.
- Las distancias pierden contraste. En alta dimensión, la distancia al vecino más cercano y al más lejano tienden a parecerse. Y si "cerca" y "lejos" apenas se distinguen, K-NN (04-05), K-means (05-01) y el jerárquico (05-02) —todos construidos sobre distancias— pierden su materia prima.
- Ruido acumulado. Cada feature irrelevante añade su ruido a la distancia euclídea; con muchas, el ruido ahoga la señal de las pocas que importan.
La salida obvia sería quitar features irrelevantes (los filtros de selección de 03-06). Pero ¿y si muchas features son relevantes pero redundantes entre sí — como gasto_total y num_pedidos, correlacionadas en 02-03? Ahí no quieres eliminar columnas: quieres fusionar la información en menos dimensiones. Eso es reducción de dimensionalidad, y PCA es su técnica reina.
Intuición geométrica: rotar los ejes hacia la máxima varianza
Imagina el scatter de dos features correlacionadas de MercaFresh: gasto_total frente a num_pedidos (estandarizadas). La nube de puntos es un elipse inclinada: quien hace más pedidos, gasta más en total. Observa dos cosas:
- La dirección diagonal de la elipse concentra casi toda la variación entre clientes: es el eje "tamaño del cliente" (mucho/poco de ambas cosas a la vez).
- La dirección perpendicular apenas varía: solo recoge el matiz "gasta más/menos de lo que sugiere su número de pedidos".
PCA formaliza exactamente esta observación: encuentra nuevos ejes, rotando los originales, de modo que el primer eje apunte hacia donde los datos más varían; el segundo, perpendicular al primero, hacia la máxima varianza restante; y así sucesivamente.
flowchart LR
A["Ejes originales:<br/>gasto_total, num_pedidos<br/>(correlacionados, redundantes)"] -->|"rotación PCA"| B["Ejes nuevos:<br/>PC1 = tamaño del cliente (var. 95%)<br/>PC2 = matiz residual (var. 5%)"]
B --> C["Compresión: quedarse<br/>solo con PC1 pierde<br/>apenas un 5% de información"]
Los ejes nuevos son las componentes principales (PC1, PC2, ...). Tres propiedades que conviene grabarse:
- Cada componente es una combinación lineal de las features originales (por ejemplo, PC1 ≈ 0,71·gasto + 0,71·pedidos): no elige columnas, las mezcla.
- Las componentes son perpendiculares entre sí y, por construcción, no correlacionadas: PCA convierte features redundantes en direcciones independientes.
- Están ordenadas por varianza: PC1 captura más que PC2, que captura más que PC3... Comprimir es simplemente quedarse con las primeras y descartar el resto.
En este sentido, "información" para PCA significa varianza: las direcciones donde los clientes difieren mucho entre sí son las que permiten distinguirlos; una dirección con varianza casi nula no dice casi nada de nadie (el mismo argumento del filtro de varianza de 03-06).
Componentes principales, varianza explicada y scree plot
¿Cuántas componentes conservar? El criterio es la varianza explicada: qué fracción de la varianza total captura cada componente.
explained_variance_ratio_en scikit-learn: por ejemplo[0.55, 0.25, 0.12, 0.05, 0.03]— PC1 explica el 55%, PC2 el 25%...- La varianza acumulada suma en orden: con 2 componentes, 80%; con 3, 92%. La regla práctica más usada: conservar las componentes necesarias para acumular el 90-95%.
- El scree plot dibuja la varianza explicada por componente. Igual que en el codo de 05-01, se busca el punto donde la curva se aplana: las componentes tras el codo aportan migajas (a menudo, ruido).
| Herramienta | Qué muestra | Decisión que apoya |
|---|---|---|
explained_variance_ratio_ |
% de varianza de cada PC | ¿Vale algo la PC3? |
| Varianza acumulada | % total con las k primeras PCs | ¿Cuántas conservo para el 90%? |
| Scree plot | La curva de las dos anteriores | Localizar el codo visualmente |
La conexión con la covarianza (02-03) y por qué estandarizar antes (03-05)
¿De dónde salen esas direcciones mágicas? De la matriz de covarianza que estudiaste en 02-03: la tabla que recoge cómo covaría cada par de features. PCA analiza esa matriz y extrae de ella sus direcciones características — cada componente principal es una de esas direcciones, y su varianza explicada, la magnitud asociada (en álgebra lineal se llaman autovectores y autovalores; no necesitamos la derivación completa, solo la consecuencia):
PCA es la matriz de covarianza hecha ejes. Donde el heatmap de correlaciones de 02-03 te decía "gasto y pedidos van juntos", PCA te da el eje concreto que resume ese ir-juntos.
De aquí sale también la regla de oro práctica: estandariza antes de PCA (03-05, StandardScaler). La covarianza depende de las unidades: si gasto_total se mide en euros (varianza en miles) y pedidos_por_mes en unidades (varianza en decenas), la dirección de máxima varianza será "el eje del gasto" por puro accidente de unidades, y PC1 será un eco de la columna más grande. Estandarizar iguala todas las varianzas a 1, con lo que PCA trabaja de hecho sobre la matriz de correlación y las direcciones reflejan estructura, no unidades. Es el mismo argumento que en K-means; en PCA es aún más crítico porque la varianza no es solo la métrica interna sino el criterio de construcción.
PCA en scikit-learn sobre los clientes MercaFresh
Ampliemos la matriz de clientes con más features del módulo 3 —RFM, ratios y tendencia— para que la reducción tenga sentido:
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import numpy as np
features = ["recencia_dias", "pedidos_por_mes", "gasto_medio_pedido",
"gasto_total", "num_pedidos", "ratio_inactividad", "tendencia"]
X = rfm[features]
X_esc = StandardScaler().fit_transform(X) # SIEMPRE antes de PCA
pca = PCA() # sin límite: todas las componentes
X_pca = pca.fit_transform(X_esc)
print(pca.explained_variance_ratio_.round(3))
# p. ej.: [0.46 0.27 0.12 0.07 0.05 0.02 0.01]
print(np.cumsum(pca.explained_variance_ratio_).round(3))
# p. ej.: [0.46 0.73 0.85 0.92 0.97 0.99 1.00]
# Scree plot
plt.plot(range(1, 8), pca.explained_variance_ratio_, "o-")
plt.xlabel("Componente principal")
plt.ylabel("Varianza explicada")
plt.title("Scree plot — clientes MercaFresh")
plt.show()Lectura del resultado:
fit_transformproyecta cada cliente sobre los nuevos ejes:X_pcatiene una columna por componente, ordenadas de mayor a menor varianza.- Dos componentes acumulan un 73% y cuatro un 92%: las 7 features originales eran en buena parte redundantes (gasto total, número de pedidos y frecuencia cuentan historias solapadas — lo sabíamos desde el heatmap de 02-03).
- Alternativas cómodas del constructor:
PCA(n_components=2)(número fijo) oPCA(n_components=0.90)(scikit-learn elige las necesarias para acumular el 90%).
Visualización 2D de los segmentos de K-means
El uso más inmediato de PCA: nuestros segmentos de 05-01 viven en un espacio que no podemos dibujar; proyectados sobre PC1-PC2 sí.
pca2 = PCA(n_components=2)
X_2d = pca2.fit_transform(X_esc)
plt.scatter(X_2d[:, 0], X_2d[:, 1], c=rfm["segmento"], cmap="tab10", s=15)
plt.xlabel(f"PC1 ({pca2.explained_variance_ratio_[0]:.0%} var.)")
plt.ylabel(f"PC2 ({pca2.explained_variance_ratio_[1]:.0%} var.)")
plt.title("Segmentos K-means de MercaFresh en el plano PCA")
plt.colorbar(label="segmento")
plt.show()Coloreamos cada punto por el segmento que K-means le asignó (c=rfm["segmento"]). Si los cuatro colores aparecen en zonas razonablemente diferenciadas del plano, tenemos confirmación visual de que los segmentos son regiones reales del espacio de clientes. Con un matiz honesto: el plano solo muestra el 73% de la varianza — dos clusters que se solapen en el dibujo pueden estar separados en la dimensión que el plano no muestra. La proyección es un mapa, no el territorio.
Interpretar componentes: los loadings
PC1 y PC2 son mezclas de features. ¿Qué significan? La respuesta está en los loadings: los pesos con que cada feature original entra en cada componente, disponibles en pca.components_.
import pandas as pd
loadings = pd.DataFrame(pca2.components_.T,
columns=["PC1", "PC2"], index=features).round(2)
print(loadings)| Feature | PC1 | PC2 |
|---|---|---|
| recencia_dias | 0,45 | 0,21 |
| pedidos_por_mes | −0,44 | 0,25 |
| gasto_medio_pedido | −0,12 | 0,62 |
| gasto_total | −0,41 | 0,48 |
| num_pedidos | −0,43 | 0,18 |
| ratio_inactividad | 0,47 | 0,15 |
| tendencia | −0,11 | −0,50 |
Cómo se leen (signos y valores son ilustrativos):
- PC1 enfrenta recencia y ratio de inactividad (pesos positivos) contra frecuencia y volumen (negativos): es un eje de actividad, de "cliente vivo" (PC1 muy negativo) a "cliente apagado" (PC1 muy positivo). No sorprende que los segmentos "VIP" y "dormidos" de 05-01 ocupen extremos opuestos de este eje.
- PC2 carga sobre gasto medio y total con signo positivo y tendencia con negativo: un eje de valor del ticket, que separa a los habituales de ticket alto de los ocasionales baratos.
- El signo global de una componente es arbitrario (el eje puede apuntar hacia cualquiera de sus dos sentidos); lo interpretable son los signos relativos entre features y la magnitud de los pesos.
Con los loadings, los ejes del scatter dejan de ser abstractos: el mapa de clientes tiene un eje horizontal "actividad" y uno vertical "valor" — vocabulario que negocio entiende.
PCA como paso previo a modelos
Además de visualizar, PCA se usa como preprocesamiento: entrenar el modelo sobre las k primeras componentes en lugar de las features originales. Beneficios: menos dimensiones (alivia la maldición para K-NN o K-means), sin colinealidad (las PCs no están correlacionadas) y menos ruido (las últimas componentes suelen ser ruido y se descartan). Se integra en el Pipeline que ya conoces del módulo 4:
from sklearn.pipeline import Pipeline
from sklearn.cluster import KMeans
pipe = Pipeline([
("escala", StandardScaler()),
("pca", PCA(n_components=0.90)), # PCs hasta el 90% de varianza
("kmeans", KMeans(n_clusters=4, random_state=42)),
])
etiquetas = pipe.fit_predict(X)El orden importa y ya lo puedes justificar entero: escalar (para que PCA no herede las unidades) → PCA (para que K-means trabaje con pocas dimensiones informativas) → clustering. La contrapartida: los centroides quedan expresados en componentes, y para perfilarlos en unidades de negocio hay que deshacer las dos transformaciones (inverse_transform de PCA y del scaler, encadenados).
Limitaciones, y PCA vs. selección de features (03-06)
Limitaciones de PCA:
- Es lineal. Solo encuentra rotaciones: si la estructura de los datos es curva (una espiral, un manifold retorcido), ninguna rotación la despliega. Para visualizar estructura no lineal existen t-SNE y UMAP (05-05).
- Interpretabilidad. "PC1 = 0,45·recencia − 0,44·frecuencia + ..." nunca será tan transparente como una feature original. Los loadings ayudan, pero explicar un modelo entrenado sobre PCs a un comité de negocio cuesta más.
- Varianza ≠ relevancia. PCA conserva las direcciones de mayor varianza sin saber para qué usarás los datos: en un problema supervisado, la señal que separa las clases podría vivir en una componente de poca varianza que descartaste. Es no supervisado también en ese sentido: ignora cualquier
y. - Hereda la sensibilidad a outliers de la varianza (02-01): un cliente extremo puede torcer una componente entera. Limpieza (03-01) o log (03-03) antes.
Y una distinción conceptual importante con lo visto en 03-06:
| Selección de features (03-06) | PCA (compresión) | |
|---|---|---|
| Qué hace | Elige un subconjunto de columnas originales | Crea columnas nuevas mezclando todas |
| Las descartadas | Desaparecen del modelo | Su información puede sobrevivir mezclada en las PCs |
| Interpretabilidad | Total: las columnas siguen siendo recencia_dias, etc. |
Parcial: ejes abstractos, interpretados vía loadings |
| Cuándo preferir | Features irrelevantes o interpretabilidad prioritaria | Features redundantes/correlacionadas entre sí |
No compiten: a menudo se seleccionan primero las features con sentido y se comprime después la redundancia restante.
Errores Comunes y Consejos
- PCA sin estandarizar. La feature de mayor varianza (por unidades) secuestra PC1 y la reducción es un espejismo.
StandardScalerprimero, siempre — salvo el caso raro de features ya en unidades comparables por naturaleza. - Quedarse con 2 componentes porque el scatter es bonito. Dos PCs son para visualizar; para modelar, decide con la varianza acumulada o el scree plot. Visualización y compresión son usos distintos con criterios distintos.
- Interpretar el signo absoluto de una componente. Reejecuta en otra máquina y PC1 puede salir con todos los signos invertidos: es el mismo eje. Interpreta pesos relativos.
- Sobre-leer el scatter 2D. Que dos segmentos se toquen en el plano no prueba que se toquen en el espacio completo: puede faltar justo la dimensión que los separa.
- Consejo: etiqueta siempre los ejes del scatter con su % de varianza (
PC1 (46%)); te obliga a ti y avisa al lector de cuánta información falta en el dibujo.
Ejercicios
Ejercicio 1. Sin código: tienes dos features estandarizadas con correlación 0,95. (a) ¿Qué fracción aproximada de la varianza explicará PC1 y por qué? (b) ¿Y si la correlación fuera 0? (c) ¿Qué implica cada caso para comprimir a 1 dimensión? Pista: con dos variables estandarizadas, la varianza explicada por PC1 es $(1+|r|)/2$.
Ejercicio 2. Aplica PCA a las 7 features de clientes de la lección (o genera un dataset sintético correlacionado). Dibuja el scree plot y la varianza acumulada, y decide cuántas componentes conservarías para (a) visualizar y (b) alimentar un K-means manteniendo el 90% de la varianza. Justifica ambas respuestas.
Ejercicio 3. Toma los loadings de PC1 de tu ejecución del ejercicio 2 y redacta en una frase, en lenguaje de negocio de MercaFresh, qué mide ese eje. Después calcula la correlación de Pearson (02-03) entre la proyección PC1 de cada cliente y su ratio_inactividad, y explica el resultado.
Soluciones
Ejercicio 1
(a) Con $r = 0{,}95$: PC1 explica $(1+0{,}95)/2 = 97{,}5%$. La nube es una elipse casi degenerada en una recta; casi toda la variación ocurre a lo largo de la diagonal. (b) Con $r = 0$: cada PC explica el 50% — la nube es circular y no existe ninguna dirección privilegiada; PCA no tiene nada que comprimir. (c) En el primer caso, reducir a 1D pierde un 2,5% de información: compresión excelente. En el segundo, pierde la mitad: inaceptable. Moraleja: PCA comprime redundancia; sin correlaciones no hay compresión posible — por eso el heatmap de 02-03 es un buen diagnóstico previo de si PCA merecerá la pena.
Ejercicio 2
pca = PCA().fit(X_esc)
var = pca.explained_variance_ratio_
plt.subplot(1, 2, 1); plt.plot(range(1, len(var)+1), var, "o-")
plt.xlabel("PC"); plt.ylabel("Varianza explicada")
plt.subplot(1, 2, 2); plt.plot(range(1, len(var)+1), np.cumsum(var), "o-")
plt.axhline(0.90, ls="--", c="gray")
plt.xlabel("PCs acumuladas"); plt.ylabel("Varianza acumulada")
plt.show()(a) Para visualizar: 2 componentes, obligatoriamente — un scatter tiene dos ejes; la pregunta relevante es cuánta varianza acumulan (aquí ~73%: aceptable, con la cautela de la lección). (b) Para K-means: donde la acumulada cruce 0,90 — típicamente 4 componentes en este dataset. PCA(n_components=0.90) lo automatiza. Nota que las respuestas difieren: el criterio depende del uso.
Ejercicio 3
Frase tipo: "PC1 mide el grado de apagado del cliente: valores altos = mucho tiempo sin comprar y alta inactividad relativa; valores bajos = cliente frecuente y voluminoso". La correlación entre PC1 y ratio_inactividad sale fuertemente positiva (en torno a +0,8/+0,9): es coherente, porque ratio_inactividad tiene uno de los mayores loadings positivos de PC1, y la proyección de cada cliente sobre el eje hereda esa relación. Comprobar los loadings contra correlaciones simples es una forma rápida de validar tu lectura del eje.
Conclusión
Has añadido al arsenal la herramienta que domestica la dimensionalidad: PCA rota los ejes hacia las direcciones de máxima varianza, convierte features correlacionadas en componentes independientes y ordenadas por importancia, y te deja elegir cuántas conservar con la varianza explicada y el scree plot. Sabes por qué exige estandarizar (hereda las unidades vía la covarianza de 02-03), sabes leer loadings para dar nombre de negocio a cada eje, y has visto sus dos oficios en MercaFresh: mapa 2D de los segmentos de K-means y compresor previo al modelado — sin confundirlo nunca con la selección de features de 03-06, porque PCA no elige columnas: las mezcla.
Pero PCA arrastra su límite de fábrica: es una rotación, y las rotaciones son lineales. En la siguiente lección conocerás un algoritmo que no necesita que los grupos sean esferas ni que la estructura sea recta: DBSCAN agrupa por densidad, encuentra clusters con cualquier forma y —lo que más le interesa a MercaFresh— señala explícitamente los puntos que no encajan en ninguno: los pedidos anómalos.
Curso de Machine Learning
Módulo 1: Introducción al Machine Learning
- ¿Qué es el Machine Learning?
- Historia y evolución del Machine Learning
- Tipos de Machine Learning
- Aplicaciones del Machine Learning
- El flujo de trabajo de un proyecto de Machine Learning
Módulo 2: Fundamentos de Estadística y Probabilidad
- Conceptos básicos de estadística
- Distribuciones de probabilidad
- Correlación y covarianza
- Inferencia estadística
- Teorema de Bayes
Módulo 3: Preprocesamiento de Datos
- Limpieza de datos
- Manejo de datos faltantes
- Transformación de datos
- Codificación de variables categóricas
- Normalización y estandarización
- Ingeniería de características
Módulo 4: Algoritmos de Machine Learning Supervisado
- Regresión lineal
- Regresión logística
- Árboles de decisión
- Máquinas de soporte vectorial (SVM)
- K-Vecinos más cercanos (K-NN)
- Naive Bayes
- Redes neuronales
Módulo 5: Algoritmos de Machine Learning No Supervisado
- Clustering: K-means
- Clustering jerárquico
- Análisis de componentes principales (PCA)
- Análisis de agrupamiento DBSCAN
- Visualización de datos con t-SNE y UMAP
Módulo 6: Evaluación y Validación de Modelos
- División de datos: entrenamiento, validación y prueba
- Métricas de evaluación
- Validación cruzada
- Curva ROC y AUC
- Overfitting y underfitting
Módulo 7: Técnicas Avanzadas y Optimización
- Regularización: Ridge, Lasso y Elastic Net
- Ensemble Learning
- Gradient Boosting
- Redes neuronales profundas (Deep Learning)
- Optimización de hiperparámetros
Módulo 8: Implementación y Despliegue de Modelos
- Frameworks y bibliotecas populares
- Implementación de modelos en producción
- Mantenimiento y monitoreo de modelos
- Consideraciones éticas y de privacidad
Módulo 9: Proyectos Prácticos
- Proyecto 1: Predicción de precios de viviendas
- Proyecto 2: Clasificación de imágenes
- Proyecto 3: Análisis de sentimientos en redes sociales
- Proyecto 4: Detección de fraudes
- Proyecto 5: Segmentación de clientes
