Parte 1 — Fundamentos del álgebra lineal: Escalares, vectores, matrices y tensores

Alejandro Debus
mate.ai
Published in
8 min readSep 8, 2018

Introducción

E l objetivo de esta serie de publicaciones sobre álgebra lineal está destinada a principiantes en la rama del álgebra lineal y el aprendizaje profundo (deep learning). Para facilitar la comprensión de los temas abordados, todos los conceptos que se enuncien irán acompañados de una serie de ejemplos utilizando código en Python, la librería de uso científico NumPy y diferentes gráficos. La codificación de determinados ejemplos no solo ayuda a explorar con mayor profundidad el álgebra lineal, si no que también sirve como punto de partida a la codificación de los principales algoritmos de deep learning y su comprensión. Personalmente creo que es un herramienta excepcional para la experimentación. De todos modos, todo esto no quita de ninguna manera la experimentación con lápiz y papel, la cual queda de tarea para el lector.

¿Qué es el álgebra lineal?

El álgebra lineal es una rama de las matemáticas muy utilizada en la ciencia y la ingeniería [1]. Si buscamos la palabra lineal en el diccionario podemos encontrar la siguiente definición: adj. Perteneciente o relativo a la línea. En matemáticas, lineal posee un significado mucho más abarcativo. De hecho, una gran parte del estudio del álgebra lineal elemental es una generalización de las propiedades de la línea recta [2]. Los principales temas de estudio del álgebra lineal son los vectores, matrices, los espacios vectoriales y sus transformaciones lineales. De hecho, muchos de estos temas son los que veremos en esta y futuras publicaciones.

Escalares, vectores, matrices y tensores

Escalares

Un escalar es únicamente un número, a diferencia de la mayoría de los otros elementos del álgebra lineal que son conjuntos de valores como los vectores y matrices. Generalmente, por convención a los escalares los escribimos en letra cursiva minúscula o usando el alfabeto griego.

Entre los principales conjuntos de escalares tenemos a:

  • Números Naturales (ℕ): los números que se utilizan para contar los elementos de cualquier conjunto. (1, 2, 3, 4, …)
  • Números Enteros (ℤ): el conjunto de los números enteros está dado por el conjunto de los naturales, sus negativos y el cero. (…, -2, -1, 0, 1, 2, …)
  • Números Reales (ℝ): el conjunto de los reales incluye tanto a los racionales como a los irracionales.

En Python existen pocos tipos de datos para valores escalares, tales como int, float, complex, bytes. Sin embargo, depende la aplicación podemos requerir mas o menor precisión para un tipo de dato y de esta manera aprovechar mejor los recursos computacionales. En NumPy, existen 24 tipos fundamentales de datos para Python para describir diferentes tipos de escalares los cuales se pueden consultar accediendo a este enlace.

#Ejemplo 1: Experimentando con escalaresa = 2
b = 4.8
c = 7.435
print(a)
print(b)
print(c)
#salida:
2
4.8
7.435
print(a + b)
print(b - c)
print(b * a)
print(c / b)
print(c // b)
#salida:
6.8
-2.635
9.6
1.5489583333333332
1.0

Vectores

Un vector es un arreglo de números. Un vector de n componentes se define como un conjunto ordenado de n números escrito de la siguiente forma:

Vector fila

si es un vector fila.
Y de la siguiente manera si es un vector columna:

Vector columna

A los vectores, generalmente los denotamos por una letra minúscula en negrita.

#Ejemplo 2: Crear un vector de 5 elementos#No olvidar importar la librería
import numpy as np
v = np.array([8, 0, 3, 1, 5])
print(v)
#salida: [8, 0, 3, 1, 5]

Existen muchos casos donde queremos saber la dimensión del arreglo con el que estamos trabajando. En NumPy es muy fácil consultarlo. Veamos el siguiente ejemplo:

#Ejemplo 3: Crear un vector de valores aleatorios de tamaño 100 y calcular su tamaño con NumPy.v = np.random.rand(100)
dim_v = v.shape
print(dim_v)
#salida: (100,) #si hacemos len(v1) obtendremos directamente 100

El producto de un vector por un escalar (no confundir con producto escalar de vectores) es la simple operación de multiplicar cada componente del vector por un escalar determinado. Veamos el siguiente ejemplo:

#Ejemplo 4: Multiplicar un vector por un escalar. Consultar mas abajo la propiedad de broadcasting que posee NumPy.escalar_b = 2.0
v = np.array([8, 0, 3, 1, 5])
print(escalar_b * v2)
#salida: [16. 0. 6. 2. 10.]

La suma de vectores está dada por la operación de sumar componente a componente de cada vector involucrado en la suma. Se debe observar que los vectores deben tener la misma longitud.

# Ejemplo 5: Crear y sumar tres vectoresv1 = np.array([6, 0, -3, 7])
v2 = np.array([2, 3, 7, -5])
v3 = np.array([0.1, 5, 0.89, 5])
print(v1 + v2 + v3)#salida: [8.1 8. 4.89 7.]
  • Producto escalar

Sean a y b, dos vectores de n componentes. Entonces el producto escalar de a y b denotado por a . b está dado por:

Este tipo de operación, a menudo también se denomina producto punto o producto interno.

Se debe observar que el producto escalar entre dos vectores de n componentes da como resultado un escalar, es decir un número. En publicaciones posteriores veremos el verdadero significado del producto escalar.

# Ejemplo 6: Producto escalarv1 = np.array([1, 5, -2, 7, 3])
v2 = np.array([3, 1, 1, -5, -1])
print(np.dot(v1, v2))#salida: -32

Matrices

Una matriz es un arreglo bi-dimensional de números. Cada elemento de la misma está identificado por dos índices, en lugar de uno como en los vectores. Usualmente, a una matriz la denotamos por una letra mayúscula en negrita.

Matriz de tamaño m x n
# Ejemplo 7: Crear una matriz de 2x3 y consultar su tamaño.A = np.array([[5, 4, 7],
[3, 8, 1]])
print(A.shape)#salida: (2, 3)
  • Suma de matrices

