La regresión lineal es una de las técnicas más usadas en Machine Learning. Su fortaleza estriba en su simplicidad e interpretabilidad. La regresión polinómica, como ya veremos, es una extensión de la regresión lineal.
Índice
Regresión Lineal – Teoría
La regresión lineal es una técnica paramétrica de machine learning. Con «paramétrica» queremos decir que incluso antes de mirar a los datos, ya sabemos cuántos parámetros (o coeficientes) vamos a necesitar.
En el caso que estemos usando una sola variable, x, sabemos que una línea necesita 2 parámetros. La fórmula para la regresión lineal con una sola variable x es:
y = wx + b
El aprendizaje consiste en encontrar cuáles son los mejores parámetros (coeficientes) para los datos que tengamos. Los mejores coeficientes serán los que minimicen alguna medida de error. Para la regresión lineal usaremos el error cuadrático medio.
Ejemplo de Regresión Lineal
Hemos usado una regresión lineal para encontrar los parámetros de la línea que minimiza el error de los datos que tenemos. El proceso de aprendizaje consiste en estimar los parámetros w y b. Así nos queda que para estos datos, los mejores valores son:
w= 0.0918 \\ b = 1.2859
así que nos queda:
y = 0.0918x + 1.2859
Podemos usar este modelo de regresión lineal para estimar cuáles serán los resultados para otros valores de x. Por ejemplo, si queremos saber el resultado para x = 5, usaremos el modelo anterior y veremos que el resultado es 1.7449:
y = 0.0918 \cdotp 5 + 1.2859 = 1.7449
Este es un ejemplo muy simple. En realidad, los problemas de machine learning tienen muchas más variables. Sin embargo, he escogido este ejemplo porque es muy fácil de visualizar, explicar y entender. Espero que la intuición de este ejemplo sirva para entender lo que está pasando cuando haya más variables.
Notación
Antes de explicar el método de los mínimos cuadrados para resolver regresiones lineales, tenemos que expandir la notación. Debemos tener en cuenta que normalmente, tendremos muchas variables.
Con una variable, la ecuación para la regresión lineal es:
y = wx + b
Por conveniencia, vamos a reescribir la ecuación anterior:
y = b + wx
Cuando tengamos un dato con N variables, llamaremos al dato X. También tenemos que expandir los parámetros W para que cada parámetro vaya con una variable:
X = [x_0, x_1, x_2, ..., x_N] \\ W = [w_0, w_1, w_2, ..., w_N]
Si hacemos que
x_0 = 1, w_0 = b
nos queda una expresión equivalente a la original. Podemos ver que:
y = b + wx = w_0 x_0 + w_1 x_1
Para el caso general, la ecuación lineal quedaría:
y = WX
usando el producto matricial. Si tienes la multiplicación de matrices un poco oxidada, la versión intuitiva sería:
y = w_0 x_0 + w_1 x_1 + w_2 x_2 + ... + w_N x_N
Formato de los datos
Para que la técnica de regresión lineal pueda aprender de nuestros datos, tenemos que proporcionar los resultados y en forma de vector de M elementos, y los datos de entrada X en forma de matrix. El convenio para la matriz X es el siguiente:
- M filas: cada fila es un dato (por ejemplo, un inmueble, si queremos predecir su valor de venta)
- N columnas: cada columna es un atributo relevante (por ejemplo, cuántas habitaciones tiene, metros cuadrados, etc).
Aprendizaje: El método de los mínimos cuadrados
El proceso de aprendizaje consiste en averiguar qué parámetros W minimizan el error cuadrático medio entre los resultados reales y los estimados.
El método de los mínimos cuadrados proporciona una solución analítica. Es decir, nos da una fórmula para obtener la mejor estimación posible de W para los datos de entrada y resultados que hemos proporcionado. La fórmula es la siguiente:
\hat{W} = (X^T X)^{-1} X^T y
En la práctica hay librerías numéricas que calculan automáticamente la mejor estimación de W por nosotros. Ya veremos algún ejemplo práctico del cálculo de regresión lineal.
De momento, sólo quería indicar que dependiendo de la cantidad de datos y atributos, puede ser una operación costosa computacionalmente hablando. Fíjate que hay que transponer matrices, multiplicar matrices e invertir matrices. Todo ello muy costoso computacionalmente para grandes cantidades de datos.
Otras formas de resolver el problema de la regresión lineal
El método de los mínimos cuadrados no es la única forma de estimar los mejores parámetros W. También podemos utilizar métodos de optimización numérica tales como el gradiente descendiente.
El gradiente descendiente va a servir no sólo para resolver regresiones lineales y polinómicas sino que es también fundamental para el aprendizaje automático de redes neuronales y aprendizaje profundo.
Ejemplo del uso del método de los mínimos cuadrados
Carl Friedrich Gauss
Carl Friedrich Gauss es famoso, entre otras muchas contribuciones, por la distribución Gaussiana o el método de los mínimos cuadrados para resolver regresiones lineales.
Cuentan que la primera aplicación del método de los mínimos cuadrados fue la determinación de la posición de Ceres. Ceres es un asteroide que se «perdió» a los 40 días de descubrirse. Realmente no se perdió, sino que al acercarse a la claridad del Sol, dejó de verse.
Varios científicos y astrónomos intentaron localizar Ceres. La única información que tenían eran los datos de su observación durante 40 días. Gauss fue el único capaz de predecir dónde se encontraría el asteroide Ceres cuando abandonó la parte del firmamento tan iluminada por el Sol. Para ello, Gauss usó el método de los mínimos cuadrados.
A finales de 1801 los astrónomos encontraron el asteroide Ceres exactamente donde Gauss predijo que estaría.
Regresión Lineal en Python
Para hacer una regresión lineal en python, vamos a usar scikit-learn, que es una librería de python para aprendizaje automático. En particular, la clase LinearRegression implementa la funcionalidad descrita en la parte teórica de este artículo. Vamos a explicarlo con un ejemplo.
Datos de ejemplo
Primero vamos a generar unos datos que siguen una línea, y le añadimos ruido gaussiano. Para ello usaremos la librería de python NumPy. La fórmula que he usado para generar los datos es:
y = 0.1x + 1.25 + N(0, 0.2)
El código en python quedaría así:
import numpy as np #Librería numérica import matplotlib.pyplot as plt # Para crear gráficos con matplotlib %matplotlib inline # Si quieres hacer estos gráficos dentro de un jupyter notebook from sklearn.linear_model import LinearRegression #Regresión Lineal con scikit-learn def f(x): # función f(x) = 0.1*x + 1.25 + 0.2*Ruido_Gaussiano np.random.seed(42) # para poder reproducirlo y = 0.1*x + 1.25 + 0.2*np.random.randn(x.shape[0]) return y x = np.arange(0, 20, 0.5) # generamos valores x de 0 a 20 en intervalos de 0.5 y = f(x) # calculamos y a partir de la función que hemos generado # hacemos un gráfico de los datos que hemos generado plt.scatter(x,y,label='data', color='blue') plt.title('Datos');
Este código genera los datos que se ven en la siguiente imagen:
Datos de ejemplo para hacer una regresión lineal: y = 0.1*x + 1.25 + N(0, 0.2)
Entrenando un modelo de Regresión Lineal en python
Para entrenar el modelo, simplemente tendremos que hacer uso de scikit-learn. El método fit se encarga de ajustar los parámetros de regresión lineal a los datos.
# Importamos la clase de Regresión Lineal de scikit-learn from sklearn.linear_model import LinearRegression regresion_lineal = LinearRegression() # creamos una instancia de LinearRegression # instruimos a la regresión lineal que aprenda de los datos (x,y) regresion_lineal.fit(x.reshape(-1,1), y) # vemos los parámetros que ha estimado la regresión lineal print('w = ' + str(regresion_lineal.coef_) + ', b = ' + str(regresion_lineal.intercept_)) # resultado: w = [0.09183522], b = 1.2858792525736682
Como vemos, la regresión lineal casi ha averiguado cómo hemos generado los datos:
- Estima 0.092 en lugar de 0.1 para w
- Estima 1.286 en vez de 1.25 para b
Este pequeño error es normal debido a la cantidad de ruido gaussiano que hemos introducido y al hecho de que hay muy pocos datos.
Prediciendo con Regresión Lineal en python
Una vez que tenemos entrenado el modelo de regresión lineal, podemos hacer predicciones usando el método predict de la clase LinearRegression. Por ejemplo, si quisiéramos saber qué valor de y corresponde para x=5 usamos este código.
# vamos a predicir y = regresion_lineal(5) nuevo_x = np.array([5]) prediccion = regresion_lineal.predict(nuevo_x.reshape(-1,1)) print(prediccion) # resultado: [1.7449]
Así vemos, que la estimación de la regresión lineal del modelo que acabamos de entrenar para x = 5 es y = 1.7449.
Evaluando la calidad de la regresión lineal
Vamos a evaluar la calidad del modelo aprendido usando solamente los datos de entrenamiento. Recuerda que en un problema real, hay que evaluar también la capacidad de generalización del modelo. Podemos evaluar la calidad del modelo midiendo el error cuadrático medio y el coeficiente de determinación R2.
Error Cuadrático Medio
# importamos el cálculo del error cuadrático medio (MSE) from sklearn.metrics import mean_squared_error # Predecimos los valores y para los datos usados en el entrenamiento prediccion_entrenamiento = regresion_lineal.predict(x.reshape(-1,1)) # Calculamos el Error Cuadrático Medio (MSE = Mean Squared Error) mse = mean_squared_error(y_true = y, y_pred = prediccion_entrenamiento) # La raíz cuadrada del MSE es el RMSE rmse = np.sqrt(mse) print('Error Cuadrático Medio (MSE) = ' + str(mse)) print('Raíz del Error Cuadrático Medio (RMSE) = ' + str(rmse))
Nos da el siguiente resultado:
Error Cuadrático Medio (MSE) = 0.033
Raíz del Error Cuadrático Medio (RMSE) = 0.182
Coeficiente de determinación R2
El coeficiente de determinación R2 determina la calidad del modelo para replicar los resultados, y la proporción de variación de los resultados que puede explicarse por el modelo
Fuente: wikipedia
El rango de R2 está entre 0 y 1, siendo 1 lo mejor. Para medir el coeficiente de determinación R2 de la regresión lineal usaremos el método score.
# calculamos el coeficiente de determinación R2 r2 = regresion_lineal.score(x.reshape(-1,1), y) print('Coeficiente de Determinación R2 = ' + str(r2))
Nos da el siguiente resultado, que es bastante bueno:
Coeficiente de Determinación R2 = 0.894359363768311
Visualización
Siempre que podamos, es bueno visualizar los resultados, para saber cómo se está comportando el modelo. Este ejemplo que estamos haciendo es muy simple, y por tanto, muy fácil de visualizar. La línea que el modelo ha aprendido siguiendo el método de los mínimos cuadrados aparece en el siguiente gráfico en rojo.
Resumen
En este artículo hemos hablado de la regresión lineal. Esta es la lista de los puntos que hemos cubierto:
- matemáticas de regresión lineal con una variable
- extensión de la notación para varias variables
- el método de los mínimos cuadrados que Gauss nos proporcionó
- cómo entrenar una regresión lineal en python
- cómo hacer predicciones con una regresión lineal ya entrenada
- evaluación con el error cuadrático medio, el coeficiente de determinación R2 y visualizando datos
Recursos
- [vídeo] donde explico la regresión lineal y polinómica (en inglés)
- Error Cuadrático Medio
- Coeficiente de Determinación R2
- LinearRegression: Documentación de la Regresión Lineal en la librería scikit-learn
Alguien que podría explicar más a detalle el porqué ocupamos ruido gaussiano en la función?
Hola Jesús, añadí ruido gaussiano a los datos para poner en evidencia que la regresión lineal también funciona en presencia de ruido.
Muchas gracias por la información, excelente guía, felicidades. :)
Por favor me puede indicar como consigue los valores de w=0.0918 b=1.2859.
Se que es con el programa, pero cual es su formulacion. Usted comenta: «En la práctica hay librerías numéricas que calculan automáticamente la mejor estimación de W por nosotros».
Hola Jaime, en el ejemplo que he puesto, he usado la clase LinearRegression de la librería scikit-learn. Después de entrenar el modelo con el método fit(X, y), puedes obtener w con .coef_ y b con .intercept.
Si quieres verlo con más detalles, la línea 10 de código obtiene esto valores para mostrarlos por pantalla: https://www.iartificial.net/regresion-lineal-con-ejemplos-en-python/#Entrenando_un_modelo_de_Regresion_Lineal_en_python
Como podría predecir la disponibilidad de una playa de estacionamiento teniendo en cuenta los ingresos y salidas? o se necesitarían mas datos?o no es posible?
Si tienes los datos de ingresos y salidas de un parking … creo que podrías decir cuántas plazas de aparcamiento libre directamente. No necesitarías machine learning … o no te he entendido bien?
Claro teniendo ambos datos ya podria tener el dato,pero queria realizar predicciones sobre la disponibilidad de las playas por fecha, hora teniendo los ingresos y salidas en base a un historico, no se si asi queda mas claro
ahh, creo que ahora lo entiendo … lo que quieres hacer es predecir el futuro. Por ejemplo, cuántas plazas de aparcamiento estarán disponibles el martes de la semana que viene a las 18:30, no?
Creo que con los datos que tienes tendrías lo que quieres predecir. También necesitarías en qué vas a basar tus predicciones. Algunas ideas pueden ser:
Seguramente puedas tener más cosas en cuenta si sabes qué tipo de aparcamiento es (centro comercial, playa, instalaciones deportivas, vía pública …)
Espero que te ayude
Gracias Jose Martinez Heras, excelente tu articulo, quiero preguntarte como hago para estimar datos hidrológicos faltantes en una sola estación, he escuchado de modelos de Autorregresión (AR) y en Python con el paquete statsmodels pero no se como aplicarlo. de nuevo Gracias
Wilfredo, es difícil saber qué funcionaría mejor sin ver los datos. Sobre el tema de hidrología escribí un artículo comentando mi solución en el Aguathon de Zaragoza. Míralo a ver si te da alguna idea https://www.iartificial.net/aguathon-mi-solucion-al-primer-hackathon-del-agua/
No logro terminar de entender para que se utiliza la regresión lineal.
Digamos que tengo los registros de varios años de las ventas de una tienda, viene la fecha, total de venta y total de venta de cada producto, qué datos podría utilizar para la regresión y que puedo predecir con estos datos? podría predecir que producto se venderá mas el próximo mes por ejemplo?
Puedes usar regresión lineal cuando tu problema pueda ser explicado por una función. Por ejemplo, en los termómetros de antes, sabiendo cuánto se ha expandido el mercurio, podemos saber la temperatura. Las relaciones no son siempre tan simples, y la regresión linear sólo puede predecir relaciones que sean lineales.
Para predecir qué producto se venderá más el próximo mes podrías tener en cuenta cómo ha ido evolucionando las ventas con respecto a lo normal, qué productos se compran a la vez, estacionalidad (por ejemplo, los helados son más de verano), etc. Puedes calcular características (features) que tengan esto en cuenta y también puedes combinarlo modelos basados en series temporales (ARIMA por ejemplo).
Puede ser que la relación entre los datos de entrada y la predicción de ventas para cada producto no sea lineal y necesites probar con modelos de machine learning más potentes.
José Martínez un saludo!!
¿Me podrías por favor darme a conocer en este ejercicio de regresión lineal la parte del código que usas para obtener las línea roja?
Muchas gracias
Hola Jorge,
La línea roja es una función lineal. Los parámetros los consigo de la regresión lineal después de que haya modelado los datos.
La función lineal tiene la forma f(x) = wx + b
En el código del ejemplo:
– w = regresion_lineal.coef_
– b = regresion_lineal.intercept_
José un saludo!!
Mira tu código para el ejercicio de regresión lineal lo veo fácil de interpretar, el código relacionado a los datos (puntos azules) me funcionó muy bien para un ejercicio de la universidad que estoy haciendo, donde nos piden; ajustar los datos a una línea recta empleando el método de los mínimos cuadrados, calcular la pendiente y la intersección, así como el error estándar y el coeficiente de correlación. Realizar una gráfica en donde se muestren los datos originales y la recta que ajusta. Esto según:
x = [6] [7] [11] [15] [18] [21] [23] [29] [31] [37] [39]
y = [29] [23] [29] [14] [21] [25] [7] [7] [13] [0] [3]
Los datos (puntos azules) relacionados a estas dos listas salen muy bien.
Con el código:
w = regresion_lineal.coef_
b = regresion_lineal.intercept_
Lo datos salen muy bien:
w = [-0.78832016], b = 32.530170620058264
Coeficiente de Determinación R2 = 0.7467950396597056
¿Pero cómo hago para que la línea roja se imprima en forma recta en medio de los puntos azules, como si lo hace usted?
Si esta solicitud le parece inapropiada para sus muy interesantes aportes, le pido disculpas y por favor olvídelo. Es sólo que veo que su aporte se acerca bastante a lo que debo dar solución a través de google colab, y no he podido con esa parte.
Muchas gracias
Hola Jorge,
Para hacer la línea roja sólo tienes que usar matplotlib y pintar la predicción
x = [-5, -4, …., 4, 5]
pred = regresion_lineal.predict(x)
plt.plot(x, pred)
Que tal Amigo.
Muy buen articulo. Tengo una pregunta. En la función
# función f(x) = 0.1*x + 1.25 + 0.2*Ruido_Gaussiano
y = 0.1*x + 1.25 + 0.2*np.random.randn(x.shape[0])
De donde obtienes el 0.2 ?
Segun el codigo el 0.2 se multiplica por el numero aleatorio usando(40) que es el numero de valores.
De donde obtienes esta definición del ruido_gaussiano?
Gracias
Hola Andrea,
– el 0.2 no sale de ningún sitio, me lo he inventado para hacer el ejemplo
– el ruido Gaussiano lo obtengo al obtener números aleatorios de una distribución normal. En numpy, random.randn produce números aleatorios de una distribución normal (o Gaussiana) con media 0 y desviación típica 1. Al multiplicarlo por 0.2 lo que hago a efectos prácticos es conseguir números aleatorios de una distribución Gaussiana con media 0 y desviación típica 0.2
Puedes obtener más información aquí:
– https://es.wikipedia.org/wiki/Distribuci%C3%B3n_normal
-https://numpy.org/devdocs/reference/random/generated/numpy.random.randn.html
Hola, me quedo una duda, como podria mostrar las dos graficas? tanto la punteada como la linea recta de la regresion lineal.
Muchas gracias
Hola, muy claro y didáctico su post, me queda la duda de la estimación de R^2, porque usó para la medición, he visto que se debe dividir la base de datos en dos sets: entrenamiento y prueba. Entiendo que su post es básico en la explicación y estoy sumamente agradecido (empecé haciendo cosas más complejas y no me quedan claros varios conceptos que ahora sí voy entendiendo) pero le agradecería pueda explicar un poco sobre el efecto de no dividir la base y calcular el R^2. Muchas gracias.
Hola buenas noches.
Antes que nada, muy buen articulo, me gusto mucho ya que en lo personal el tema se ha dificultado mucho, pero lo has explicado muy bien! gracias por ello.
Por otro lado al ejecutar el código en Phyton, tengo duda ya que, al hacerlo me marca error en la linea donde utilizas «from sklearn.linear_model import LinearRegression» espero y pueda ayudarme.
Muchas gracias.
Hola Buenos Días,
Excelente artículo. Por casualidad tiene algún ejemplo de regresión lineal mútiple.