Machine Learning para principiantes, regresión lineal en sklearn

Introducción al machine learning

Estoy seguro de que no es la primera vez que escuchas el término de aprendizaje automático o machine learning en Inglés. Estoy también seguro de que lo habrás oído muchas veces relacionado con otras buzzwords como la inteligencia artificial, redes neuronales, deep learning o la regresión lineal, de la que hablaremos en este post.

Tantos términos pueden dar lugar a confusión, y de hecho muchas veces se usan de manera errónea. Vamos a dar una breve definición de cada uno para ponernos en contexto:

  • Deep Learning: Es un subconjunto del machine learning, y se basa en algoritmos que pueden ser entrenados para realizar ciertas tareas como reconocer el contenido de una imagen o voz. Usan grandes redes neuronales con gran cantidad de capas.
  • Machine Learning: Es un subconjunto de la inteligencia artificial, que a través de diferentes algoritmos y técnicas (fundamentadas en la estadística) permiten a las máquinas aprender con la experiencia. Engloba el deep learning.
  • Inteligencia artificial: Es un concepto mas general, que tiene como objetivo imitar el comportamiento humano usando diferentes tipos de lógica, como redes neuronales, árboles de decisión o deep learning.

En este post os hablaremos de la regresión lineal, un concepto que se podría englobar dentro del machine learning. Se trata de un modelo matemático usado para modelar la relación entre una variable dependiente y otra(s) independiente(s), asumiendo como su propio nombre indica una relación lineal.

Aunque como hemos dicho se podría englobar dentro del machine learning, cualquier estadístico con alguna que otra cana se reiría. El concepto de machine learning es relativamente nuevo, pero la regresión data de varios siglos atrás y se le atribuye a Francis Galton.

De hecho este meme se hizo popular debido precisamente a esto. El machine learning no es otra cosa que estadística de toda la vida con algún que otro adorno.

¿Qué es una regresión lineal?

En estadística, una regresión lineal es un modelo matemático que permite modelar la relación entre una variable dependiente, típicamente y y una o varias variables independientes x_i.

Veamos un ejemplo sencillo con una sola variable independiente. Imagínate que estamos haciendo un estudio del precio de las casas en una determinada zona, y para ello tenemos una sola característica, que es el número de metros cuadrados. Tenemos por lo tanto una gráfica con el precio vs los metros.

En este caso, la variable independiente son los metros cuadrados de la vivienda, y la variable dependiente el precio. Podríamos representarlo en una gráfica de la siguiente forma.

Una regresión lineal es un modelo con la formay = m*x + n (para el caso de una variable dependiente) que de alguna manera permite generalizar en base a unos datos conocidos a priori y darnos el poder de predecir el precio que tendrá una vivienda con unos metros cuadrados determinados.

Para este ejemplo, el modelo resultante sería precio = metros*1525 + 57223 y al final del post os explicaremos como calcularlo usando sklearn. Algunos ejemplos que usan nuestro modelo:

  • Para una casa de 35 metros cuadrados, el precio sería 107.573 €
  • 1200 metros cuadrados, el precio sería 1.888.146 €

Es muy importante tener en cuenta lo siguiente:

  • Se asume que la relación precio/metros es lineal, pero podría no serlo. En el caso de no serlo, evidentemente no se podría usar un modelo lineal para modelar un comportamiento no lineal.
  • Por otro lado, es importante conocer los límites del modelo. Una casa con 0 metros cuadrados costaría 57223 €. ¿Es esto válido?
  • Dependiendo de lo que estemos intentando modelar, tal vez nos falten variables ya que puede ser que una sola no sea lo suficientemente representativa. De hecho en el caso de la vivienda los metros cuadrados no son suficientes. Un modelo más completo incluiría si la casa esta reformada, año de construcción o vecindario.

Función coste

Uno de los pilares básicos de muchos conceptos estadísticos y del machine learning en general, es la función coste. En el ejemplo anterior hemos calculado una recta que generalizaba los puntos, pero claro, para calcular esa recta hay que aplicar algún criterio.

Desde un punto de vista más conceptual y menos matemático es fácil, podríamos dibujarla a mano alzada, intentando que mantuviera la misma distancia de todos los puntos. El problema es que los algoritmos sólo entienden números.

En concreto la regresión lineal entiende lo que se denomina como función de coste, y viene a representar lo que se aleja nuestro modelo de la realidad. Dicha función se conoce como Mean Squared Error o MSE y simplemente calcula la diferencia entre las predicciones y el valor real, lo eleva al cuadrado y lo divide entre el número de muestras. Es una forma de medir lo que nuestro modelo se aleja de la realidad.

J = \frac{1}{n}\sum_{i=1}^{n}(pred_i - y_i)^2

