Introducción a Machine Learning I

Image by Manfred Steger

Este post es el primero de muchos que iré publicando, a medida que vaya avanzando en el curso de Machine Learning de Andrew Ng, curso ofrecido por la universidad de Stanford en la plataforma Coursera.

El objetivo de estos posts es doble. Por un lado, ser una increíble forma de resumir lo aprendido y tenerlo accesible siempre que lo necesite, y por otro, compartirlo con todo aquel que pueda encontrarlo interesante.

Machine Learning vs Programación Tradicional

La diferencia entre la programación tradicional y Machine Learning es que, mientras en la primera el código es estático (las operaciones que se ejecutan son siempre las mismas), en Machine Learning los algoritmos se adaptan automáticamente a un conjunto de datos de partida y la propia salida que estos generan. Por eso se dice que el ordenador aprende.

Estos tipos de algoritmos son especialmente útiles para, entre otras aplicaciones, la explotación de bases de datos como por ejemplo registros médicos; aplicaciones de reconocimiento de caracteres (OCR); drones auto guiados o, también, para aplicaciones personalizadas donde el usuario recibe recomendaciones, tipo Netflix o Amazon.

Los algoritmos que desarrolla el ML se pueden clasificar de varias maneras, pero la forma mas común es estos dos grandes bloques:

  • Aprendizaje supervisado: donde se le enseña cómo hacer algo.
  • Aprendizaje no supervisado: donde se le deja que actúe sólo.

Aprendizaje Supervisado

El aprendizaje supervisado consiste básicamente en la generación de una función matemática a partir del análisis de un conjunto de datos de entrada (training data), que se aproxime lo máximo posible a esos datos. La formula devolverá un valor numérico (regresión) o una etiqueta (clasificación) dependiendo del tipo de problema que tratemos de resolver. Como siempre, lo mejor es ver a que me refiero con un par de ejemplos:

Problema de Regresión.

Imaginemos que tenemos la siguiente tabla sobre viviendas vendidas en base a su tamaño, y queremos crear un programa que nos dé el precio aproximado de un vivienda, una vez proporcionado su tamaño.

Una aproximación al problema con programación tradicional sería asignar un valor al metro cuadrado, y hacer la multiplicación correspondiente, ¿verdad? Tendríamos entonces el precio medio por metro cuadrado.

Si somos capaces de generar una ecuación lineal que se aproxime a los training data que tenemos, podremos dar una estimación más acertada a futuros valores de entrada. Como se ve en el gráfico, podríamos utilizar dos ecuaciones lineales diferentes como solución.

Fíjate que según la ecuación que utilicemos el resultado será más o menos preciso. Qué algoritmos nos ayudan a encontrar la mejor regresión posible es algo que veremos más adelante.

Problema de Clasificación.

Imaginemos que disponemos de un historial médico sobre cáncer de mama. En él, tenemos asociados una serie de cánceres benignos y malignos en base a su tamaño. Y queremos hacer un programa que nos diga, en base al tamaño del cancer de mama, si puede ser maligno o benigno.

En estos casos tendremos que trazar una frontera que nos ayude a separar nuestras categorías. Podemos tener una sola variable, como se muestra en el primer diagrama, o multiples variables, como se muestra en el segundo diagrama.

En este caso, no devolvemos un valor numérico, no tenemos que realizar ningún cálculo matemático. Siempre será un valor discreto como por ejemplo: sí o no, o spam o no spam.

Aprendizaje No Supervisado

La gran diferencia con el supervisado es que, aquí el algoritmo no conoce o conoce muy poco los datos de entrada. El algoritmo tiene que identificar estructuras a partir de los datos. Un ejemplo claro es Google News, que es capaz de agrupar links que tratan sobre la misma noticia.

Los algoritmos más típicos del aprendizaje no supervisado, y de los que escribiré más adelante, son:

  • Agrupación (Clustering).
  • Detección de anomalías.
  • Redes neuronales.

Ejemplo de clustering sería coger una muestra de un millón de genes, y encontrar la forma de agrupar automáticamente estos genes que de alguna manera sean similares o estén relacionados con variables como, esperanza de vida, ubicación, trabajos, etc.




Analizados los dos grandes grupos de problemas que cubre el ML, ya estamos en disposición de ver nuestro primer algoritmo, que utilizaremos para resolver problemas sencillos de regresión.

Regresión Lineal Simple o de 1 Variable

