PCA desde cero con NumPy: implementación completa
Clase 6 de 12 • Curso Avanzado de Álgebra Lineal y Machine Learning: PCA y SVD
Contenido del curso
Eigen-Análisis
Reducción de Dimensionalidad con PCA
Descomposición en Valores Singulares (SVD)
Aprende a implementar PCA desde cero con NumPy y a validar los resultados con Scikit-learn. En cuatro pasos claros: estandarizar, calcular la matriz de covarianza, hacer eigenanálisis y proyectar los datos a menos dimensiones. Además, verás cómo graficar los componentes y qué significa la ambigüedad de signo en los eigenvectores.
¿Cómo ejecutar PCA desde cero y qué resultados esperar?
El flujo central une fundamentos numéricos y manipulación matricial. Se trabaja en Google Colab, con NumPy y Matplotlib, y se contrasta con el PCA de Scikit-learn aplicando la misma estandarización para asegurar comparabilidad.
- Paso 1: estandarizar los datos. Centrar con media cero y escalar con desviación estándar por columna.
- Paso 2: matriz de covarianza. Describe forma y orientación de los datos.
- Paso 3: eigenanálisis. Obtener eigenvalores y eigenvectores; ordenar de mayor a menor varianza con argsort descendente.
- Paso 4: proyección. Multiplicar datos estandarizados por los eigenvectores principales para obtener los componentes.
- Validación: comparar contra PCA de Scikit-learn tras estandarizar con StandardScaler.
- Visualización: dispersión 2D de ambos resultados para confirmar equivalencia.
¿Cómo se implementa la función y se valida con Scikit-learn?
A continuación, el esqueleto en Python que traduce el proceso a código y el contraste con la librería.
¿Cómo se escribe la función pca_desde_cero en Python?
import numpy as np
def pca_desde_cero(X, n_componentes):
# Paso 1: estandarización
X_centrado = X - np.mean(X, axis=0)
X_estandarizado = X_centrado / np.std(X, axis=0)
# Paso 2: matriz de covarianza (columnas como variables)
matriz_cov = np.cov(X_estandarizado, rowvar=False)
# Paso 3: eigenanálisis y orden descendente
eigenvalores, eigenvectores = np.linalg.eig(matriz_cov)
idx_orden = np.argsort(eigenvalores)[::-1]
eigenvectores_ordenados = eigenvectores[:, idx_orden]
# Paso 4: proyección a k dimensiones
componentes_principales = eigenvectores_ordenados[:, :n_componentes]
X_proyectado = X_estandarizado @ componentes_principales
return X_proyectado
¿Cómo crear datos 3D y comparar con Scikit-learn?
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
# Supón que X, G y Z son vectores columna creados previamente
# (por ejemplo, en la sesión anterior)
datos_3D = np.column_stack((X, G, Z))
# Nuestro PCA desde cero
datos_pca_nuestro = pca_desde_cero(datos_3D, n_componentes=2)
# PCA de Scikit-learn con estandarización equivalente
scaler = StandardScaler()
datos_escalados_sklearn = scaler.fit_transform(datos_3D)
pca_sklearn = PCA(n_components=2)
datos_pca_sklearn = pca_sklearn.fit_transform(datos_escalados_sklearn)
# Comparación rápida (primeras 5 filas, redondeadas)
print("Resultados de nuestro PCA:\n", np.round(datos_pca_nuestro[:5], 2))
print("Resultados de PCA de Scikit-learn:\n", np.round(datos_pca_sklearn[:5], 2))
¿Cómo visualizar ambos resultados en 2D?
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6))
ax1.scatter(datos_pca_nuestro[:, 0], datos_pca_nuestro[:, 1], alpha=0.7)
ax1.set_title("Nuestro PCA")
ax2.scatter(datos_pca_sklearn[:, 0], datos_pca_sklearn[:, 1], alpha=0.7)
ax2.set_title("PCA de Scikit-learn")
plt.suptitle("Validación de nuestro PCA versus Scikit-learn")
plt.show()
¿Qué conceptos clave debes dominar y qué errores evitar?
Dominar estos elementos asegura que la implementación sea correcta y comparable.
- Estandarización consistente. Si tu función centra y escala, aplica lo mismo antes de fit_transform en la librería; de lo contrario, los números se verán distintos aunque el método sea correcto.
- Matriz de covarianza con rowvar=False. Indica que las variables están en columnas.
- Orden descendente de eigenvalores. Usa argsort invertido para priorizar ejes de mayor varianza.
- Selección de componentes con slicing. eigenvectores_ordenados[:, :k] devuelve los k ejes principales.
- Producto matriz-matriz. La proyección es X_estandarizado @ componentes_principales.
- Ambigüedad de signo en eigenvectores. Un eje y su opuesto (v y −v) representan la misma dirección; que difieran los signos no implica error en PCA.
- Buenas prácticas de visualización. Dispersión 2D con títulos claros y alfa moderado para comparar densidades.
Habilidades practicadas: manipulación de matrices con NumPy, cálculo de desviación estándar, covarianza y eigenanálisis, ordenamiento con argsort, slicing avanzado, comparación con Scikit-learn y gráficos con Matplotlib.
Propuesta de práctica: crea una matriz con más de tres dimensiones, aplica el PCA desde cero y el de Scikit-learn, reduce a las dimensiones que prefieras y compara visualmente. ¿Te animas a compartir tus resultados y hallazgos en los comentarios?