Por lo tanto, la principal tarea del algoritmo de regresión lineal es literalmente ir probando valores de m y n en nuestro modelo y = m*x + n intentando que el coste J sea el mínimo. El proceso sería algo así:

  • Paso 0: Se empieza con unos valores de m y n.
  • Paso 1: Se calcula el coste J tal y como hemos visto.
  • Paso 2: Se modifican los parámetros aplicando un criterio que veremos a continuación.
  • Se vuelve al paso 1, y se empieza de nuevo.

Este proceso se realiza un número de veces que puede ser determinado o hasta que después de varias iteraciones no hemos obtenido mejora. Si no hay mejora, asumimos que no se puede mejorar más, y se termina el algoritmo.

Gradient descent

Anteriormente en el Paso 2 hemos dicho que se modifican los parámetros siguiendo un determinado criterio. No tendría ningún sentido modificarlos de manera aleatoria, ya que una vez se incrementaría el error y otras disminuiría.

El gradient descent nos da una pista de cómo debemos modificar los parámetros de nuestro modelo para que el error se reduzca.

Se puede entender muy bien con el símil de una montaña. Imaginemos que estamos en la cima y queremos llegar abajo, pero desde donde estamos no vemos el punto más bajo.

Sin embargo si que podemos ver algunos puntos que están más bajos de donde nos encontramos. Tendría sentido elegir bajar por el camino que veamos que nos puede llevar al punto más bajo dentro de los que vemos.

Desde el nuevo punto podremos ver otro punto más bajo y así sucesivamente hasta que por fin habremos llegado a la base.

El gradient descent es exactamente lo mismo, y desde un punto de vista matemático lo que hace es calcular la derivadas parciales de la función con respecto a los parámetros, en nuestro caso m y n. Dicha operación, representa la pendiente. Volviendo al símil, siempre intentaremos ir por el camino que tenga mayor pendiente, pues llegaremos más pronto al mínimo.

Existe otro parámetro conocido comúnmente como \alpha y es el learning rate. Se trata de un parámetro configurable muy importante, porque una mala configuración puede hacer que nunca lleguemos al mínimo. En la siguiente imagen podemos ver que pasa si se usa un learning rate demasiado grande o pequeño.

 Regresión lineal con sklearn

Ahora que ya tenemos la base teórica vamos a ver como podemos implementar con código de una manera muy sencilla nuestro modelo para predecir el precio de las casas.

Vamos a hacer uso de una librería llamada scikit-learn, también referida como sklearn. Usaremos también la librería numpy para tratar los arrays y matplotlib para los gráficos.

El primer paso es importar todo.

import matplotlib.pyplot as plt
import numpy as np
from sklearn.linear_model import LinearRegression

Ahora necesitamos unos datos para entrenar nuestro modelo. Tenemos un total de 8 viviendas, la primera de 75 metros cuadrados y 180.000 €, la segunda de 60 y 150.000, etc.

# Nuestro dataset. Metros cuadrados vs precios
metros_cuadrados = np.array([[75, 60, 55, 80, 120, 130, 145, 100]]).T
precios = np.array([[180000, 150000, 135000, 210000, 230000, 250000, 300000, 170000]]).T

Ahora vamos a crear un objeto de la clase que nos proporciona sklearn llamada LinearRegression. Dicha clase nos permite entrenar un regresor lineal ref. Usando el método fit, podemos pasarle los valores x e y (variable dependiente e independiente que hemos visto antes) y sklearn se encargará de iterar calculando el coste y el gradient descent hasta dar con los parámetros más óptimos.

# Regresor lineal
modelo = LinearRegression()
# Entrenamos el modelo con los datos existentes
modelo.fit(metros_cuadrados, precios)

Y una vez tenemos nuestro modelo entrenado en modelo, podemos realizar predicciones nuevas sobre otras casas con diferentes metros cuadrados, en este caso de 50, 60, etc.

valores_a_predecir = np.array([[50, 60, 55, 80, 120, 130, 145, 150]]).T
y_predichos = modelo.predict(valores_a_predecir)

En el siguiente ejemplo realizamos predicciones para 33 metros y 1200.

print(modelo.predict(np.array([[33]])))
print(modelo.predict(np.array([[1200]])))
# [[107573.71154614]]
# [[1888146.22453056]]

Con los siguientes comandos podemos representar la gráfica.

plt.scatter(metros_cuadrados, precios)
plt.plot(valores_a_predecir, y_predichos, 'r')
plt.legend(["Regresión Lineal", "Datos"])
plt.title('Precio de casas vs metros cuadrados (cursospython.com)')
plt.xlabel('Metros cuadrados')
plt.ylabel('Precio (Eur)')

Y haciendo uso de coef_ y intercept_ obtendremos nuestro modelo en forma y = m*x + n.

print(f"Modelo: precio = {round(modelo.coef_[0,0])}*metros + {round(modelo.intercept_[0])}")
# Modelo: precio = 1526.0*metros + 57223.0

Modelo: precio = 1526.0*metros + 57223.0

¡Deja un comentario!

avatar
  Subscribe  
Notify of