Como hemos visto en la definición de problema de regresión, la idea principal es encontrar una función lineal que recorra lo más cerca posible a nuestros datos, y nos permita así, poder hacer una estimación para un nuevo valor. Este modelo matemático que vamos a ver es el más simple de todos y perfecto como introducción. Y como sabemos, en una ecuación lineal, si sólo contamos con una variable, ésta será una línea recta.

Para describir estos problemas de manera más formal introducimos el término hipótesis, y como la misma ecuación lineal simple describe, sería como sigue:

Con esta ecuación podemos representar cualquier línea recta. La pregunta ahora es: ¿qué regresión lineal aplicamos para que se ajuste al máximo a nuestro training data? Tenemos que elegir un θo y un θ1 que haga que nuestra hθ(x) se aproxime lo máximo a nuestro training data.

La respuesta a la pregunta es, mediante la Función de Coste:

No te asustes todavía, que es bien sencilla. En regresión, la suma total de los cuadrados ayuda a expresar la variación total de las y. Si la observas un poco verás que no está haciendo nada más que sumar esas diferencias que existen entre los puntos que ofrece la hipótesis que hemos elegido, y los datos que tenemos, para después calcular algo así como la media. Y como ya habrás podido adivinar, cuanto menor sea la función de coste, menor será la diferencia entre la hipótesis y nuestros datos. Vamos a verlo con un ejemplo que es como mejor se entienden las cosas. Supongamos que tenemos el siguiente training data de 3 muestras (m=3):

Es un ejemplo donde se ve claramente que y(x) = x, por lo que θo=0 y θ1=1, pero supongamos que no lo sabemos. Vamos ahora a analizar la función con una versión simplificada del problema, donde reduciremos la hipótesis a hθ(x)=θ1 o lo que es lo mismo, fijar θo=0. Ahora vamos a dar un par de valores a θ1 para ver como se comporta la función de coste:

Si probamos con θ1=1, veamos qué valor tendría nuestra función de coste:

Como se puede observar, la desviación de cada punto de la recta descrita por la función con θ1=1 es 0, por lo que la función de coste también es 0.

Vamos a ver como quedaría la función de coste con θ1=0.5:

En este caso, vemos que a medida que avanzamos, la diferencia entre nuestra hipótesis y nuestra f(y) es cada vez mayor, y por tanto nuestra función de coste crecerá exponencialmente. Por eso, si analizamos todos los posibles valores de θ1, veremos que nuestra función de coste dibuja una gráfica como la siguiente:

Pero esta representación gráfica de la función de coste es para la versión simplificada de nuestro problema. Si recuperamos la variable θo eliminada, la gráfica toma otra dimensión, literalmente hablando:

Algoritmo Gradient Descent

Como bien habréis adivinado, este algoritmo es el que nos va a ayudar a encontrar los valores de θo y θ1 que minimicen la función de coste.

Para explicar cómo funciona este algoritmo la mejor forma es viéndolo gráficamente. Imagina que tenemos un training data cuya función de coste dibuja una gráfica como ésta:

La idea básica de este algoritmo es buscar un θo y θ1 inicial cualquiera, y descender montaña abajo, como su nombre indica, hasta el punto más bajo o dicho de otra manera, hasta que empecemos a subir de nuevo.

Como ya habrás podido deducir, este algoritmo no siempre nos garantizará el valor mínimo de la función de coste, ya que dependemos de la elección del punto de partida.

Entonces, ¿cómo descendemos?

Para poder responder esta pregunta tenemos que refrescar un poco nuestras matemáticas. Si recordáis del colegio, para poder calcular la pendiente o los puntos de descenso necesitamos hacer mano de las rectas tangentes. ¿Y cómo conseguimos hallar esas tangentes? pues mediante derivadas. Y recordemos que estamos en un plano con tres dimensiones, así que el descenso deberá hacerse en los tres planos. Por tanto, el algoritmo será:

O lo que es lo mismo, una vez aplicada la derivada a la función de coste:

El símbolo α de la ecuación corresponde al Learning Rate, que define la longitud de los saltos a dar. Cuanto mayor sea α, más agresivo será el algoritmo, y aunque parezca que podemos alcanzar la solución antes, también podemos hacer que diverja o incluso saltarse un mínimo. Por otro lado, si es muy pequeño, puede que demos demasiados saltos. Así que como en casi todo en esta vida, en el termino medio está la solución: el algoritmo de gradiente descendente comienza con un Learning Rate grande y a medida que nos acercamos al mínimo, se va haciendo cada vez más pequeño.

Comentarios

Entradas populares de este blog

Envío de checkboxes o selector multiple por AJAX con jQuery

Patrones de Diseño Creacionales

Conceptos básicos de la POO