Sean A y B dos matrices de tamaño m x n. Entonces la suma de A y B es una matriz de m x n dada por:

Hay que tener en cuenta que dos matrices solo se pueden sumar cuando poseen la misma dimensión.

# Ejemplo 8: Crear 2 matrices de valores enteros y sumarlas.A = np.array([[5, 4, 7],
[3, 6, 1]])
B = np.array([[1, 0, 2],
[4, 3, 3]])
print(A + B)#salida: [[6 4 9]
[7 9 4]]
  • Multiplicación de una matriz por un escalar

Si A es una matriz de tamaño m x n y si α es un escalar, entonces el resultado de multiplicar α por A da como resultado una matriz de tamaño m x n, donde cada componente es el resultado de multiplicar cada componente de A por α, tal como se muestra a continuación:

# Ejemplo 9: Crear una matriz de 2x2 y multiplicarla por un escalarA = np.array([[5, 4],
[3, 6]])
escalar = 3print(escalar * A)#salida: [[15 12]
[ 9 18]]
  • Producto de matrices

Sea A una matriz de m x n, y sea B una matriz de n x p. Entonces el producto de A y B es una matriz C de tamaño m x p donde:

Se debe observar que dos matrices solo se pueden multiplicar si el número de columnas de la primera matriz es igual al número de filas de la segunda.

# Ejemplo 10: Crear 2 matrices y multiplicarlasA = np.array([[5, 4, 7],
[3, 6, 1]])
B = np.array([[1, 0],
[4, 3],
[9, 2]])
print(np.matmul(A, B)) #También se puede usar la función dot#salida:[[84 26]
[36 20]]
  • Transpuesta de una matriz

Sea A, una matriz de m x n. Entonces la matriz transpuesta de A, denotada por Aᵀ, es la matriz de n x m la cual se obtiene las filas por las columnas de A.

Notar que simplemente se coloca el renglón i de A como la columna i de Aᵀ transpuesta y la columna j de A como la fila j de Aᵀ.

# Ejemplo 11: Crear una matriz de 2x3, hallar su transpuesta y verificar el nuevo tamaño.A = np.array([[5, 4, 7],
[3, 6, 1]])
A_t = np.transpose(A)print('A_t: ', A_t)
print('Tamaño de A_t: ', A_t.shape)
#salida: A_t:
[[5 3]
[4 6]
[7 1]]
Tamaño de A_t: (3, 2)

Tensores

Existen diversos casos en los cuales se precisan mas de dos ejes para almacenar valores. En el caso general, una matriz con un número regular de ejes se lo conoce como tensor. Por ejemplo, cuando almacenamos los valores de los píxeles de una imagen a color necesitamos una matriz con tres ejes (uno para cada canal de color: R, G y B).

Las operaciones que vimos para matrices pueden ser extendidas los tensores, por lo que solo veremos un ejemplo de tensor y la importancia que tienen.

# Ejemplo 12: En este ejemplo crearemos un tensor de 10x10x3 de valores aleatorios enteros en un rango de 0 a 255 (niveles de intensidad de un pixel) y lo mostraremos como si fuera una imagen.#Libería para visualizar la imagen
import matplotlib.pyplot as plt
#Fijamos la semilla del generador de valores aleatorios
np.random.seed(123)
#256 indica que se crean valores entre 0 y 255
A = np.random.randint(256, size=(10,10,3))
#Visualizamos el tensor A
plt.imshow(A)
#salida:
Imagen de salida producto de crear el tensor de 10x10x3

Broadcasting

El concepto de broadcasting se usa para entender como NumPy realiza las operaciones entre arreglos (vectores, matrices, tensores) de diferente tamaño. Sujeto a ciertas restricciones, el arreglo más pequeño es “difundido” (¡?) a través del arreglo más grande, para que de esta forma sean compatibles en tamaño.

El broadcasting muchas veces conduce a una implementación más eficiente de los algoritmos ya que proporciona un medio para la vectorización de operaciones de modo que los bucles se realicen en C y no en Python. Sin embargo pueden existir situaciones en que utilizar broadcasting sea ineficiente, debido a un uso ineficiente de la memoria.

# Ejemplo 13: Experimentar el concepto de broadcasting. Crearemos una matriz de 3x3, un vector de 3x1 y los sumaremos.M = np.array([[1, 6, 2],
[4, 2, 3],
[1, 4, 2]])
v = np.array([5, 2, 1])print(M + v)#salida:[[ 6 6 2]
[11 4 5]
[ 7 5 3]]

Esta publicación solo ha sido una pequeña introducción al mundo del álgebra lineal. En futuras publicaciones iremos aumentando la complejidad de los temas y ejemplos con la idea de poder aplicarlo al deep learning.

Todos los ejemplos se pueden encontrar en el siguiente enlace a GitHub.

Si encuentra un error, por favor repórtelo.

Referencias

[1] Goodfellow, I., Bengio, Y., Courville, A., & Bengio, Y. (2016). Deep learning (Vol. 1). Cambridge: MIT press.
[2] Grossman, S., & Flores, J. J. (2012). Álgebra lineal (Séptima Edición (C. de México, Ed.).
[3] Documentación de NumPy: https://docs.scipy.org (2018)

--

--