Normas de vectores: Algoritmo, teoría y ejemplos en Python
Aprende qué son las normas de un vector, cómo calcularlas de forma eficiente y cómo aplicarlas en proyectos reales de ciencia de datos y desarrollo de software.
1. Introducción a las normas de un vector
En matemáticas y en áreas como Machine Learning, optimización o simulaciones, la norma de un vector es una medida de su longitud o magnitud. Formalmente, una norma \(\|\cdot\|\) es una función que asigna a cada vector \(\mathbf{x}\in\mathbb{R}^n\) un número real no negativo cumpliendo tres axiomas:
- Positividad: \(\|\mathbf{x}\| \ge 0\) y \(\|\mathbf{x}\| = 0 \iff \mathbf{x}=\mathbf{0}\).
- Homogeneidad: \(\|\alpha\mathbf{x}\| = |\alpha|\,\|\mathbf{x}\|\) para cualquier escalar \(\alpha\).
- Desigualdad triangular: \(\|\mathbf{x}+\mathbf{y}\| \le \|\mathbf{x}\| + \|\mathbf{y}\|\).
2. Tipos de normas más usadas
L1 (norma Manhattan)
\[\|\mathbf{x}\|_1 = \sum_{i=1}^{n} |x_i|\]
- Robusta ante valores atípicos.
- Frecuente en regularización Lasso.
L2 (norma Euclidiana)
\[\|\mathbf{x}\|_2 = \sqrt{\sum_{i=1}^{n} x_i^2}\]
- Representa la distancia geométrica tradicional.
- Base de la regularización Ridge y de la mayoría de algoritmos de clustering.
L∞ (norma del máximo)
\[\|\mathbf{x}\|_{\infty} = \max_i |x_i|\]
- Útil cuando el peor caso es crítico (por ejemplo, en análisis de estabilidad).
P‑norm (norma generalizada)
\[\|\mathbf{x}\|_p = \left(\sum_{i=1}^{n} |x_i|^p\right)^{1/p},\quad p\ge 1\]
- Permite ajustar la sensibilidad a valores grandes o pequeños variando p.
3. Algoritmo genérico para calcular una p‑norm
def p_norm(vector, p=2):
"""Calcula la p‑norma de un vector iterable.
Args:
vector (Iterable[float]): componentes del vector.
p (float): orden de la norma (p≥1). El valor 2 corresponde a la norma Euclidiana.
Returns:
float: valor de la p‑norma.
"""
if p < 1:
raise ValueError("p debe ser >= 1")
total = sum(abs(x) ** p for x in vector)
return total ** (1.0 / p)
El algoritmo anterior es sencillo, pero tiene limitaciones de rendimiento para vectores muy grandes o cuando se necesita precisión de punto flotante alta.
4. Implementaciones en Python: Pure vs. NumPy
4.1 Pure Python (para vectores pequeños)
import random, time
vec = [random.random() for _ in range(1000)]
start = time.time()
print('L2:', p_norm(vec, p=2))
print('Tiempo:', time.time() - start)
4.2 NumPy (optimizado con C‑loops)
import numpy as np, time
vec_np = np.random.rand(1_000_000)
start = time.time()
print('L2 (NumPy):', np.linalg.norm(vec_np, ord=2))
print('Tiempo (NumPy):', time.time() - start)
En pruebas típicas, np.linalg.norm supera a la versión pura en más de 10× para vectores con más de 10⁵ elementos.
Recomendación: Usa siempre NumPy o bibliotecas basadas en C/Fortran para cálculos de gran escala. La versión pura es útil para enseñanza o entornos sin dependencias externas.
5. Comparativa de rendimiento (benchmark)
| Tamaño del vector | Pure Python (ms) | NumPy (ms) | Speed‑up |
|---|---|---|---|
| 1 000 | 0.8 | 0.06 | ≈13× |
| 10 000 | 7.4 | 0.45 | ≈16× |
| 100 000 | 78 | 4.2 | ≈19× |
| 1 000 000 | 800 | 38 | ≈21× |
Los resultados pueden variar según la arquitectura CPU y la versión de BLAS vinculada a NumPy.
6. Casos de uso reales
- Regularización en modelos lineales: L1 para Lasso, L2 para Ridge.
- Clustering K‑means: se basa en la distancia Euclidiana (L2).
- Detección de anomalías: la norma L∞ permite identificar la característica más desviada.
- Redes neuronales y embeddings: normalizar vectores de embedding con L2 antes de calcular similitudes de coseno.
7. Buenas prácticas y consideraciones de seguridad numérica
- Evita overflow/underflow: Cuando los componentes son muy grandes, calcula la norma usando
np.linalg.normcondtype=np.float64o escala el vector antes de la suma. - Precisión de punto flotante: En entornos críticos (finanzas, simulaciones científicas) prefiere
Decimalo bibliotecas de precisión arbitraria. - Vectorización: Siempre que sea posible, utiliza operaciones vectorizadas (NumPy, JAX, PyTorch) para aprovechar SIMD y GPU.
- Validación de entrada: Asegúrate de que la entrada sea un iterable de números; rechaza NaN o Inf con una excepción clara.
8. Troubleshooting frecuente
8.1 Resultado inesperado con NaN
Si np.linalg.norm devuelve nan, verifica que el vector no contenga np.nan o np.inf. Usa np.isfinite() para filtrar.
if not np.all(np.isfinite(vec)):
raise ValueError('El vector contiene valores no finitos')
8.2 Diferencias entre ord=2 y ord=None
En NumPy, ord=None calcula la norma Frobenius (para matrices) que equivale a la L2 vectorial cuando la entrada es 1‑D. Asegúrate de especificar ord=2 para evitar ambigüedad.
9. Optimización avanzada
Para entornos de alto rendimiento (HPC) o entrenamiento de modelos con miles de millones de parámetros, considera:
- JAX:
jax.numpy.linalg.normcompila a XLA y ejecuta en GPU/TPU. - PyTorch:
torch.normcondimespecificado permite cálculos en lotes sin bucles de Python. - Numba: Decorar la función
p_normcon@njitpara generar código máquina nativo.
from numba import njit
@njit
def p_norm_numba(arr, p=2):
total = 0.0
for x in arr:
total += abs(x) ** p
return total ** (1.0 / p)
Normas de vectores: Algoritmo, teoría y ejemplos prácticos en Python