Matemática para Machine Learning -
Este artículo es parte de una serie.
Parte 1:
Este artículo
En el módulo anterior exploramos los fundamentos conceptuales de la Inteligencia Artificial. Ahora es momento de sumergirnos en una de las áreas de la matemática que hacen posible que los algoritmos de Machine Learning funcionen: el álgebra lineal.
Si eres como la mayoría de los ingenieros de software, probablemente te preguntes: “¿por qué necesito álgebra lineal para programar IA?” La respuesta es simple pero profunda: el álgebra lineal es el lenguaje nativo del machine learning.
Imagina que estás desarrollando un sistema de recomendaciones para Netflix. Cada usuario tiene preferencias (acción, comedia, drama) que pueden representarse como un vector. Cada película también tiene características (género, año, rating) que forman otro vector. El problema de recomendar películas se convierte en encontrar similitudes entre vectores: álgebra lineal.
O considera una red neuronal procesando una imagen de \(224x224\) píxeles. Esa imagen se convierte en un vector de \(50176\) elementos. Las operaciones de la red (convoluciones, transformaciones) son multiplicaciones de matrices. El entrenamiento optimiza estas matrices, otra vez: álgebra lineal.
Los tres pilares del ML que dependen del Álgebra Lineal#
Representación de Datos: Todo en ML se convierte en vectores y matrices
Transformaciones: Los algoritmos manipulan datos mediante operaciones lineales
Optimización: Los métodos de entrenamiento usan gradientes (derivadas de operaciones matriciales)
Como programadores, estamos acostumbrados a pensar en estructuras de datos como arrays, listas o objetos. En machine learning, pensamos en vectores y matrices. En este módulo aprenderemos a hacer esa transición mental.
Un vector no es simplemente un array de números. Es una entidad matemática que representa tanto magnitud como dirección. En el contexto de machine learning, un vector es una forma de codificar información.
Un vector en dos dimensiones (2D) se puede visualizar como una flecha desde el origen \((0,0)\) hasta el punto \((v_1, v_2)\). Esta visualización es clave para entender las operaciones vectoriales.
importmatplotlib.pyplotaspltimportnumpyasnpdefplot_vector(vector,color='blue',label='Vector'):plt.quiver(0,0,vector[0],vector[1],angles='xy',scale_units='xy',scale=1,color=color,label=label,width=0.005)plt.xlim(-1,5)plt.ylim(-1,5)plt.grid(True)plt.axhline(y=0,color='k',linewidth=0.5)plt.axvline(x=0,color='k',linewidth=0.5)# Ejemplo: vector que representa preferencias de usuariouser_preferences=np.array([3,4])# [acción: 3, comedia: 4]plt.figure(figsize=(8,6))plot_vector(user_preferences,'blue','Preferencias Usuario')plt.xlabel('Rating Acción')plt.ylabel('Rating Comedia')plt.title('Vector de Preferencias de Usuario')plt.legend()plt.show()
Interpretación en ML: Si tenemos las preferencias de dos usuarios similares, podemos promediar sus vectores para encontrar preferencias “típicas” de ese segmento.
Similitud: Vectores similares tienen productos punto altos
Proyección: Mide cuánto un vector “apunta” en la dirección de otro
Redes neuronales: La base de las operaciones en cada neurona
La interpretación geométrica es crucial, el producto punto es igual al producto entre las magnitudes de cada vector y el coseno del ángulo entre ellos:
Antes de usar NumPy, implementemos nuestras propias operaciones vectoriales para entender qué sucede en el detrás de escena:
importmathfromtypingimportListclassVector:"""
Implementación básica de un vector matemático.
Esta clase nos ayuda a entender las operaciones vectoriales
antes de usar bibliotecas optimizadas como NumPy.
"""def__init__(self,componentes:List[float]):"""
Inicializa un vector con una lista de componentes.
Args:
componentes: Lista de números que forman el vector
"""ifnotcomponentes:raiseValueError("Un vector debe tener al menos un componente")self.componentes=componentesself.dimension=len(componentes)def__repr__(self):returnf"Vector({self.componentes})"def__len__(self):returnself.dimensiondef__getitem__(self,index):returnself.componentes[index]def__add__(self,otro_vector):"""
Suma vectorial: componente por componente.
Ejemplo:
v1 = Vector([1, 2, 3])
v2 = Vector([4, 5, 6])
v3 = v1 + v2 # Vector([5, 7, 9])
"""ifself.dimension!=otro_vector.dimension:raiseValueError("Los vectores deben tener la misma dimensión")componentes_resultado=[a+bfora,binzip(self.componentes,otro_vector.componentes)]returnVector(componentes_resultado)def__sub__(self,otro_vector):"""Resta vectorial."""ifself.dimension!=otro_vector.dimension:raiseValueError("Los vectores deben tener la misma dimensión")componentes_resultado=[a-bfora,binzip(self.componentes,otro_vector.componentes)]returnVector(componentes_resultado)def__mul__(self,escalar):"""
Multiplicación por escalar.
Ejemplo:
v = Vector([1, 2, 3])
v_scaled = v * 2 # Vector([2, 4, 6])
"""returnVector([escalar*componenteforcomponenteinself.componentes])defproducto_punto(self,otro_vector):"""
Producto punto: la operación más importante en Machine Learning.
El producto punto mide la similitud direccional entre vectores.
- Producto alto: vectores apuntan en direcciones similares
- Producto cero: vectores perpendiculares
- Producto negativo: vectores apuntan en direcciones opuestas
Args:
otro_vector: Otro vector de la misma dimensión
Returns:
float: El producto punto
"""ifself.dimension!=otro_vector.dimension:raiseValueError("Los vectores deben tener la misma dimensión")returnsum(a*bfora,binzip(self.componentes,otro_vector.componentes))defmagnitud(self):"""
Calcula la magnitud (norma) del vector.
La magnitud representa la "longitud" del vector.
Es importante para normalización y cálculo de distancias.
Returns:
float: La magnitud del vector
"""returnmath.sqrt(sum(componente**2forcomponenteinself.componentes))defnormalizar(self):"""
Normaliza el vector (magnitud = 1).
Los vectores normalizados son cruciales en Machine Learning porque:
- Eliminan el efecto de la escala
- Facilitan la comparación de direcciones
- Son requeridos en muchos algoritmos
Returns:
Vector: Nuevo vector normalizado
"""mag=self.magnitud()ifmag==0:raiseValueError("No se puede normalizar el vector cero")returnVector([componente/magforcomponenteinself.componentes])defsimilitud_coseno(self,otro_vector):"""
Calcula la similitud coseno entre dos vectores.
La similitud coseno es fundamental en:
- Sistemas de recomendación
- Procesamiento de lenguaje natural
- Búsqueda semántica
Retorna valores entre -1 y 1:
- 1: Vectores idénticos en dirección
- 0: Vectores perpendiculares
- -1: Vectores opuestos
Args:
otro_vector: Otro vector
Returns:
float: Similitud coseno
"""dot_prod=self.producto_punto(otro_vector)producto_magnitudes=self.magnitud()*otro_vector.magnitud()ifproducto_magnitudes==0:return0returndot_prod/producto_magnitudes# Ejemplos de usodefdemo_operaciones_vectoriales():"""
Prueba las operaciones vectoriales con ejemplos de Machine Learning.
"""mensaje="Ejemplos de Operaciones Vectoriales"print("#"*len(mensaje))print(mensaje)print("#"*len(mensaje))print("\n")# Ejemplo 1: Preferencias de usuariosprint("=== Ejemplo 1: Preferencias de usuarios ===")print(" Cada usuario se corresponde con un vector que mapea sus preferencias en películas")print(" Vector([acción, comedia, drama])")print("\n")usuarios=[Vector([4,2,5]),Vector([3,4,2]),Vector([9,1,2]),Vector([3,8,1]),Vector([1,2,9])]forindex_i,usuario_iinenumerate(usuarios):print(f" Usuario {index_i}: {usuario_i}")forindex_jinrange(index_i+1,len(usuarios)):usuario_j=usuarios[index_j]print(f" Cálculos de similitud con el usuario {index_j}")combinadas=usuario_i+usuario_jprint(f" Suma: preferencias combinadas: {combinadas}")similitud_producto_punto=usuario_i.producto_punto(usuario_j)print(f" Similitud (producto punto): {similitud_producto_punto}")similitud_coseno=usuario_i.similitud_coseno(usuario_j)print(f" Similitud coseno: {similitud_coseno:.3f}")print("\n")# Ejemplo 2: Vectores de característicasprint("=== Ejemplo 2: Análisis de Documentos ===")print(" Cada documento se corresponde con un vector que mapea las frecuencias de las palabras que contiene")print(" Vector([frecuencia_palabra_1, frecuencia_palabra_2, frecuencia_palabra_3, frecuencia_palabra_4])")documento_1=Vector([2,1,0,3])# Frecuencias de palabrasdocumento_2=Vector([1,2,1,2])# Frecuencias de palabrasprint(f" Documento 1: {documento_1}")print(f" Documento 2: {documento_2}")similitud_documentos_producto_punto=documento_1.producto_punto(documento_2)print(f" Similitud (producto punto): {similitud_documentos_producto_punto}")similitud_documentos_coseno=documento_1.similitud_coseno(documento_2)print(f" Similitud entre documentos (coseno): {similitud_documentos_coseno:.3f}")if__name__=="__main__":demo_operaciones_vectoriales()
Al ejecutar el código anterior obtenemos:
> python vector.py
###################################Ejemplos de Operaciones Vectoriales
###################################=== Ejemplo 1: Preferencias de usuarios=== Cada usuario se corresponde con un vector que mapea sus preferencias en películas
Vector([acción, comedia, drama]) Usuario 0: Vector([4, 2, 5]) Cálculos de similitud con el usuario 1 Suma: preferencias combinadas: Vector([7, 6, 7]) Similitud (producto punto): 30 Similitud coseno: 0.830
Cálculos de similitud con el usuario 2 Suma: preferencias combinadas: Vector([13, 3, 7]) Similitud (producto punto): 48 Similitud coseno: 0.772
Cálculos de similitud con el usuario 3 Suma: preferencias combinadas: Vector([7, 10, 6]) Similitud (producto punto): 33 Similitud coseno: 0.572
Cálculos de similitud con el usuario 4 Suma: preferencias combinadas: Vector([5, 4, 14]) Similitud (producto punto): 53 Similitud coseno: 0.852
Usuario 1: Vector([3, 4, 2]) Cálculos de similitud con el usuario 2 Suma: preferencias combinadas: Vector([12, 5, 4]) Similitud (producto punto): 35 Similitud coseno: 0.701
Cálculos de similitud con el usuario 3 Suma: preferencias combinadas: Vector([6, 12, 3]) Similitud (producto punto): 43 Similitud coseno: 0.928
Cálculos de similitud con el usuario 4 Suma: preferencias combinadas: Vector([4, 6, 11]) Similitud (producto punto): 29 Similitud coseno: 0.581
Usuario 2: Vector([9, 1, 2]) Cálculos de similitud con el usuario 3 Suma: preferencias combinadas: Vector([12, 9, 3]) Similitud (producto punto): 37 Similitud coseno: 0.464
Cálculos de similitud con el usuario 4 Suma: preferencias combinadas: Vector([10, 3, 11]) Similitud (producto punto): 29 Similitud coseno: 0.337
Usuario 3: Vector([3, 8, 1]) Cálculos de similitud con el usuario 4 Suma: preferencias combinadas: Vector([4, 10, 10]) Similitud (producto punto): 28 Similitud coseno: 0.351
Usuario 4: Vector([1, 2, 9])=== Ejemplo 2: Análisis de Documentos=== Cada documento se corresponde con un vector que mapea las frecuencias de las palabras que contiene
Vector([frecuencia_palabra_1, frecuencia_palabra_2, frecuencia_palabra_3, frecuencia_palabra_4]) Documento 1: Vector([2, 1, 0, 3]) Documento 2: Vector([1, 2, 1, 2]) Similitud (producto punto): 10 Similitud entre documentos (coseno): 0.845
Si los vectores representan datos, las matrices representan transformaciones de esos datos. Una matriz es una tabla rectangular de números organizados en filas y columnas.
Cuando se multiplica una matriz por un vector, es necesario que el número de elementos del vector coincida con el número de columnas de la matriz. Si no es así, la multiplicación no está definida.
Ejemplo práctico: En una red neuronal, cada capa aplica una transformación lineal:
salida = pesos × entrada + sesgo
Si aún no lo notaste, se puede establecer una conexión entre la multiplicación de una matriz por un vector y el producto punto entre vectores.
La conexión es directa: multiplicar una matriz por un vector es, en el fondo, hacer varios productos punto seguidos.
Si \(A\) es una matriz de \(m \times n\) y \(v\) es un vector de dimensión \(n\), el resultado de \(A \ v\) es un vector de dimensión \(m\) donde cada componente se obtiene haciendo el producto punto de una fila de la matriz con el vector.
Para que el producto de dos matrices \(A\) y \(B\) es decir, \(AB\) esté definido, la matriz \(A\) debe tener el mismo número de columnas que la matriz \(B\) tenga de filas. Si \(A\) es de tamaño \(m x n\) y \(B\) es de tamaño \(n x p\), entonces el resultado \(C = AB\) será una matriz de tamaño \(m x p\).
importmathfromtypingimportListfromvectorimportVectorclassMatriz:"""
Implementación básica de una matriz matemática.
Esta clase nos ayuda a entender las operaciones matriciales
fundamentales en Machine Learning.
"""def__init__(self,datos:List[List[float]]):"""
Inicializa una matriz con una lista de listas.
Args:
datos: Lista de filas, donde cada fila es una lista de números
"""ifnotdatosornotdatos[0]:raiseValueError("La matriz debe tener al menos un elemento")# Verificar que todas las filas tengan la misma longitudlongitud_fila=len(datos[0])forfilaindatos:iflen(fila)!=longitud_fila:raiseValueError("Todas las filas deben tener la misma longitud")self.datos=datosself.filas=len(datos)self.columnas=len(datos[0])self.forma=(self.filas,self.columnas)def__repr__(self):"""Representación legible de la matriz."""filas=[]forfilainself.datos:row_str=" ".join(f"{x:8.3f}"forxinfila)filas.append(f"[{row_str}]")returnf"Matriz(\n "+"\n ".join(filas)+"\n)"def__getitem__(self,indices):"""Permite acceso con matriz[i][j] o matriz[i, j]."""ifisinstance(indices,tuple):fila,columna=indicesreturnself.datos[fila][columna]else:returnself.datos[indices]def__setitem__(self,indices,value):"""Permite asignación con matriz[i][j] = value."""ifisinstance(indices,tuple):fila,columna=indicesself.datos[fila][columna]=valueelse:fila=indicesself.datos[fila]=valuedef__add__(self,otra):"""Suma de matrices (elemento por elemento)."""ifself.forma!=otra.shape:raiseValueError("Las matrices deben tener la misma forma")datos_resultado=[[self.datos[i][j]+otra.datos[i][j]forjinrange(self.columnas)]foriinrange(self.filas)]returnMatriz(datos_resultado)deftrasponer(self):"""
Calcula la transpuesta de la matriz.
La transpuesta intercambia filas por columnas.
Es fundamental en álgebra lineal y en Machine Learning.
Returns:
Matriz: Nueva matriz transpuesta
"""datos_transpuestos=[[self.datos[fila][columna]forfilainrange(self.filas)]forcolumnainrange(self.columnas)]returnMatriz(datos_transpuestos)defmultiplicar_por_escalar(self,escalar):"""Multiplicación por escalar."""datos_resultado=[[escalar*self.datos[i][j]forjinrange(self.columnas)]foriinrange(self.filas)]returnMatriz(datos_resultado)defmultiplicar_por_vector(self,vector:Vector):"""
Multiplica la matriz por un vector.
Esta es la operación fundamental en redes neuronales:
cada capa aplica una transformación lineal Ax + b.
Args:
vector: Vector a multiplicar
Returns:
Vector: Resultado de la multiplicación
"""ifself.columnas!=len(vector):raiseValueError(f"Dimensiones incompatibles: matriz {self.forma} * vector {len(vector)}")componentes_resultado=[]forindex_filainrange(self.filas):fila=[self.datos[index_fila][columna]forcolumnainrange(self.columnas)]producto_punto=Vector(fila).producto_punto(vector)componentes_resultado.append(producto_punto)returnVector(componentes_resultado)defmultiplicar_matrices(self,otra):"""
Multiplica dos matrices.
La multiplicación de matrices permite componer transformaciones.
En deep learning, representa la composición de capas.
Args:
otra: Otra matriz
Returns:
Matriz: Resultado de la multiplicación
"""ifself.columnas!=otra.filas:raiseValueError(f"Dimensiones incompatibles: {self.forma} * {otra.forma}")print(f" Forma matriz A: {self.forma}")print(f" Forma matriz B: {otra.forma}")datos_resultado=[]forindex_filainrange(self.filas):fila_i_matriz=[self.datos[index_fila][columna]forcolumnainrange(self.columnas)]vector_fila_i_matriz=Vector(fila_i_matriz)fila_resultado=[]forindex_columna_otrainrange(otra.columnas):columna_j_matriz_otra=[otra.datos[fila][index_columna_otra]forfilainrange(otra.filas)]vector_columna_j_matriz_otra=Vector(columna_j_matriz_otra)fila_resultado.append(vector_fila_i_matriz.producto_punto(vector_columna_j_matriz_otra))datos_resultado.append(fila_resultado)returnMatriz(datos_resultado)@staticmethoddefidentidad(tamano:int):"""
Crea una matriz identidad de tamaño size * size.
La matriz identidad es el "1" de las matrices:
A * I = I * A = A
Args:
tamano: Tamaño de la matriz cuadrada
Returns:
Matriz: Matriz identidad
"""datos=[[1.0ifi==jelse0.0forjinrange(tamano)]foriinrange(tamano)]returnMatriz(datos)defrotar_vector(vector:Vector,angulo:int):"""Rotar vector"""angulo_radianes=angulo*math.pi/180# angulo en grados convertido a radianesmatriz_transformacion=Matriz([[math.cos(angulo_radianes),-math.sin(angulo_radianes)],[math.sin(angulo_radianes),math.cos(angulo_radianes)]])return{"matriz_transformacion":matriz_transformacion,"vector_rotado":matriz_transformacion.multiplicar_por_vector(vector)}# Ejemplos de usodefdemo_operaciones_matriciales():"""
Demuestra las operaciones matriciales con ejemplos de Machine Learning.
"""mensaje="Ejemplos de Operaciones Matriciales"print("#"*len(mensaje))print(mensaje)print("#"*len(mensaje))print("\n")print("=== Ejemplo 1: Transponer ===")datos=Matriz([[1.0,2.0,3.0],[4.0,5.0,6.0],[7.0,8.0,9.0]])print(datos)print("Transponer...")print(datos.trasponer())print("\n")print("=== Ejemplo 2: Multiplicación matriz por escalar ===")print(datos)escalar=3print(f"Multiplicación por el escalar: {escalar}...")print(datos.multiplicar_por_escalar(escalar))print("\n")print("=== Ejemplo 3: Multiplicación matriz por vector ===")print(datos)vector=Vector([1.0,2.0,3.0])print(f"Multiplicación por el vector: {vector}...")print(datos.multiplicar_por_vector(vector))print("\n")print("=== Ejemplo 4: Multiplicación matriz por matriz ===")print(datos)otra=Matriz([[9.0,8.0,7.0],[6.0,5.0,4.0],[3.0,2.0,1.0]])print(f"Multiplicación por la matriz: {otra}...")print(datos.multiplicar_matrices(otra))print("\n")print("=== Ejemplo 5: Rotación de un vector en 2D ===")vector_original=Vector([1.0,0.0])print("\n")angulo=45rotacion=rotar_vector(vector_original,angulo)print(f"Vector original en 2D: {vector_original}")print(f"Matriz de rotacion en {angulo} grados: {rotacion["matriz_transformacion"]}")print(f"Vector rotado en {angulo} grados: {rotacion["vector_rotado"]}")print("\n")angulo=90rotacion=rotar_vector(vector_original,angulo)print(f"Vector original en 2D: {vector_original}")print(f"Matriz de rotacion en {angulo} grados: {rotacion["matriz_transformacion"]}")print(f"Vector rotado en {angulo} grados: {rotacion["vector_rotado"]}")print("\n")angulo=180rotacion=rotar_vector(vector_original,angulo)print(f"Vector original en 2D: {vector_original}")print(f"Matriz de rotacion en {angulo} grados: {rotacion["matriz_transformacion"]}")print(f"Vector rotado en {angulo} grados: {rotacion["vector_rotado"]}")if__name__=="__main__":demo_operaciones_matriciales()
Al ejecutar el código anterior obtenemos:
> python matriz.py
###################################Ejemplos de Operaciones Matriciales
###################################=== Ejemplo 1: Transponer===Matriz([ 1.000 2.000 3.000][ 4.000 5.000 6.000][ 7.000 8.000 9.000])Transponer...
Matriz([ 1.000 4.000 7.000][ 2.000 5.000 8.000][ 3.000 6.000 9.000])=== Ejemplo 2: Multiplicación matriz por escalar===Matriz([ 1.000 2.000 3.000][ 4.000 5.000 6.000][ 7.000 8.000 9.000])Multiplicación por el escalar: 3...
Matriz([ 3.000 6.000 9.000][ 12.000 15.000 18.000][ 21.000 24.000 27.000])=== Ejemplo 3: Multiplicación matriz por vector===Matriz([ 1.000 2.000 3.000][ 4.000 5.000 6.000][ 7.000 8.000 9.000])Multiplicación por el vector: Vector([1.0, 2.0, 3.0])...
Vector([14.0, 32.0, 50.0])=== Ejemplo 4: Multiplicación matriz por matriz===Matriz([ 1.000 2.000 3.000][ 4.000 5.000 6.000][ 7.000 8.000 9.000])Multiplicación por la matriz: Matriz([ 9.000 8.000 7.000][ 6.000 5.000 4.000][ 3.000 2.000 1.000])...
Forma matriz A: (3, 3) Forma matriz B: (3, 3)Matriz([ 30.000 24.000 18.000][ 84.000 69.000 54.000][ 138.000 114.000 90.000])=== Ejemplo 5: Rotación de un vector en 2D===Vector original en 2D: Vector([1.0, 0.0])Matriz de rotacion en 45 grados: Matriz([ 0.707 -0.707][ 0.707 0.707])Vector rotado en 45 grados: Vector([0.7071067811865476, 0.7071067811865475])Vector original en 2D: Vector([1.0, 0.0])Matriz de rotacion en 90 grados: Matriz([ 0.000 -1.000][ 1.000 0.000])Vector rotado en 90 grados: Vector([6.123233995736766e-17, 1.0])Vector original en 2D: Vector([1.0, 0.0])Matriz de rotacion en 180 grados: Matriz([ -1.000 -0.000][ 0.000 -1.000])Vector rotado en 180 grados: Vector([-1.0, 1.2246467991473532e-16])
Un espacio vectorial (o espacio lineal) es un conjunto no vacío de vectores, en el que se han definido dos operaciones: la suma de vectores y la multiplicación de un vector por un escalar (número real o complejo). Para que un conjunto sea considerado un espacio vectorial, debe cumplir con ciertos axiomas fundamentales.
Conmutatividad: \(u + v = v + u\)
Asociatividad: \((u + v) + w = u + (v + w)\)
Existencia del vector nulo: \(\exists \ v_0 \in V \ \;|\; \ v_0 + u = u \ \forall \ u \in V \)
Existencia del opuesto: \(\forall \ v_i \in V \ \exists \ -v_i \in V \ \;|\; \ v_i + (-v_i) = 0\)
Distributividad del producto respecto a la suma vectorial: \(\alpha (u + v) = \alpha u + \alpha v\)
Distributividad del producto respecto a la suma escalar: \((\alpha + \beta) u = \alpha u + \beta u\)
Asociatividad del producto de escalares: \(\alpha (\beta u) = (\alpha \beta) u\)
Elemento neutro: \(1 u = u \ \forall \ u \in V\)
Entre algunos ejemplos de espacios vectoriales podemos mencionar:
Vectores en el plano: Los vectores en \(\mathbb{R}^2\) son un ejemplo clásico de espacio vectorial, donde cada vector se representa como un par ordenado \((x,y)\)
Vectores en el espacio tridimensional: En \(\mathbb{R}^3\), un vector se puede escribir como \(V = \alpha i + \beta j + \gamma k \) donde \(i\), \(j\) y \(k\) son vectores base.
Los espacios vectoriales son fundamentales en diversas áreas, incluyendo matemáticas, física, ingeniería y ciencias de la computación, ya que permiten modelar y resolver problemas complejos mediante el uso de vectores y matrices.
¿Por qué importa en Machine Learning?
Características: Cada dataset define un espacio vectorial
Modelos: Los algoritmos de Machine Learning operan en estos espacios
Transformaciones: Cambiamos de un espacio a otro para facilitar el aprendizaje
Una transformación \(T: \mathbb{R}^n \rightarrow \mathbb{R}^m\) se define como una función que asigna a cada vector \(v\) en un espacio vectorial \(V\) un único vector \(w\) en otro espacio vectorial \(W\).
Para que \(T\) sea considerada lineal, debe cumplir dos condiciones fundamentales:
Adición: Para cualquier par de vectores \(u\) y \(v\) en \(V\), se cumple que:
$$ T(u + v) = T(u) + T(v) $$
Homogeneidad: Para cualquier escalar \(c\) y cualquier vector \(v\) en \(V\) se cumple que:
$$ T(c \ v) = c \ T(v) $$
Toda transformación lineal entre espacios vectoriales de dimensión finita puede representarse mediante una matriz, por ejemplo:
Imaginemos una transformación \(T: \mathbb{R}^2 \rightarrow \mathbb{R}^2\) definida por:
La base canónica es un conjunto de vectores que forma una base ortonormal en un espacio vectorial. En el plano, la base canónica está compuesta por los vectores \(i\) y \(j\), que representan las direcciones de los ejes \(x\) e \(y\), respectivamente. Estos vectores se utilizan para expresar otros vectores como combinaciones lineales de la base canónica. Además, la base canónica es fundamental para entender la dimensión y la estructura de los espacios vectoriales.
Los valores propios o autovalores y los vectores propios o autovectores revelan las direcciones “especiales” de una transformación lineal.
Los vectores propios o autovectores de una transformación lineal son los vectores no nulos que, cuando son transformados, dan lugar a un múltiplo escalar de sí mismos, con lo que no cambian su dirección. Este escalar \(\lambda\) recibe el nombre de valor propio o autovalor. En muchos casos, una transformación queda completamente determinada por sus vectores propios y valores propios. Un espacio propio o autoespacio asociado al valor propio \(\lambda\) es el conjunto de vectores propios con un valor propio común.
Para una transformación lineal representada por la matriz \(\mathbf{A}\), un vector \(\mathbf{v}\) es un vector propio con valor propio \(\lambda\) si:
$$\mathbf{A}\mathbf{v} = \lambda \mathbf{v}$$
Interpretación: La transformación \(\mathbf{A}\) solo escala el vector \(\mathbf{v}\) por el factor \(\lambda\), sin cambiar su dirección.
Imagen de J. Finkelstein y Vb on Wikimedia Commons, dominio públicoEn esta transformación de la Mona Lisa, la imagen se ha deformado de tal forma que su eje vertical no ha cambiado. El vector azul, representado por la flecha azul que va desde el pecho hasta el hombro, ha cambiado de dirección, mientras que el rojo, representado por la flecha roja, no ha cambiado. El vector rojo es entonces un vector propio o autovector de la transformación, mientras que el azul no lo es. Dado que el vector rojo no ha cambiado de longitud, su valor propio o autovalor es \(1\). Todos los vectores de esta misma dirección son vectores propios, con el mismo valor propio. Forman un subespacio del espacio propio de este valor propio.
Crea un archivo Python con el siguiente contenido:
defver_valores_propios():"""
Visualiza conceptualmente los valores y los vectores propios.
Esta es una simplificación para matrices 2x2.
"""importmatplotlib.pyplotaspltimportnumpyasnp# Matriz de ejemploA=np.array([[3,1],[0,2]])# Calcular valores y vectores propios usando NumPyvalores_propios,vectores_propios=np.linalg.eig(A)# Crear varios vectores para mostrar la transformaciónangles=np.linspace(0,2*np.pi,16)vectores_originales=np.array([[np.cos(a),np.sin(a)]forainangles])vectores_transformados=np.array([A@vforvinvectores_originales])fig,(ax1,ax2)=plt.subplots(1,2,figsize=(12,5))# Vectores originalesax1.set_aspect('equal')forvinvectores_originales:ax1.arrow(0,0,v[0],v[1],head_width=0.05,head_length=0.1,fc='blue',ec='blue',alpha=0.6)# Vectores propios originalesfori,(val,vec)inenumerate(zip(valores_propios,vectores_propios.T)):ax1.arrow(0,0,vec[0],vec[1],head_width=0.1,head_length=0.15,fc='red',ec='red',linewidth=3,label=f'Vector propio {i+1}')ax1.set_xlim(-2,2)ax1.set_ylim(-2,2)ax1.set_title('Vectores Originales')ax1.grid(True)ax1.legend()# Vectores transformadosax2.set_aspect('equal')forvinvectores_transformados:ax2.arrow(0,0,v[0],v[1],head_width=0.05,head_length=0.1,fc='green',ec='green',alpha=0.6)# Vectores propios transformados (escalados por valor propio)fori,(val,vec)inenumerate(zip(valores_propios,vectores_propios.T)):vectores_propios_transformados=val*vecax2.arrow(0,0,vectores_propios_transformados[0],vectores_propios_transformados[1],head_width=0.1,head_length=0.15,fc='red',ec='red',linewidth=3,label=f'λ{i+1}={val:.1f} × eigenvec{i+1}')ax2.set_xlim(-4,4)ax2.set_ylim(-4,4)ax2.set_title('Vectores Transformados por A')ax2.grid(True)ax2.legend()plt.tight_layout()plt.show()print(f"Valores propios: {valores_propios}")print(f"Vectores propios:\n{vectores_propios}")ver_valores_propios()
Implementación práctica: un sistema de recomendaciones usando álgebra lineal#
En el siguiente artículo de este módulo, vamos a actualizar nuestro sistema de recomendaciones para utilizar los conceptos de álgebra lineal que aprendimos hasta acá.
¡Nos vemos allí! 🚀
¡Gracias por haber llegado hasta acá!
Si te gustó el artículo, por favor ¡no olvides compartirlo con tu familia, amigos y colegas!
Y si puedes, envía tus comentarios, sugerencias, críticas a nuestro mail o por redes sociales, nos ayudarías a generar mejor contenido y sobretodo más relevante para vos.
Matemática para Machine Learning -
Este artículo es parte de una serie.
Parte 1:
Este artículo
Relacionados
Fundamentos de Inteligencia Artificial: Conclusión