Gráfica de velas

Aprendizaje automático con Scikit-learn (Parte #2): Regresión lineal

Contenido

En el anterior artículo hemos visto como el aprendizaje automático se ha utilizado para resolver un problema de clasificación. Estos problemas son bastante típicos en el campo del machine learning, pero no son los únicos que nos podemos encontrar. Otros problemas que nos podemos encontrar en el mundo del machine learning son por ejemplo los problemas de regresión lineal. Veamos a continuación cómo son estos problemas.

Centrando el problema

Los problemas de regresión son bastante habituales dentro del mundo del aprendizaje automático. Pero ¿en qué consisten exactamente? Bien, en esencia, se trata de poder obtener un valor numérico a partir de unos atributos conocidos. Puede sonar un poco abstracto pero con un ejemplo lo entenderás fácilmente.

Imagina una empresa inmobiliaria, que tiene en su base de datos un gran número de casas, pisos, etc. Para cada uno de ellos dispone de una serie de atributos: localización, superficie habitable, calificación energética, etc. Además, sabe el precio por el que el inmueble está a la venta o ha sido vendido recientemente. Pues, lo que esta empresa querría hacer es dado un nuevo inmueble que entra a su cartera, poder determinar un precio competitivo en base a sus características. Enhorabuena, ya hemos definido un problema de regresión.

¿Qué estamos haciendo realmente cuando resolvemos un problema de regresión lineal?

Cuando estamos resolviendo un problema de regresión realmente estamos ajustando una función matemática. Esto puede sonar complicado pero veremos que no lo es en absoluto. Imaginemos el siguiente dataset simple:

InstanciaRadio (cms)Precio ($)
1107
2159
31812
42015
52222
Valores para un dataset que relaciona precio de una pizza con su radio en centímetros

Este dataset nos define un problema en el que queremos obtener el precio de la pizza en base al atributo del radio (en centímetros) de la misma. Si mostramos el radio y precios de las instancias en una gráfica obtendremos la siguiente imagen:

Relación entre diámetro y precio
Relación entre diámetro y precio

En la imagen anterior podemos intuir que hay una relación entre el diámetro de nuestra pizza y el precio de la misma. Podríamos dibujar una línea recta que pasara lo más cerca posible de los puntos que hemos dibujado en la gráfica anterior. De esta forma obtendríamos la siguiente figura.

Relación entre radio y precio con recta del modelo. Podemos apreciar que se puede modelar como una regresión lineal.
Relación entre radio y precio con recta del modelo

Pues bien, esa recta no es ni más ni menos que un modelo ajustado o entrenado para el problema mínimo de regresión planteado. De forma más teórica hemos ajustado una línea recta usando la ecuación de la siguiente figura:

Ecuación de linea recta empleada
Ecuación de linea recta empleada

Siendo « el precio que queremos predecir y «x» la variable del modelo. El modelo contiene los parámetros α y β que deberán ser ajustados durante el entrenamiento. Por último, denominaremos regresión lineal a este problema, ya que hemos usado una línea recta como modelo para ajustar.

Planteando el problema de regresión lineal

Dentro de la librería Scikit-learn existen varios datasets que podemos utilizar directamente para trabajar con este tipo de problemas. Para continuar con el ejemplo planteado anteriormente, vamos a usar el dataset llamado Boston, que contiene un conjunto de datos acerca de los precios de inmuebles en la ciudad de Boston.

La forma de cargar el conjunto de datos es similar a la que ya vimos en el anterior problema de clasificación. Así, con el siguiente código realizaremos la carga del dataset.

from sklearn.datasets import load_boston

dataset = load_boston()
# Mostramos la descripción para nuestro dataset
print(dataset['DESCR'])
# Mostramos los valores de una instancia
print(dataset['data'][0])

En el código anterior hemos realizado la importación del método que carga el dataset (load_boston). Usamos dicho método para cargarlo y lo asignamos a la variable dataset. Por último hemos mostrado por pantalla la descripción del dataset.

Explicación del dataset

Lo que nos aparece por pantalla se puede resumir en los siguientes puntos:

  • El dataset contiene un total de 506 ejemplos de datos o instancias.
  • El número total de atributos que definen cada instancia son un total de 14.
  • El valor objetivo que queremos obtener es el precio.
  • Los atributos que lo componen se resumen en:
    • CRIM: Tasa de criminalidad por ciudad.
    • ZN: Proporción de zonas residenciales.
    • INDUS: Proporción de negocios no minoristas por ciudad.
    • CHAS: Variable booleana que será 1 si hay tramo de río o 0 en caso contrario.
    • NOX: Concentración de óxido nítrico en la zona.
    • RM: Número de habitaciones por vivienda.
    • AGE: Proporción de viviendas ocupadas de construcción anterior a 1940.
    • DIS: Distancias ponderadas a cinco centros de trabajo de Boston.
    • RAD: Índice de accesibilidad a autovías radiales.
    • TAX: Tasa de impuestos por cada 10.000$ de valor de la propiedad.
    • PTRATIO: Ratio alumno/profesor en la zona.
    • B: 1000(Bk – 0.63)^2 dónde Bk es la proporción de población negra de la ciudad
    • LSTAT: Porcentaje de población de clase baja en la ciudad.
    • MEDV: Valor medio de la vivienda en miles de dólares.

El dataset por lo que podemos apreciar contiene una serie de 14 atributos que son numéricos. Puesto que es el dataset que suministra la librería no es necesario que realicemos ningún preprocesamiento al mismo, ya que no tenemos valores no suministrado para algunos atributos de alguna instancia.

Tampoco nos encontraremos valores que estén en rangos muy diferentes para un atributo. Por ejemplo, imaginemos que nuestro dataset contiene un atributo de peso que varia entre 0.5 y 50000 kgs. Este atributo hará que nuestro algoritmos de machine learning se comporten mal. Este problema lo trataremos en un artículo específico sobre preprocesamiento de datasets.

Entrenando un modelo lineal

Como hemos visto anteriormente podemos usar un modelo lineal para ajustar con los valores de los atributos de nuestro dataset, y de esa manera, poder obtener las predicciones en base a nuevos ejemplos. Ya tenemos nuestro dataset cargado, por lo que ahora importaremos un modelo y realizaremos el entrenamiento del mismo.

# Importamos el modelo de regresión lineal
from sklearn.linear_model import LinearRegression
lin_reg = LinearRegression()

# Extraemos los atributos (X) y los valores objetivo (Y)
X = dataset['data']
Y = dataset['target']

# Entrenamos el modelo
lin_reg.fit(X, Y)

En la primera línea hemos importado el modelo lineal que vamos a usar para entrenar, mientras que en la segunda hemos obtenido un objeto de ese tipo. A continuación hemos extraído los valores de los atributos de las instancias (X) y los precios de cada instancia (Y). Por último hemos entrenado el modelo mediante la función fit del objeto.

Usando el modelo de regresión lineal

Una vez entrenado podemos realizar predicciones para una nueva instancia que entre en nuestra cartera de clientes. Para ello usaremos un ejemplo de nuestro dataset. A continuación tenemos el código que realiza la predicción.

# Mostramos la predicción para un ejemplo del dataset
print(lin_reg.predict([X[10]]))
# Mostramos el valor real que tiene el inmueble en nuestro dataset
print(Y[10])

En el código realizamos la predicción para el ejemplo número 11 (en Python los índice empiezan en el valor 0) de nuestro dataset. También mostramos el valor real del inmueble. Comprobamos que el error real que hemos obtenido es de casi 4000$, ya que la predicción es de 18999$ y el valor real es de 15000$.

Determinando el desempeño de nuestro modelo

Como vemos nuestras predicciones contienen un error con respecto a los valores reales que queremos predecir. Sin embargo, como podemos determinar que grado de error estamos cometiendo. Para poder realizar este medición deberemos comprobar la diferencia entre los valores de predicciones y los valores reales. Para ello usaremos una medida denominado error medio cuadrático. Este error se define mediante la siguiente fórmula:

MSE ( y , y ^ ) = 1 n samples i = 0 n samples 1 ( y i y ^ i ) 2 .

dónde estamos elevamos al cuadrado la diferencia entre el valor real y la predicción para cada instancia y obtenemos el valor medio, sumando todas esas diferencias dividiéndolas por el número de instancias. Como vemos es el error medio al cuadrado, por lo que si queremos el error medio bastaría con aplicar una raíz cuadrada al MSE obteniendo el error medio (RMSE).

A continuación podemos ver el código necesario para obtener ambas métricas de error para nuestro modelo de regresión lineal.

from sklearn.metrics import mean_squared_error
import numpy as np
preds = lin_reg.predict(X)

# Calculamos el error medio entre las predicciones del modelo con los valores reales
mse = mean_squared_error(Y, preds)
rmse = np.sqrt(mse)
print(mse)
print(rmse)

En el código vemos como importamos la métrica para calcular el error medio cuadrático e importamos la librería Numpy. En la siguiente línea obtenemos las predicciones de nuestro modelo lineal para los valores de nuestro dataset. A continuación calculamos el MSE con la función pasando como parámetro los valores reales (Y) y las predicciones (preds). Para obtener el error medio (RMSE) simplemente usamos la función de raíz cuadrada de Numpy. Por últimos mostramos los valores que hemos calculado. Podremos observar que el error medio que obtenemos está en torno a 4,679 lo que son 4679$. Esto es un valor bastante elevado para nuestro dataset ya que el precio medio de los valores que queremos predecir es de 22532 por lo que el error representa un 20.76%.

Resumiendo

Como hemos visto el modelo que hemos entrenado obtiene unos resultados que tienen un error del 20.76% del precio que pretendemos predecir. Probablemente sería necesario entrenar un modelo diferente a una regresión lineal, ya que el dataset es complejo (13 atributos) y una regresión lineal no sea capaz de modelar bien el problema. No obstante, dejaremos los modelos diferentes a la regresión lineal para artículos más avanzados.

Como en otros artículos dispones del código fuente que has visto a lo largo del texto para que puedas probarlo y hacer cambios. Concretamente está disponible en el repositorio de la web, a través de este enlace.

Bibliografía

Sugerencias

    captcha

    Comparte el artículo

    Entradas relacionadas