El álgebra lineal es una de las herramientas matemáticas básicas que necesitamos en ciencia de datos. Comprender estos conceptos mejora tu entendimiento de muchos algoritmos. Es, de verdad, una base excelente para una trayectoria en data science y machine learning.
\n
El objetivo de este tutorial es entrar en las matemáticas para ciencia de datos programando con Python/Numpy. Tener tutoriales prácticos sobre temas teóricos como el álgebra lineal puede ser muy útil, porque escribir y leer código es una gran forma de interiorizar conceptos matemáticos. Y, sobre todo, ¡puede ser muy divertido!
\n
No hay prerrequisitos específicos, pero si no tienes claro qué es una matriz o cómo hacer el producto punto, los primeros posts (1 a 4) de mi serie sobre el libro de deep learning de Ian Goodfellow son un buen comienzo.
\n
En este tutorial veremos un concepto importante para machine learning y deep learning: la norma. La norma se usa muchísimo, por ejemplo, para evaluar la calidad de un modelo. Al terminar, tendrás una mejor intuición de este concepto y por qué es tan valioso en machine learning. También veremos cómo se usa la derivada de la norma para entrenar un algoritmo de machine learning.
\n
Configuración básica
\n
Antes de nada, vamos a preparar las librerías que usaremos:
\n
import numpy as np\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nCon la tecnología de
\n
Y añadimos algunos atajos en LaTeX a los comandos bs para símbolos en negrita y norm para el símbolo de la norma:
\n
$$\n\\newcommand\\bs[1]{\\boldsymbol{#1}}\n\\newcommand\\norm[1]{\\left\\lVert#1\\right\\rVert}\n$$\nCon la tecnología de
Lo último es ajustar la apariencia de los gráficos que vamos a crear:
\n
# Parámetros de las gráficas\nsns.set()\n%pylab inline\npylab.rcParams['figure.figsize'] = (4, 4)\nplt.rcParams['xtick.major.size'] = 0\nplt.rcParams['ytick.major.size'] = 0\nCon la tecnología de
\n
Populating the interactive namespace from numpy and matplotlib\nCon la tecnología de
\n
Un ejemplo práctico
\n
Empecemos con un ejemplo sencillo. Imagina que tienes un conjunto de canciones con diferentes características. Ahora quieres crear un modelo que prediga la duración de una canción en función de otras variables como el género musical, la instrumentación, etc. Entrenas un modelo y ahora quieres evaluarlo al predecir la duración de una nueva canción. Una forma de hacerlo es tomar datos nuevos y predecir la duración con tu modelo. Como conoces la duración real de cada canción para estas observaciones, puedes comparar la duración real y la predicha en cada caso. Tienes los siguientes resultados en segundos para 7 observaciones:
Estas diferencias se pueden interpretar como el error del modelo. Un modelo perfecto tendría solo 0, mientras que un modelo muy malo tendría valores enormes positivos o negativos.
\n
Ahora imagina que pruebas otro modelo y obtienes las siguientes diferencias entre la duración predicha y la real:
¿Qué puedes hacer si quieres encontrar el mejor modelo? Una forma natural es sumar los valores absolutos de estos errores. Usamos el valor absoluto porque un error negativo (duración real menor que la predicha) también es un error. Cuanto menor sea el error total del modelo, mejor:
\n
totalErrorModel1 = np.sum(np.abs(errorModel1))\ntotalErrorModel1\nCon la tecnología de
Parece que el modelo 1 es bastante mejor que el modelo 2.
\n
¡Enhorabuena! ¡Acabas de calcular la norma del vector de errores de cada modelo!
\n
Intuición
\n
Puedes pensar en la norma como la longitud del vector. Para hacernos una idea gráfica, retomemos el ejemplo anterior. Los vectores de error son multidimensionales: hay una dimensión por observación. En el último ejemplo, 7 observaciones implicaban 7 dimensiones. Aún es difícil representar 7 dimensiones, así que simplifiquemos y quedémonos con solo 2 observaciones:
Ahora podemos representar estos vectores considerando que el primer elemento del array es la coordenada x y el segundo es la coordenada y. Empezaremos escribiendo una función para dibujar los vectores fácilmente y hacernos una idea de su representación.
\n
Cómo representar vectores con Python y Matplotlib
\n
Queremos una función que nos ayude a dibujar los vectores. Empecemos por cómo la usaríamos. Queremos pasar una lista de arrays con las coordenadas de los vectores y obtener una gráfica de esos vectores. Digamos que también podemos pasar un array de colores para diferenciarlos en la gráfica. En resumen, nos gustaría llamar a la función así:
defplotVectors(vecs, cols, alpha=1):\n \"\"\"\n Dibuja un conjunto de vectores.\n\n Parámetros\n ----------\n vecs : array-like\n Coordenadas de los vectores a dibujar. Cada vector va en un array. Por\n ejemplo:[[1,3],[2,2]] sirve para dibujar 2 vectores.\n cols : array-like\n Colores de los vectores. Por ejemplo:['red','blue'] mostrará el\n primer vector en rojo y el segundo en azul.\n alpha :float\n Opacidad de los vectores\n\n Devuelve:\n\n fig : instancia de matplotlib.figure.Figure\n La figura con los vectores\n \"\"\"\n plt.axvline(x=0, color='#A9A9A9', zorder=0)\n plt.axhline(y=0, color='#A9A9A9', zorder=0)\n\n for i inrange(len(vecs)):\n if(isinstance(alpha,list)):\n alpha_i = alpha[i]\n else:\n alpha_i = alpha\n if(len(vecs[i])==2):\n x = np.concatenate([[0,0],vecs[i]])\n elif(len(vecs[i])==4):\n x = vecs[i]\n plt.quiver([x[0]],\n [x[1]],\n [x[2]],\n [x[3]],\n angles='xy', scale_units='xy', scale=1, color=cols[i],\n alpha=alpha_i)\nCon la tecnología de
\n
Toma como entrada un array de vectores a dibujar (vecs) y sus colores (cols). Si en el vector solo se indican 2 dimensiones, el origen es (0, 0). Por debajo, iteramos sobre el array de vectores y usamos plt.quiver() para representarlos.
\n
Usemos la nueva función para dibujar los errores de los modelos 1 y 2:
\n
plotVectors([errorModel1, errorModel2],[sns.color_palette()[0], sns.color_palette()[1]])\n\nplt.xlim(-1,25)\nplt.ylim(-5,10)\nplt.show()\nCon la tecnología de
\n
\n
Nota: no incluimos plt.show() en la función para poder añadir ajustes a la gráfica como, por ejemplo, los límites.
\n
Nota 2: usamos los colores de seaborn manualmente con sns.color_palette()
\n
Así tenemos un vector de error por cada modelo. El mejor modelo es el que corresponde al vector más corto. Una forma de calcular la longitud de los vectores es usar el teorema de Pitágoras: $\\sqrt{x^2+y^2}$. Podemos calcular la longitud de los dos vectores:
\n
# Longitud del vector errorModel1\nnp.sqrt(errorModel1[0]**2+errorModel1[1]**2)\nCon la tecnología de
¡Enhorabuena! Has calculado otra norma de los vectores de error. La longitud del vector de error del primer modelo es $22.36$ y la del segundo ronda los $16.64$. En este caso, el segundo modelo es mejor, pero recuerda que solo hemos usado los dos primeros valores.
\n
Primero calculamos la suma de los errores, pero también podemos usar el teorema de Pitágoras para calcular la norma de un vector. Son dos normas distintas, lo que muestra que hay varias maneras de calcular normas.
\n
Funciones de norma: definiciones
\n
La norma de un vector puede ser cualquier función que mapee un vector a un valor positivo. Se pueden usar funciones distintas y veremos algunos ejemplos. Estas funciones pueden llamarse normas si cumplen las siguientes propiedades:
\n
\n
\n
Las normas son valores no negativos. Si piensas en la norma como una longitud, verás por qué no puede ser negativa.
\n
\n
\n
La norma es $0$ si y solo si el vector es el vector nulo.
\n
\n
\n
Las normas cumplen la desigualdad del triángulo. Ver más abajo.
\n
\n
\n
$\\norm{k\\cdot \\bs{u}}=\\norm{k}\\cdot\\norm{\\bs{u}}$. Aquí, $k$ es un escalar y $\\bs{u}$ un vector. La norma de un vector multiplicado por un escalar es igual al valor absoluto de ese escalar multiplicado por la norma del vector.
\n
\n
\n
Suele escribirse con dos barras verticales: $\\norm{\\bs{x}}$
\n
La desigualdad del triángulo
\n
Hemos visto arriba que una condición para que una función sea una norma es que cumpla la desigualdad del triángulo. Significa que la norma de la suma de unos vectores es menor o igual que la suma de las normas de esos vectores:
Para ilustrarlo, tomaremos dos vectores, cada uno con dos elementos (útiles de nuevo para representarlos como coordenadas x e y). Nuestros vectores son:
Más adelante veremos distintos tipos de normas, pero por ahora usaremos la clásica: la norma euclídea ($L^2$). La norma $L^2$ se puede calcular con la función de Numpy np.linalg.norm() (ver más detalles en la documentación).
Verás que la representación gráfica de este teorema lo hace bastante trivial. Dibujaremos los vectores $\\bs{u}$, $\\bs{v}$ y $\\bs{u}+\\bs{v}$ usando nuestra función plotVectors y añadiendo texto para identificarlos:
\n
u = np.array([0,0,1,6])\nv = np.array([0,0,4,2])\nw = u+v\n\nu_bis =[u[2], u[3], v[2], v[3]]\n\nplotVectors([u, u_bis, w],\n [sns.color_palette()[0],\n sns.color_palette()[1],\n sns.color_palette()[2]])\n\nplt.xlim(-2,6)\nplt.ylim(-2,9)\n\nplt.text(-1,3.5,r'$||\\vec{u}||$', color=sns.color_palette()[0], size=20)\nplt.text(2.5,7.5,r'$||\\vec{v}||$', color=sns.color_palette()[1], size=20)\nplt.text(2,2,r'$||\\vec{u}+\\vec{v}||$', color=sns.color_palette()[2], size=20)\n\nplt.show()\nplt.close()\nCon la tecnología de
\n
\n
La longitud de $\\bs{u}$ más la de $\\bs{v}$ es mayor que la longitud del vector $\\bs{u}+\\bs{v}$. Geométricamente, ¡esto no es más que decir que el camino más corto entre dos puntos es una línea!
\n
Normas p: reglas generales
\n
Hemos visto las condiciones que debe cumplir una función para llamarse norma. Esto significa que hay varias funciones que se pueden usar como normas. Más adelante veremos pros y contras de cada una. Llamamos $p$-norma a la siguiente familia de funciones que dependen de $p$:
Veamos qué implica. Elevar al exponente 0 valores absolutos te da un $1$ para cada valor distinto de $0$ y un $0$ para los ceros.
\n
Por tanto, esta \"norma\" corresponde al número de elementos no nulos del vector. En rigor no es una norma, porque si multiplicas el vector por $\\alpha$, este número no cambia (regla 4 de arriba).
\n
La norma $L^1$
\n
Si $p=1$, simplemente tenemos la suma de los valores absolutos. Es lo que usamos de forma intuitiva al principio de este tutorial:
\n
\n
La norma $L^2$ (norma euclídea)
\n
La norma euclídea es la $p$-norma con $p=2$. Probablemente es la más usada junto con la norma $L^2$ al cuadrado (ver más abajo).
Observa que ya no necesitamos el valor absoluto porque $x$ está al cuadrado. Es lo que usamos al calcular la longitud de nuestros vectores con el teorema de Pitágoras.
\n
Veamos otro ejemplo de esta norma:
\n
Ejemplo 2.
\n
Gráficamente, la norma euclídea corresponde a la longitud del vector desde el origen hasta el punto obtenido por la combinación lineal (teorema de Pitágoras). Veremos un ejemplo en 2 dimensiones: el vector $\\bs{u}$ tiene dos valores que corresponden a la coordenada $x$ y la coordenada $y$. Si representas el punto con esas coordenadas y dibujas un vector desde el origen hasta ese punto, la norma $L^2$ será la longitud de ese vector.
La norma $L^2$ al cuadrado es cómoda porque elimina la raíz cuadrada y nos quedamos con la simple suma de cada valor del vector al cuadrado.
\n
La norma euclídea al cuadrado se usa mucho en machine learning en parte porque se puede calcular con la operación vectorial $\\bs{x}^\\text{T}\\bs{x}$. Puede haber mejoras de rendimiento gracias a la optimización. Ver aquí y aquí para más detalles.
\n
Ejemplo 3.
\n
Veremos en este ejemplo que la norma euclídea al cuadrado puede calcularse con operaciones vectorizadas. Empecemos con un vector $\\bs{x}$:
El producto punto de $\\bs{x}$ y $\\bs{x}^\\text{T}$ (ver aquí si necesitas recordar el producto punto) corresponde, de hecho, a multiplicar cada elemento por sí mismo:
\n
\n
¡Esto es exactamente la definición de la norma euclídea al cuadrado!
\n
Comprobémoslo con Numpy. Recuerda (y pruébalo para convencerte) que el orden del vector en el producto punto importa:
¡Funciona! La posibilidad de usar una operación vectorizada es una gran ventaja respecto a otras normas.
\n
Derivada de la norma $L^2$ al cuadrado
\n
Hemos visto que las normas pueden usarse para evaluar la calidad de un modelo resumiendo los vectores de errores.
\n
Ahora queremos ir un paso más allá y saber cómo cambiar los parámetros del modelo para reducir el error total. Para ello podemos usar una función de coste que asocie el error del modelo en función de los valores de los parámetros. El algoritmo de descenso de gradiente se puede usar para encontrar el mínimo de esta función. El descenso de gradiente se hace calculando las derivadas respecto a cada parámetro (derivadas parciales = gradientes). Por eso es crucial poder calcular la derivada de forma eficiente.
\n
De hecho, una gran ventaja de la norma $L^2$ al cuadrado es que su derivada parcial se calcula muy fácilmente. Consideremos el siguiente vector:
Luego, para calcular las derivadas parciales, consideramos todas las demás variables como constantes. Por ejemplo, la derivada parcial respecto a $u_1$ es la derivada de $u_1^2+a$ (siendo $a$ la constante que corresponde al resto de variables). Por esta razón, tenemos las siguientes derivadas parciales:
Lo bueno de los gradientes de la norma $L^2$ al cuadrado es que las derivadas no dependen de las otras variables. Veremos que no es el caso con la norma $L^2$.
\n
Derivada de la norma $L^2$
\n
En el caso de la norma $L^2$, la derivada es más compleja y tiene en cuenta todos los elementos del vector. Tomemos como ejemplo el último vector $\\bs{u}$. La norma $L^2$ es:
La norma $L^2$ al cuadrado es estupenda, pero tiene un problema: discrimina poco entre 0 y valores pequeños porque la función crece lentamente.
\n
Podemos verlo comparando gráficamente la norma $L^2$ al cuadrado con la norma $L^2$. El eje $z$ corresponde al valor de la norma y los ejes $x$ e $y$ a dos parámetros. Lo mismo ocurre con más de 2 dimensiones, pero sería difícil de visualizar.
\n
Norma $L^2$:
\n
\n
Norma $L^2$ al cuadrado:
\n
\n
Para comparar, aquí tienes la norma $L^1$:
\n
\n
Estas gráficas se han hecho con ayuda de este sitio web. Entra y dibuja estas normas si necesitas moverlas para captar su forma.
\n
La norma máxima
\n
Es la norma $L^\\infty$ y corresponde al valor absoluto del mayor elemento del vector.
El producto punto entre los vectores $\\bs{x}$ y $\\bs{y}$ se puede recuperar con las normas $L^2$ de estos vectores. $\\theta$ es el ángulo entre ambos.
x =[0,0,0,2]\ny =[0,0,2,2]\n\nplotVectors([x, y],[sns.color_palette()[0], sns.color_palette()[1]])\n\nplt.xlim(-1,3)\nplt.ylim(-1,3)\n\nplt.text(-0.5,1,r'$\\vec{x}$', size=18, color=sns.color_palette()[0])\nplt.text(1.5,0.5,r'$\\vec{y}$', size=18, color=sns.color_palette()[1])\nCon la tecnología de
Es el mismo resultado que con el producto punto. Aquí están las operaciones con numpy. Ten en cuenta que usamos la función deg2rad de Numpy porque np.cos toma el ángulo en radianes, así que hay que convertirlo.
\n
# Nota: np.cos toma el ángulo en radianes\nnp.cos(np.deg2rad(45))*2*np.sqrt(8)\nCon la tecnología de
La norma $L^2$ (o la norma de Frobenius en el caso de una matriz) y la norma $L^2$ al cuadrado se usan ampliamente en machine learning, deep learning y ciencia de datos en general. Por ejemplo, las normas pueden usarse como funciones de coste. Imagina que quieres ajustar una recta a un conjunto de puntos. Una forma de encontrar la mejor recta es empezar con parámetros aleatorios e iterar minimizando la función de coste. La función de coste representa el error de tu modelo, así que quieres que ese error sea lo más pequeño posible. Las normas son útiles aquí porque te dan una manera de medir ese error. La norma transforma el vector que contiene todos tus errores en un escalar simple, y la función de coste es ese escalar para un conjunto de valores de tus parámetros.
\n
Hemos visto que las normas no son más que reducir un array a un escalar. También hemos visto que hay variaciones según la función que usemos para calcularla. Elegir qué norma usar depende mucho del problema a resolver, ya que hay pros y contras para aplicar una u otra. Por ejemplo, la norma $L^1$ es más robusta que la $L^2$. Esto significa que la $L^2$ es más sensible a valores atípicos, ya que errores grandes se convierten en errores enormes al cuadrado.
\n
Este tutorial se basa en este artículo de mi serie sobre el capítulo de álgebra lineal del Deep Learning Book de Goodfellow et al.
Proyectos de machine learning para principiantes, estudiantes de último año y profesionales. La lista incluye proyectos guiados, tutoriales y código fuente de ejemplo.
Descubre qué es el machine learning supervisado, en qué se diferencia del machine learning no supervisado y cómo funcionan algunos algoritmos esenciales del machine learning supervisado
Introducción
\nEl álgebra lineal es una de las herramientas matemáticas básicas que necesitamos en ciencia de datos. Comprender estos conceptos mejora tu entendimiento de muchos algoritmos. Es, de verdad, una base excelente para una trayectoria en data science y machine learning.
\nEl objetivo de este tutorial es entrar en las matemáticas para ciencia de datos programando con Python/Numpy. Tener tutoriales prácticos sobre temas teóricos como el álgebra lineal puede ser muy útil, porque escribir y leer código es una gran forma de interiorizar conceptos matemáticos. Y, sobre todo, ¡puede ser muy divertido!
\nNo hay prerrequisitos específicos, pero si no tienes claro qué es una matriz o cómo hacer el producto punto, los primeros posts (1 a 4) de mi serie sobre el libro de deep learning de Ian Goodfellow son un buen comienzo.
\nEn este tutorial veremos un concepto importante para machine learning y deep learning: la norma. La norma se usa muchísimo, por ejemplo, para evaluar la calidad de un modelo. Al terminar, tendrás una mejor intuición de este concepto y por qué es tan valioso en machine learning. También veremos cómo se usa la derivada de la norma para entrenar un algoritmo de machine learning.
\nConfiguración básica
\nAntes de nada, vamos a preparar las librerías que usaremos:
\n\nY añadimos algunos atajos en LaTeX a los comandos
\n\nbspara símbolos en negrita ynormpara el símbolo de la norma:$$ \\newcommand\\bs[1]{\\boldsymbol{#1}} \\newcommand\\norm[1]{\\left\\lVert#1\\right\\rVert} $$
\nLo último es ajustar la apariencia de los gráficos que vamos a crear:
\n\n\nUn ejemplo práctico
\nEmpecemos con un ejemplo sencillo. Imagina que tienes un conjunto de canciones con diferentes características. Ahora quieres crear un modelo que prediga la duración de una canción en función de otras variables como el género musical, la instrumentación, etc. Entrenas un modelo y ahora quieres evaluarlo al predecir la duración de una nueva canción. Una forma de hacerlo es tomar datos nuevos y predecir la duración con tu modelo. Como conoces la duración real de cada canción para estas observaciones, puedes comparar la duración real y la predicha en cada caso. Tienes los siguientes resultados en segundos para 7 observaciones:
\n\nEstas diferencias se pueden interpretar como el error del modelo. Un modelo perfecto tendría solo 0, mientras que un modelo muy malo tendría valores enormes positivos o negativos.
\nAhora imagina que pruebas otro modelo y obtienes las siguientes diferencias entre la duración predicha y la real:
\n\n¿Qué puedes hacer si quieres encontrar el mejor modelo? Una forma natural es sumar los valores absolutos de estos errores. Usamos el valor absoluto porque un error negativo (duración real menor que la predicha) también es un error. Cuanto menor sea el error total del modelo, mejor:
\n\n\n\n\nParece que el modelo 1 es bastante mejor que el modelo 2.
\n¡Enhorabuena! ¡Acabas de calcular la norma del vector de errores de cada modelo!
\nIntuición
\nPuedes pensar en la norma como la longitud del vector. Para hacernos una idea gráfica, retomemos el ejemplo anterior. Los vectores de error son multidimensionales: hay una dimensión por observación. En el último ejemplo, 7 observaciones implicaban 7 dimensiones. Aún es difícil representar 7 dimensiones, así que simplifiquemos y quedémonos con solo 2 observaciones:
\n\nAhora podemos representar estos vectores considerando que el primer elemento del array es la coordenada x y el segundo es la coordenada y. Empezaremos escribiendo una función para dibujar los vectores fácilmente y hacernos una idea de su representación.
\nCómo representar vectores con Python y Matplotlib
\nQueremos una función que nos ayude a dibujar los vectores. Empecemos por cómo la usaríamos. Queremos pasar una lista de arrays con las coordenadas de los vectores y obtener una gráfica de esos vectores. Digamos que también podemos pasar un array de colores para diferenciarlos en la gráfica. En resumen, nos gustaría llamar a la función así:
\n\nEscribamos esta función:
\n\nToma como entrada un array de vectores a dibujar (
\nvecs) y sus colores (cols). Si en el vector solo se indican 2 dimensiones, el origen es (0, 0). Por debajo, iteramos sobre el array de vectores y usamosplt.quiver()para representarlos.Usemos la nueva función para dibujar los errores de los modelos 1 y 2:
\n\nNota: no incluimos
\nplt.show()en la función para poder añadir ajustes a la gráfica como, por ejemplo, los límites.Nota 2: usamos los colores de seaborn manualmente con sns.color_palette()
\nAsí tenemos un vector de error por cada modelo. El mejor modelo es el que corresponde al vector más corto. Una forma de calcular la longitud de los vectores es usar el teorema de Pitágoras: $\\sqrt{x^2+y^2}$. Podemos calcular la longitud de los dos vectores:
\n\n\n\n\n¡Enhorabuena! Has calculado otra norma de los vectores de error. La longitud del vector de error del primer modelo es $22.36$ y la del segundo ronda los $16.64$. En este caso, el segundo modelo es mejor, pero recuerda que solo hemos usado los dos primeros valores.
\nPrimero calculamos la suma de los errores, pero también podemos usar el teorema de Pitágoras para calcular la norma de un vector. Son dos normas distintas, lo que muestra que hay varias maneras de calcular normas.
\nFunciones de norma: definiciones
\nLa norma de un vector puede ser cualquier función que mapee un vector a un valor positivo. Se pueden usar funciones distintas y veremos algunos ejemplos. Estas funciones pueden llamarse normas si cumplen las siguientes propiedades:
\n\n- \n
\n- \n
\n- \n
\n- \n
\n
\nLas normas son valores no negativos. Si piensas en la norma como una longitud, verás por qué no puede ser negativa.
\nLa norma es $0$ si y solo si el vector es el vector nulo.
\nLas normas cumplen la desigualdad del triángulo. Ver más abajo.
\n$\\norm{k\\cdot \\bs{u}}=\\norm{k}\\cdot\\norm{\\bs{u}}$. Aquí, $k$ es un escalar y $\\bs{u}$ un vector. La norma de un vector multiplicado por un escalar es igual al valor absoluto de ese escalar multiplicado por la norma del vector.
\nSuele escribirse con dos barras verticales: $\\norm{\\bs{x}}$
\nLa desigualdad del triángulo
\nHemos visto arriba que una condición para que una función sea una norma es que cumpla la desigualdad del triángulo. Significa que la norma de la suma de unos vectores es menor o igual que la suma de las normas de esos vectores:
\nEjemplo 1.
\nPara ilustrarlo, tomaremos dos vectores, cada uno con dos elementos (útiles de nuevo para representarlos como coordenadas x e y). Nuestros vectores son:
\ny
\nComparemos:
\ny:
\nMás adelante veremos distintos tipos de normas, pero por ahora usaremos la clásica: la norma euclídea ($L^2$). La norma $L^2$ se puede calcular con la función de Numpy
\nnp.linalg.norm()(ver más detalles en la documentación).Más adelante veremos en detalle qué son las normas $L^1$ y $L^2$.
\n\n\ny
\nVemos que se cumple la desigualdad del triángulo, ya que:
\nExplicación gráfica
\nVerás que la representación gráfica de este teorema lo hace bastante trivial. Dibujaremos los vectores $\\bs{u}$, $\\bs{v}$ y $\\bs{u}+\\bs{v}$ usando nuestra función
\n\nplotVectorsy añadiendo texto para identificarlos:La longitud de $\\bs{u}$ más la de $\\bs{v}$ es mayor que la longitud del vector $\\bs{u}+\\bs{v}$. Geométricamente, ¡esto no es más que decir que el camino más corto entre dos puntos es una línea!
\nNormas p: reglas generales
\nHemos visto las condiciones que debe cumplir una función para llamarse norma. Esto significa que hay varias funciones que se pueden usar como normas. Más adelante veremos pros y contras de cada una. Llamamos $p$-norma a la siguiente familia de funciones que dependen de $p$:
\nVamos a desglosar esta ecuación paso a paso. Vemos que hay una suma de elementos, así que podemos pensar en una iteración sobre los elementos $i$:
\n\n- $\\vert\\bs{x}_i\\vert$ Calcula el valor absoluto del elemento $i$
\n- $\\vert\\bs{x}_i\\vert^p$ Eleva a la potencia $p$
\n- $\\sum_i\\vert\\bs{x}_i\\vert^p$ Suma todos esos absolutos elevados
\n- $(\\sum_i\\vert\\bs{x}_i\\vert^p)^{1/p}$ Eleva el resultado a la potencia $\\frac{1}{p}$
\n
\nQuedará claro con ejemplos usando estas $p$-normas tan extendidas.
\nLa norma $L^0$
\nSi $p=0$, la fórmula queda:
\nVeamos qué implica. Elevar al exponente 0 valores absolutos te da un $1$ para cada valor distinto de $0$ y un $0$ para los ceros.
\nPor tanto, esta \"norma\" corresponde al número de elementos no nulos del vector. En rigor no es una norma, porque si multiplicas el vector por $\\alpha$, este número no cambia (regla 4 de arriba).
\nLa norma $L^1$
\nSi $p=1$, simplemente tenemos la suma de los valores absolutos. Es lo que usamos de forma intuitiva al principio de este tutorial:
\nLa norma $L^2$ (norma euclídea)
\nLa norma euclídea es la $p$-norma con $p=2$. Probablemente es la más usada junto con la norma $L^2$ al cuadrado (ver más abajo).
\nObserva que ya no necesitamos el valor absoluto porque $x$ está al cuadrado. Es lo que usamos al calcular la longitud de nuestros vectores con el teorema de Pitágoras.
\nVeamos otro ejemplo de esta norma:
\nEjemplo 2.
\nGráficamente, la norma euclídea corresponde a la longitud del vector desde el origen hasta el punto obtenido por la combinación lineal (teorema de Pitágoras). Veremos un ejemplo en 2 dimensiones: el vector $\\bs{u}$ tiene dos valores que corresponden a la coordenada $x$ y la coordenada $y$. Si representas el punto con esas coordenadas y dibujas un vector desde el origen hasta ese punto, la norma $L^2$ será la longitud de ese vector.
\nPor ejemplo:
\nEmpecemos calculando la norma con la fórmula:
\nAsí que la norma $L^2$ es $5$.
\nPor cierto, recuerda que la norma $L^2$ se puede calcular con la función
\n\n\nlinalg.norm()de Numpy:Aquí tienes la representación gráfica del vector:
\n\nVemos que el vector va del origen (0, 0) a (3, 4) y que su longitud es 5.
\nEn este caso, el vector está en un espacio de 2 dimensiones, pero esto se mantiene en más dimensiones.
\nLa norma euclídea al cuadrado (norma $L^2$ al cuadrado)
\nLa norma $L^2$ al cuadrado es cómoda porque elimina la raíz cuadrada y nos quedamos con la simple suma de cada valor del vector al cuadrado.
\nLa norma euclídea al cuadrado se usa mucho en machine learning en parte porque se puede calcular con la operación vectorial $\\bs{x}^\\text{T}\\bs{x}$. Puede haber mejoras de rendimiento gracias a la optimización. Ver aquí y aquí para más detalles.
\nEjemplo 3.
\nVeremos en este ejemplo que la norma euclídea al cuadrado puede calcularse con operaciones vectorizadas. Empecemos con un vector $\\bs{x}$:
\nComo siempre, usaremos código para comprobar el proceso. Primero, creemos nuestro vector de Numpy $\\bs{x}$:
\n\n\nAhora tomemos la traspuesta de este vector. Esto convierte el vector columna inicial en un vector fila:
\nPodemos calcular la traspuesta de $\\bs{x}$ con el método
\n\n\nTde los objetos de Numpy:El producto punto de $\\bs{x}$ y $\\bs{x}^\\text{T}$ (ver aquí si necesitas recordar el producto punto) corresponde, de hecho, a multiplicar cada elemento por sí mismo:
\n¡Esto es exactamente la definición de la norma euclídea al cuadrado!
\nComprobémoslo con Numpy. Recuerda (y pruébalo para convencerte) que el orden del vector en el producto punto importa:
\n\n\n¡Debería ser nuestra norma euclídea al cuadrado! Calculemos la norma $L^2$ y elevémosla al cuadrado para verificarlo:
\n\n\n¡Funciona! La posibilidad de usar una operación vectorizada es una gran ventaja respecto a otras normas.
\nDerivada de la norma $L^2$ al cuadrado
\nHemos visto que las normas pueden usarse para evaluar la calidad de un modelo resumiendo los vectores de errores.
\nAhora queremos ir un paso más allá y saber cómo cambiar los parámetros del modelo para reducir el error total. Para ello podemos usar una función de coste que asocie el error del modelo en función de los valores de los parámetros. El algoritmo de descenso de gradiente se puede usar para encontrar el mínimo de esta función. El descenso de gradiente se hace calculando las derivadas respecto a cada parámetro (derivadas parciales = gradientes). Por eso es crucial poder calcular la derivada de forma eficiente.
\nDe hecho, una gran ventaja de la norma $L^2$ al cuadrado es que su derivada parcial se calcula muy fácilmente. Consideremos el siguiente vector:
\nHemos visto que su norma $L^2$ al cuadrado se calcula como:
\nLuego, para calcular las derivadas parciales, consideramos todas las demás variables como constantes. Por ejemplo, la derivada parcial respecto a $u_1$ es la derivada de $u_1^2+a$ (siendo $a$ la constante que corresponde al resto de variables). Por esta razón, tenemos las siguientes derivadas parciales:
\nLo bueno de los gradientes de la norma $L^2$ al cuadrado es que las derivadas no dependen de las otras variables. Veremos que no es el caso con la norma $L^2$.
\nDerivada de la norma $L^2$
\nEn el caso de la norma $L^2$, la derivada es más compleja y tiene en cuenta todos los elementos del vector. Tomemos como ejemplo el último vector $\\bs{u}$. La norma $L^2$ es:
\nCalculemos su derivada respecto a $u_1$:
\nVemos que la derivada parcial respecto a $u_1$ sigue conteniendo $u_2...u_n$. El resto de gradientes siguen la misma estructura:
\nOtras consideraciones
\nLa norma $L^2$ al cuadrado es estupenda, pero tiene un problema: discrimina poco entre 0 y valores pequeños porque la función crece lentamente.
\nPodemos verlo comparando gráficamente la norma $L^2$ al cuadrado con la norma $L^2$. El eje $z$ corresponde al valor de la norma y los ejes $x$ e $y$ a dos parámetros. Lo mismo ocurre con más de 2 dimensiones, pero sería difícil de visualizar.
\nNorma $L^2$:
\nNorma $L^2$ al cuadrado:
\nPara comparar, aquí tienes la norma $L^1$:
\nEstas gráficas se han hecho con ayuda de este sitio web. Entra y dibuja estas normas si necesitas moverlas para captar su forma.
\nLa norma máxima
\nEs la norma $L^\\infty$ y corresponde al valor absoluto del mayor elemento del vector.
\nNormas de matrices: la norma de Frobenius
\nEquivale a tomar la norma $L^2$ de la matriz aplanada.
\nSe puede usar la misma función de Numpy:
\n\n\n\n\nExpresión del producto punto con normas
\nEl producto punto entre los vectores $\\bs{x}$ y $\\bs{y}$ se puede recuperar con las normas $L^2$ de estos vectores. $\\theta$ es el ángulo entre ambos.
\nEjemplo 4.
\nTomemos dos vectores en 2 dimensiones:
\ny
\nLa siguiente gráfica muestra su representación:
\n\n\nElegimos este ejemplo por su sencillez. Como vemos, el ángulo $\\theta$ es de 45°.
\nPrimero, calculemos el producto punto de los vectores:
\nY ahora calculemos sus normas:
\ny
\nCon la fórmula anterior, tenemos:
\nEs el mismo resultado que con el producto punto. Aquí están las operaciones con numpy. Ten en cuenta que usamos la función
\n\n\ndeg2radde Numpy porquenp.costoma el ángulo en radianes, así que hay que convertirlo.Conclusión
\nLa norma $L^2$ (o la norma de Frobenius en el caso de una matriz) y la norma $L^2$ al cuadrado se usan ampliamente en machine learning, deep learning y ciencia de datos en general. Por ejemplo, las normas pueden usarse como funciones de coste. Imagina que quieres ajustar una recta a un conjunto de puntos. Una forma de encontrar la mejor recta es empezar con parámetros aleatorios e iterar minimizando la función de coste. La función de coste representa el error de tu modelo, así que quieres que ese error sea lo más pequeño posible. Las normas son útiles aquí porque te dan una manera de medir ese error. La norma transforma el vector que contiene todos tus errores en un escalar simple, y la función de coste es ese escalar para un conjunto de valores de tus parámetros.
\nHemos visto que las normas no son más que reducir un array a un escalar. También hemos visto que hay variaciones según la función que usemos para calcularla. Elegir qué norma usar depende mucho del problema a resolver, ya que hay pros y contras para aplicar una u otra. Por ejemplo, la norma $L^1$ es más robusta que la $L^2$. Esto significa que la $L^2$ es más sensible a valores atípicos, ya que errores grandes se convierten en errores enormes al cuadrado.
\nEste tutorial se basa en este artículo de mi serie sobre el capítulo de álgebra lineal del Deep Learning Book de Goodfellow et al.
\nReferencias
\nhttps://www.quora.com/Why-is-L1-regularization-better-than-L2-regularization-provided-that-all-Norms-are-equivalent
\nhttp://www.deeplearningbook.org/contents/linear_algebra.html
\nhttps://docs.scipy.org/doc/numpy-1.14.0/reference/generated/numpy.linalg.norm.html
\nhttps://hadrienj.github.io/deep-learning-book-series-home/
\nhttp://christopher5106.github.io/deep/learning/2016/09/16/about-loss-functions-multinomial-logistic-logarithm-cross-entropy-square-errors-euclidian-absolute-frobenius-hinge.html
\nhttps://datascience.stackexchange.com/questions/10188/why-do-cost-functions-use-the-square-error