Resumen

Entiende con claridad cómo la matriz de covarianza resume la estructura de tus datos y cómo los eigenvectores señalan las direcciones de máxima información. Con ejemplos prácticos en NumPy y Matplotlib, verás por qué este análisis es clave para PCA y reducción de dimensión.

¿Qué es y cómo interpretar la matriz de covarianza?

La matriz de covarianza es un resumen estadístico cuadrado que captura la historia de tus características. En la diagonal aparecen las varianzas: miden la dispersión de cada característica frente a su media. Fuera de la diagonal están las covarianzas: indican cómo varían juntas dos características.

  • Covarianza positiva: si una sube, la otra tiende a subir. La nube forma una elipse que asciende hacia la derecha.
  • Covarianza negativa: si una sube, la otra tiende a bajar. La elipse desciende hacia la derecha.
  • Covarianza cercana a cero: no hay relación lineal clara. La nube luce casi circular.

En el ejemplo con “horas de estudio” y “calificación”, la diagonal mostró varianzas aproximadas de 7.5 y 126.7, y una covarianza fuera de la diagonal de alrededor de 30.3: fuerte relación positiva. En “horas de videojuegos” y “calificación”, las varianzas fueron 11.06 y 180.66 y la covarianza negativa fue grande en magnitud: relación inversa marcada. En datos aleatorios, la covarianza fuera de la diagonal es cercana a cero: no hay relación.

La clave aparece con los eigenvalores y eigenvectores de la matriz de covarianza: los eigenvectores marcan las direcciones de máxima varianza y los eigenvalores cuantifican su “longitud” o importancia. El eje con mayor eigenvalor captura la mayor parte de la información; el menor suele recoger ruido.

¿Cómo implementarlo con NumPy y Matplotlib paso a paso?

A continuación, se muestra cómo calcular la matriz de covarianza, obtener sus eigenvalores y eigenvectores, ordenarlos por importancia y visualizarlos con scatter plot y flechas con quiver. Se centra la matriz de datos para una visualización más clara. También se ilustran tres casos: covarianza positiva, negativa y cercana a cero.

import numpy as np
import matplotlib.pyplot as plt

# Función para analizar y graficar
def analizar_graficar(ax, datos, titulo, feature_names):
    # 1) Matriz de covarianza (columnas como variables)
    matriz_cov = np.cov(datos, rowvar=False)

    # 2) Eigenvalores y eigenvectores
    eigenvalores, eigenvectores = np.linalg.eig(matriz_cov)

    # 3) Orden descendente por importancia
    idx = np.argsort(eigenvalores)[::-1]
    eigenvalores = eigenvalores[idx]
    eigenvectores = eigenvectores[:, idx]

    # 4) Centrado de datos (para graficar)
    datos_centrados = datos - np.mean(datos, axis=0)

    # 5) Dispersión
    ax.scatter(datos_centrados[:, 0], datos_centrados[:, 1], alpha=0.7)

    # 6) Flechas de los ejes principales
    for i in range(len(eigenvalores)):
        eigenvector = eigenvectores[:, i]
        longitud = np.sqrt(eigenvalores[i])  # desviación estándar
        ax.quiver(
            0, 0,
            eigenvector[0] * longitud,
            eigenvector[1] * longitud,
            angles='xy', scale_units='xy', scale=1,
            color=f'C{i+2}', width=0.015,
            label=f'eje {i+1} (eigenvalor {eigenvalores[i]:.1f})'
        )

    # 7) Etiquetas y título
    ax.set_title(titulo)
    ax.set_xlabel(f'{feature_names[0]}')
    ax.set_ylabel(f'{feature_names[1]}')
    ax.legend()

    return matriz_cov

# Datos con covarianza positiva (horas de estudio vs calificación)
datos_pos = np.array([
    [2, 65],
    [3, 70],
    [5, 75],
    [6, 85],
    [8, 88],
    [9, 94],
])

# Datos con covarianza negativa (horas de videojuegos vs calificación)
datos_neg = np.array([
    [10, 60],
    [8, 70],
    [7, 72],
    [5, 85],
    [3, 90],
    [1, 95],
])

# Datos sin relación (aleatorios)
np.random.seed(42)  # *seed* reproducible
datos_cero = np.random.randn(100, 2) * np.array([10.0, 5.0])

# Subgráficos
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(21, 7))

cov_pos = analizar_graficar(ax1, datos_pos, 'covarianza positiva', ['horas de estudio', 'calificaciones'])
cov_neg = analizar_graficar(ax2, datos_neg, 'covarianza negativa', ['horas de videojuegos', 'calificaciones'])
cov_cero = analizar_graficar(ax3, datos_cero, 'sin covarianza', ['característica 1', 'característica 2'])

plt.show()

print('Matriz de covarianza (positiva):')
print(cov_pos)
print('Matriz de covarianza (negativa):')
print(cov_neg)
print('Matriz de covarianza (cero):')
print(cov_cero)

¿Cómo se calcula la matriz de covarianza y sus eigenvalores?

  • Usa np.cov con rowvar=False para tratar columnas como variables.
  • Aplica np.linalg.eig a la matriz de covarianza.
  • Interpreta los eigenvalores como magnitudes de varianza por dirección.

¿Cómo ordenar e interpretar las direcciones?

  • Ordena con np.argsort en descendente para priorizar direcciones informativas.
  • El primer eigenvector indica la dirección de máxima varianza.
  • La raíz del eigenvalor da la desviación estándar para escalar la flecha.

¿Cómo visualizar los datos y los ejes principales?

  • Centra los datos restando la media por columna.
  • Grafica dispersión con alpha para ver densidad.
  • Dibuja con quiver los ejes principales y compara su longitud.

¿Para qué sirve en PCA y reducción de dimensión?

El análisis mostró que el eigenvector principal (flecha verde) sigue la dirección de máxima información y el segundo (rojo) suele capturar ruido. PCA se apoya en esto: si el primer eje acumula casi toda la varianza, puedes proyectar los datos en ese eje y reducir de dos dimensiones a una, casi sin perder información relevante.

Prueba ahora con un caso con fuerte covarianza positiva: “años de experiencia” y “salario”. Si la varianza del salario es mucho mayor que la de experiencia, ¿la elipse será más vertical u horizontal? ¿hacia dónde apuntará el eigenvector principal? Comparte tus resultados y tu interpretación en los comentarios.