Algoritmo de Subespacios y Rangos
Una guía completa que cubre la teoría, la implementación en Python y las mejores prácticas para trabajar con subespacios vectoriales y rangos de matrices.
Introducción
Los subespacios y el rango de una matriz son conceptos centrales en álgebra lineal y aparecen en áreas como la visión por computadora, procesamiento de señales, aprendizaje automático y análisis de datos. Este artículo explica:
- Qué es un subespacio y cómo se define formalmente.
- Cómo se calcula el rango de una matriz y por qué es importante.
- Implementación paso‑a‑paso en
Pythonusandonumpyyscipy. - Comparativas con técnicas relacionadas como PCA y SVD.
- Consejos de rendimiento, seguridad y troubleshooting.
Fundamentos Teóricos
Sea A ∈ ℝm×n. Un subespacio de ℝn es cualquier conjunto cerrado bajo suma y multiplicación por escalar. Los subespacios más relevantes asociados a A son:
- Column space (C(A)): conjunto de combinaciones lineales de las columnas de A.
- Row space (R(A)): conjunto de combinaciones lineales de las filas de A.
El rango de A, denotado rank(A), es la dimensión del column space (o del row space, ambas dimensiones coinciden). Se pueden obtener mediante:
- El número de pivotes después de la eliminación de Gauss‑Jordan.
- El número de valores singulares no nulos en la descomposición SVD.
Propiedades clave:
- rank(A) ≤ min(m, n).
- Si rank(A) = n, las columnas son linealmente independientes y forman una base del espacio ℝn.
Implementación en Python
Usaremos numpy para operaciones básicas y scipy.linalg para la SVD robusta.
import numpy as np
from scipy.linalg import svd
# Matriz de ejemplo (m=4, n=3)
A = np.array([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
], dtype=float)
# 1️⃣ Rango mediante eliminación gaussiana (numpy.linalg.matrix_rank)
rank_gauss = np.linalg.matrix_rank(A)
print("Rango (Gauss):", rank_gauss)
# 2️⃣ Rango mediante SVD (número de valores singulares > eps)
U, s, Vh = svd(A, full_matrices=False)
# Umbral de tolerancia (criterio de NumPy)
eps = np.finfo(s.dtype).eps * max(A.shape) * s[0]
rank_svd = np.sum(s > eps)
print("Rango (SVD):", rank_svd)
# 3️⃣ Bases de los subespacios columna y fila
# - Column space (usando los vectores singulares izquierdos correspondientes a s>0)
col_basis = U[:, s > eps]
# - Row space (usando los vectores singulares derechos)
row_basis = Vh[s > eps, :]
print("Base del column space:\n", col_basis)
print("Base del row space:\n", row_basis)
Salida esperada:
Rango (Gauss): 2
Rango (SVD): 2
Base del column space:
[[-0.140...]
[-0.342...]
[-0.544...]
[-0.746...]]
Base del row space:
[[-0.504... -0.574... -0.644...]]
Observa que el rango es 2, aunque la matriz tiene 3 columnas; la tercera columna es combinación lineal de las dos primeras.
Comparativa con PCA, SVD y otras técnicas de reducción dimensional
Algoritmo de Subespacios (Rank)
- Objetivo: determinar la dimensionalidad real del espacio generado por los datos.
- Salida: número entero (rango) + bases opcionales.
- Complejidad: O(min(m,n)·max(m,n)²) con SVD; O(m·n·min(m,n)) con eliminación gaussiana.
- Uso típico: verificación de colinealidad, cálculo de nulidad, diagnóstico de sistemas lineales.
PCA (Análisis de Componentes Principales)
- Objetivo: transformar datos a un nuevo sistema de coordenadas que maximiza la varianza.
- Salida: componentes principales (vectores) y varianzas explicadas.
- Complejidad: O(m·n²) (usualmente SVD de la matriz centrada).
- Uso típico: reducción de dimensionalidad para aprendizaje automático.
En resumen, el cálculo del rango es una operación de diagnóstico, mientras que PCA y SVD buscan una representación más compacta y orientada a la varianza de los datos.
Buenas Prácticas, Optimización y Seguridad
Rendimiento
- Usar
numpy.linalg.matrix_rankcuando sólo necesitas el rango; esta función ya aplica un umbral inteligente. - Para matrices muy grandes (10⁶ elementos), emplea
scipy.sparse.linalg.svdsque trabaja con matrices dispersas y devuelve sólo los k valores singulares más grandes. - Si el hardware dispone de GPU,
cupyotorch.linalgpueden acelerar la SVD.
Seguridad y Validación de Entrada
- Valida que la matriz sea numérica (
np.isfinite) antes de ejecutar la SVD para evitar NaN o inf que provocan excepciones. - Controla el tipo de dato (
float64recomendado) para evitar pérdida de precisión en valores singulares muy pequeños.
Debugging y Troubleshooting
- Problema:
np.linalg.matrix_rankdevuelve un rango menor al esperado.- Solución: revisar la tolerancia con
np.linalg.matrix_rank(A, tol=1e-10)o escalar la matriz.
- Solución: revisar la tolerancia con
- Problema: SVD falla con
LinAlgError: SVD did not converge.- Solución: usar
scipy.linalg.svdconlapack_driver='gesdd'o aplicar una ligera regularización (A + epsilon*I).
- Solución: usar
Casos de Uso Reales
- Ingeniería de Control: Verificar la controllabilidad y observabilidad de sistemas lineales mediante el rango de matrices de controllabilidad/observabilidad.
- Procesamiento de Señales: Detectar redundancia en canales de sensores; si el rango es menor que el número de sensores, hay información duplicada.
- Machine Learning: Pre‑filtrado de características: eliminar columnas linealmente dependientes antes de entrenar modelos.
Conclusión
El algoritmo de subespacios y el cálculo del rango son herramientas esenciales para comprender la estructura lineal de los datos. Con numpy y scipy disponemos de implementaciones rápidas, fiables y escalables. Aplicar buenas prácticas de validación, tolerancia y uso de versiones dispersas garantiza un rendimiento óptimo incluso en entornos de producción.
Algoritmo de Subespacios y Rangos: Fundamentos, Implementación en Python y Buenas Prácticas