Las lecciones anteriores operaron sobre vectores y matrices dando por supuesto qué son. Este módulo establece la definición. No es un formalismo prescindible: es lo que explica por qué las mismas técnicas se aplican a listas de números, a polinomios y a las representaciones internas de un modelo de lenguaje.
La definición
Un espacio vectorial sobre es un conjunto con dos operaciones, una suma y un producto por escalar , que satisfacen ocho condiciones. Para todos y :
Los elementos de se llaman vectores, con independencia de su naturaleza. La definición no menciona flechas, listas ni coordenadas.
En , realizado en NumPy como un ndarray unidimensional, las ocho se heredan de las propiedades de los números reales y son comprobables directamente:
import numpy as np
u = np.array([1., 2., 3.])
v = np.array([4., 5., 6.])
np.allclose(u + v, v + u) # conmutativa
np.allclose(3 * (u + v), 3 * u + 3 * v) # distributiva
np.allclose(u + np.zeros(3), u) # elemento neutro
Cerradura y vectorización
Las dos primeras condiciones de la definición, antes de los axiomas, son que la suma y el producto por escalar devuelvan elementos de . Esa propiedad se denomina cerradura, y en NumPy se manifiesta en la forma del resultado:
(u + v).shape == (3 * u).shape == u.shape # True
La consecuencia es de implementación, no solo de notación. Como el resultado pertenece al mismo espacio y tiene el mismo tipo y la misma forma, la operación puede compilarse en un único bucle tipado sobre un bloque contiguo de memoria, sin decidir nada en cada elemento. Eso es lo que se denomina vectorización, y es la razón de que u + v sea entre uno y dos órdenes de magnitud más rápido que el bucle equivalente en Python.
La cerradura algebraica y la eficiencia de la biblioteca no son hechos independientes: la segunda es posible porque se cumple la primera.
Combinaciones lineales y span
La operación central del álgebra lineal combina ambas: escalar varios vectores y sumarlos.
Disponiendo los vectores como columnas de una matriz, la combinación es un producto matriz-vector:
V = np.column_stack([u, v]) # (3, 2)
c = np.array([2., -1.])
V @ c # array([-2., -1., 0.]) = 2u − v
La identificación merece enunciarse con claridad: el producto es la combinación lineal de las columnas de con coeficientes . Es la lectura que convierte en la pregunta de qué combinación de las columnas de produce .
El conjunto de todas las combinaciones lineales posibles se denomina span:
Aplicado a las columnas de una matriz, recibe el nombre de espacio columna, y es exactamente el conjunto de vectores para los que tiene solución.
Subespacios
Un subconjunto es un subespacio si es a su vez un espacio vectorial con las mismas operaciones. No hace falta verificar los ocho axiomas: se heredan de . Basta comprobar tres condiciones:
La figura aplica el criterio a varios subconjuntos de :
- contiene al 0
- cerrado bajo la suma
- cerrado bajo el producto por escalar
es un subespacio
Cada fallo ilustra una condición distinta. La recta desplazada no contiene al origen. El primer cuadrante lo contiene y es cerrado bajo la suma, pero multiplicar por lo abandona. La parábola contiene al origen y falla en las otras dos: y pertenecen a ella y su suma no, y duplicar produce , que tampoco.
Los subespacios de son, en consecuencia, únicamente , las rectas que pasan por el origen y completo. Un subespacio contiene siempre al origen, y esa es la diferencia con el conjunto solución de descrito en la lección sobre solución particular y general, que es afín salvo que .
Los subespacios ya aparecidos en el curso son instancias de esta definición: el núcleo de una matriz, su espacio columna y el espacio fila.
Las tres orientaciones de un array
En NumPy, un vector unidimensional de forma (n,) carece de orientación: no es ni fila ni columna. Para el álgebra matricial se le da forma explícita:
u.shape # (3,) sin orientación
u.reshape(-1, 1).shape # (3, 1) columna
u.reshape(1, -1).shape # (1, 3) fila
La distinción no es cosmética. Bajo las reglas de broadcasting descritas en la lección sobre matrices, combinar dos orientaciones distintas produce una matriz en lugar de un vector:
v + v
resultado (3) · elemento a elemento
Sumar una columna (3, 1) con una fila (1, 3) alinea las formas por la derecha, encuentra un en cada posición y extiende ambas: el resultado es de forma (3, 3) y contiene todas las sumas cruzadas. La operación es legal y no produce ningún aviso, de modo que el error se manifiesta más adelante, en una dimensión que no encaja o en una pérdida silenciosamente mal calculada.
La comprobación de .shape antes de operar es el hábito que lo evita.
Espacios que no son ℝⁿ
La generalidad de la definición no es un detalle técnico. Cualquier conjunto cuyas operaciones satisfagan los ocho axiomas hereda toda la teoría posterior: independencia lineal, base, dimensión, transformaciones lineales.
| Espacio | Elementos | Dimensión |
|---|---|---|
| matrices reales | ||
| polinomios de grado | ||
| funciones continuas en | infinita | |
| el núcleo de |
En aprendizaje automático el espacio relevante es casi siempre , pero la elección de y de la aplicación que lleva los datos hasta allí es donde se concentra el diseño. Un texto se representa como un punto de , una imagen como uno de tras aplanar sus píxeles, un usuario como un vector de factores latentes.
Que esas representaciones vivan en un espacio vectorial es lo que autoriza las operaciones habituales sobre ellas. Promediar embeddings para representar un documento tiene sentido porque la suma y el producto por escalar están definidos y el resultado sigue perteneciendo al espacio. La lección sobre el producto por un escalar mostró la otra cara: la métrica que se emplee sobre ese espacio decide qué significa que dos representaciones sean próximas.
Ejercicio. Determinar cuáles de los siguientes subconjuntos de son subespacios, aplicando las tres condiciones: los vectores con ; los vectores con ; los vectores con . Verificar después la primera respuesta comprobando que null_space(np.ones((1, 3))) tiene la dimensión esperada.