Regresión lineal en Python con Scikit-Learn

R

Hay dos tipos de algoritmos de Machine Learning supervisados: regresión y clasificación. El primero predice salidas de valor continuo, mientras que el segundo predice salidas discretas. Por ejemplo, predecir el precio de una casa en dólares es un problema de regresión, mientras que predecir si un tumor es maligno o benigno es un problema de clasificación.

En este artículo estudiaremos brevemente qué es la regresión lineal y cómo se puede implementar usando la biblioteca Python Scikit-Learn, que es una de las bibliotecas de Machine Learning más populares para Python.

Teoría de regresión lineal

El término “linealidad” en álgebra se refiere a una relación lineal entre dos o más variables. Si dibujamos esta relación en un espacio bidimensional (entre dos variables, en este caso), obtenemos una línea recta.

Consideremos un escenario en el que queremos determinar la relación lineal entre la cantidad de horas que estudia un estudiante y el porcentaje de calificaciones que obtiene el estudiante en un examen. Queremos saber que, dada la cantidad de horas que un estudiante se prepara para una prueba, ¿qué tan alta calificación puede lograr el estudiante? Si trazamos la variable independiente (horas) en el eje xy la variable dependiente (porcentaje) en el eje y, la regresión lineal nos da una línea recta que se ajusta mejor a los puntos de datos, como se muestra en la siguiente figura.

Sabemos que la ecuación de una línea recta es básicamente:

y = mx + b

¿Dónde bestá la intersección y mla pendiente de la línea? Básicamente, el algoritmo de regresión lineal nos da el valor más óptimo para la intersección y la pendiente (en dos dimensiones). Las variables yy xsiguen siendo las mismas, ya que son las características de los datos y no se pueden cambiar. Los valores que podemos controlar son el intercepto y la pendiente. Puede haber varias líneas rectas dependiendo de los valores de intersección y pendiente. Básicamente, lo que hace el algoritmo de regresión lineal es ajustar varias líneas en los puntos de datos y devolver la línea que da como resultado el menor error.

Este mismo concepto se puede extender a los casos en los que existan más de dos variables. Esto se llama regresión lineal múltiple. Por ejemplo, considere un escenario en el que tiene que predecir el precio de la casa en función de su área, el número de dormitorios, el ingreso promedio de las personas en el área, la edad de la casa, etc. En este caso, la variable dependiente depende de varias variables independientes. Un modelo de regresión que involucra múltiples variables se puede representar como:


        y = b0 + m1b1 + m2b2 + m3b3 + ... ... mnbn
    

Esta es la ecuación de un hiperplano. Recuerde, un modelo de regresión lineal en dos dimensiones es una línea recta; en tres dimensiones es un plano, y en más de tres dimensiones, un hiperplano.

Regresión lineal con Python Scikit Learn

En esta sección veremos cómo se puede utilizar la biblioteca Python Scikit-Learn para el Machine Learning para implementar funciones de regresión. Comenzaremos con una regresión lineal simple que involucra dos variables y luego avanzaremos hacia una regresión lineal que involucra múltiples variables.

Regresión lineal simple

En esta tarea de regresión predeciremos el porcentaje de calificaciones que se espera que obtenga un estudiante en función del número de horas que estudió. Esta es una tarea de regresión lineal simple, ya que involucra solo dos variables.

Importación de bibliotecas

Para importar las bibliotecas necesarias para esta tarea, ejecute las siguientes instrucciones de importación:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

Nota : Como habrá notado en las declaraciones de importación anteriores, este código se ejecutó utilizando un Jupyter iPython Notebook.

Conjunto de datos

El conjunto de datos que se utiliza para este ejemplo se ha puesto a disposición del público y se puede descargar desde este enlace:

https://drive.google.com/open?id=1oakZCv7g3mlmCSdv9J8kdSaqO5_6dIOw

Nota: Este ejemplo se ejecutó en una máquina con Windows y el conjunto de datos se almacenó en la carpeta “D: conjuntos de datos”. Puede descargar el archivo en una ubicación diferente siempre que cambie la ruta del conjunto de datos en consecuencia.

El siguiente comando importa el conjunto de datos CSV usando pandas:

dataset = pd.read_csv('D:Datasetsstudent_scores.csv')

Ahora exploremos un poco nuestro conjunto de datos. Para hacerlo, ejecute el siguiente script:

dataset.shape

Después de hacer esto, debería ver lo siguiente impreso:

(25, 2)

Esto significa que nuestro conjunto de datos tiene 25 filas y 2 columnas. Echemos un vistazo a cómo se ve realmente nuestro conjunto de datos. Para hacer esto, use el head()método:

dataset.head()

El método anterior recupera los primeros 5 registros de nuestro conjunto de datos, que se verán así:

Horas
Puntuaciones
01234

2.521
5.147
3.227
8.575
3.530

Para ver detalles estadísticos del conjunto de datos, podemos usar describe():

dataset.describe()

Horas Contador de
puntuaciones
significa tdmin 25% 50% 75% máx.

25.00000025.000000
5.01200051.480000
2.52509425.286887
1.10000017.000000
2.70000030.000000
4.80000047.000000
7.40000075.000000
9.20000095.000000

Y finalmente, tracemos nuestros puntos de datos en un gráfico 2-D para observar nuestro conjunto de datos y ver si podemos encontrar manualmente alguna relación entre los datos. Podemos crear la trama con el siguiente script:

dataset.plot(x='Hours', y='Scores', style="o")
plt.title('Hours vs Percentage')
plt.xlabel('Hours Studied')
plt.ylabel('Percentage Score')
plt.show()

En el script anterior, usamos la plot()función del marco de datos de pandas y le pasamos los nombres de las columnas para xcoordenadas y ycoordenadas, que son “Horas” y “Puntuaciones” respectivamente.

La trama resultante se verá así:

En el gráfico anterior, podemos ver claramente que existe una relación lineal positiva entre el número de horas estudiadas y el porcentaje de puntuación.

Preparando los datos

Ahora tenemos una idea sobre los detalles estadísticos de nuestros datos. El siguiente paso es dividir los datos en “atributos” y “etiquetas”. Los atributos son las variables independientes, mientras que las etiquetas son variables dependientes cuyos valores deben predecirse. En nuestro conjunto de datos solo tenemos dos columnas. Queremos predecir la puntuación porcentual en función de las horas estudiadas. Por lo tanto, nuestro conjunto de atributos consistirá en la columna “Horas” y la etiqueta será la columna “Puntaje”. Para extraer los atributos y etiquetas, ejecute el siguiente script:

X = dataset.iloc[:, :-1].values
y = dataset.iloc[:, 1].values

Los atributos se almacenan en la Xvariable. Especificamos “-1” como el rango de las columnas ya que queríamos que nuestro conjunto de atributos contuviera todas las columnas excepto la última, que es “Puntajes”. De manera similar, la yvariable contiene las etiquetas. Especificamos 1 para la columna de etiqueta, ya que el índice de la columna “Puntajes” es 1. Recuerde, los índices de columna comienzan con 0, siendo 1 la segunda columna. En la siguiente sección, veremos una mejor manera de especificar columnas para atributos y etiquetas.

Ahora que tenemos nuestros atributos y etiquetas, el siguiente paso es dividir estos datos en conjuntos de prueba y entrenamiento. Haremos esto usando el train_test_split()método integrado de Scikit-Learn :

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)

El script anterior divide el 80% de los datos en el conjunto de entrenamiento, mientras que el 20% de los datos en el conjunto de prueba. La test_sizevariable es donde realmente especificamos la proporción del conjunto de prueba.

Entrenando el algoritmo

Hemos dividido nuestros datos en conjuntos de entrenamiento y prueba, y finalmente es el momento de entrenar nuestro algoritmo. Ejecute el siguiente comando:

from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X_train, y_train)

Con Scikit-Learn es extremadamente sencillo implementar modelos de regresión lineal, ya que todo lo que realmente necesita hacer es importar la LinearRegressionclase, instanciarla y llamar al fit()método junto con nuestros datos de entrenamiento. Esto es tan simple como se vuelve cuando se usa una biblioteca de Machine Learning para entrenar sus datos.

En la sección de teoría dijimos que el modelo de regresión lineal básicamente encuentra el mejor valor para la intersección y la pendiente, lo que da como resultado una línea que se ajusta mejor a los datos. Para ver el valor de la intersección y la pendiente calculada por el algoritmo de regresión lineal para nuestro conjunto de datos, ejecute el siguiente código.

Para recuperar la intersección:

print(regressor.intercept_)

El valor resultante que ve debe ser aproximadamente 2.01816004143.

Para recuperar la pendiente (coeficiente de x):

print(regressor.coef_)

El resultado debería ser aproximadamente 9,91065648.

Esto significa que por cada unidad de cambio en las horas estudiadas, el cambio en la puntuación es de aproximadamente 9,91%. O en palabras más simples, si un alumno estudia una hora más de lo que estudió anteriormente para un examen, puede esperar lograr un aumento del 9,91% en la puntuación obtenida anteriormente por el alumno.

Haciendo predicciones

Ahora que hemos entrenado nuestro algoritmo, es hora de hacer algunas predicciones. Para hacerlo, utilizaremos nuestros datos de prueba y veremos con qué precisión nuestro algoritmo predice la puntuación porcentual. Para hacer predicciones sobre los datos de prueba, ejecute el siguiente script:

y_pred = regressor.predict(X_test)

El y_predes una matriz numpy que contiene todos los valores predichos para los valores de entrada en la X_testserie.

Para comparar los valores de salida reales X_testcon los valores predichos, ejecute el siguiente script:

df = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
df

La salida se ve así:

Actual
Predicted
01234

2016.884145
2733.732261
6975.357018
3026.794801
6260.491033

Aunque nuestro modelo no es muy preciso, los porcentajes previstos se acercan a los reales.

Nota :

Los valores de las columnas anteriores pueden ser diferentes en su caso porque la train_test_splitfunción divide aleatoriamente los datos en conjuntos de prueba y de tren, y es probable que sus divisiones sean diferentes de las que se muestran en este artículo.

Evaluar el algoritmo

El último paso es evaluar el rendimiento del algoritmo. Este paso es particularmente importante para comparar qué tan bien funcionan los diferentes algoritmos en un conjunto de datos en particular. Para los algoritmos de regresión, se utilizan comúnmente tres métricas de evaluación:

  • El error absoluto medio (MAE) es la media del valor absoluto de los errores. Se calcula como:
  • El error cuadrático medio (MSE) es la media de los errores cuadráticos y se calcula como:
  • Root Mean Squared Error (RMSE) es la raíz cuadrada de la media de los errores cuadrados:

Afortunadamente, no tenemos que realizar estos cálculos manualmente. La biblioteca Scikit-Learn viene con funciones predefinidas que pueden usarse para descubrir estos valores por nosotros.

Busquemos los valores para estas métricas usando nuestros datos de prueba. Ejecute el siguiente código:

from sklearn import metrics
print('Mean Absolute Error:', metrics.mean_absolute_error(y_test, y_pred))
print('Mean Squared Error:', metrics.mean_squared_error(y_test, y_pred))
print('Root Mean Squared Error:', np.sqrt(metrics.mean_squared_error(y_test, y_pred)))

La salida se verá similar a esto (pero probablemente ligeramente diferente):

Mean Absolute Error: 4.183859899
Mean Squared Error: 21.5987693072
Root Mean Squared Error: 4.6474476121

Puede ver que el valor de la raíz del error cuadrático medio es 4,64, que es menos del 10% del valor medio de los porcentajes de todos los estudiantes, es decir, 51,48. Esto significa que nuestro algoritmo hizo un trabajo decente.

Regresión lineal múltiple

En la sección anterior realizamos una regresión lineal con dos variables. Casi todos los problemas del mundo real que se van a encontrar tendrán más de dos variables. La regresión lineal que involucra múltiples variables se denomina “regresión lineal múltiple”. Los pasos para realizar la regresión lineal múltiple son casi similares a los de la regresión lineal simple. La diferencia radica en la evaluación. Puede usarlo para averiguar qué factor tiene el mayor impacto en la salida prevista y cómo se relacionan las diferentes variables entre sí.

En esta sección usaremos regresión lineal múltiple para predecir el consumo de gas (en millones de galones) en 48 estados de EE. UU. Con base en los impuestos a la gasolina (en centavos), el ingreso per cápita (dólares), las carreteras pavimentadas (en millas) y la proporción de población que tiene licencia de conducir.

Los detalles del conjunto de datos se pueden encontrar en este enlace:

http://people.sc.fsu.edu/~jburkardt/datasets/regression/x16.txt

Las dos primeras columnas del conjunto de datos anterior no proporcionan ninguna información útil, por lo que se han eliminado del archivo del conjunto de datos. Ahora desarrollemos un modelo de regresión para esta tarea.

Importar las bibliotecas

El siguiente script importa las bibliotecas necesarias:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
Conjunto de datos

El conjunto de datos para este ejemplo está disponible en:

https://drive.google.com/open?id=1mVmGNx6cbfvRHC_DvF12ZL3wGLSHD9f_

El siguiente comando importa el conjunto de datos del archivo que descargó a través del enlace anterior:

dataset = pd.read_csv('D:Datasetspetrol_consumption.csv')

Al igual que la última vez, echemos un vistazo a cómo se ve realmente nuestro conjunto de datos. Ejecute el head()comando:

dataset.head()

Las primeras líneas de nuestro conjunto de datos se ven así:

Impuesto a la
gasolina Ingresos medios
Carreteras pavimentadas Licencia de conductor de
población (%)
Consumo de
gasolina 01234

9.0357119760.525541
9.0409212500.572524
9.0386515860.580561
7.5487023510.529414
8.043994310.544410

Para ver detalles estadísticos del conjunto de datos, usaremos el describe()comando nuevamente:

dataset.describe()

Gasolina_impuesto_ingreso_promedio
Carreteras_
pavimentadas
Población_Licencia_conductores (%)
Recuento de
consumo_de gasolinameanstdmin25% 50% 75% máx.

48.00000048.00000048.00000048.00000048.000000
7.6683334241.8333335565.4166670.570333576.770833
0.950770573.6237683491.5071660.055470111.885816
5.0000003063.000000431.0000000.451000344.000000
7.0000003739.0000003110.2500000.529750509.500000
7.5000004298.0000004735.5000000.564500568.500000
8.1250004578.7500007156.0000000.595250632.750000
10.000005342.00000017782.0000000.724000986.000000
Preparando los datos

El siguiente paso es dividir los datos en atributos y etiquetas como hicimos anteriormente. Sin embargo, a diferencia de la última vez, esta vez usaremos nombres de columna para crear un conjunto de atributos y una etiqueta. Ejecute el siguiente script:

X = dataset[['Petrol_tax', 'Average_income', 'Paved_Highways',
       'Population_Driver_licence(%)']]
y = dataset['Petrol_Consumption']

Ejecute el siguiente código para dividir nuestros datos en conjuntos de prueba y entrenamiento:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
Entrenando el algoritmo

Y finalmente, para entrenar el algoritmo ejecutamos el mismo código que antes, usando el fit()método de la LinearRegressionclase:

from sklearn.linear_model import LinearRegression
regressor = LinearRegression()
regressor.fit(X_train, y_train)

Como se dijo anteriormente, en caso de regresión lineal multivariable, el modelo de regresión tiene que encontrar los coeficientes más óptimos para todos los atributos. Para ver qué coeficientes ha elegido nuestro modelo de regresión, ejecute el siguiente script:

coeff_df = pd.DataFrame(regressor.coef_, X.columns, columns=['Coefficient'])
coeff_df

El resultado debería verse así:

Coeficiente
Gasolina_impuestoAverage_inomePaved_HighwaysPopulation_Driver_license (%)

-24.196784
-0.81680
-0.000522
1324.675464

Esto significa que por un aumento unitario en “petrol_tax”, hay una disminución de 24,19 millones de galones en el consumo de gas. De manera similar, un aumento unitario en la proporción de la población con licencia de conducir resulta en un aumento de 1,324 billones de galones de consumo de gasolina. Podemos ver que “Average_income” y “Paved_Highways” tienen muy poco efecto en el consumo de gas.

Haciendo predicciones

Para hacer predicciones sobre los datos de prueba, ejecute el siguiente script:

y_pred = regressor.predict(X_test)

Para comparar los valores de salida reales X_testcon los valores predichos, ejecute el siguiente script:

df = pd.DataFrame({'Actual': y_test, 'Predicted': y_pred})
df

La salida se ve así:

Real
Previsto
3622203818144211645

640643.176639
464411.950913
649683.712762
648728.049522
865755.473801
524559.135132
782671.916474
540550.633557
603594.425464
510525.038883
Evaluar el algoritmo

El último paso es evaluar el rendimiento del algoritmo. Haremos esto encontrando los valores de MAE , MSE y RMSE . Ejecute el siguiente script:

from sklearn import metrics
print('Mean Absolute Error:', metrics.mean_absolute_error(y_test, y_pred))
print('Mean Squared Error:', metrics.mean_squared_error(y_test, y_pred))
print('Root Mean Squared Error:', np.sqrt(metrics.mean_squared_error(y_test, y_pred)))

La salida se verá similar a esto:

Mean Absolute Error: 45.8979842541
Mean Squared Error: 3609.37119141
Root Mean Squared Error: 60.0780425065

Puede ver que el valor de la raíz del error cuadrático medio es 60,07, que es ligeramente superior al 10% del valor medio del consumo de gas en todos los estados. Esto significa que nuestro algoritmo no era muy preciso, pero aún puede hacer predicciones razonablemente buenas.

Hay muchos factores que pueden haber contribuido a esta inexactitud, algunos de los cuales se enumeran aquí:

  • Se necesitan más datos: solo un año de datos no es tanto, mientras que tener varios años podría habernos ayudado a mejorar bastante la precisión.
  • Suposiciones erróneas: asumimos que estos datos tienen una relación lineal, pero puede que no sea así. La visualización de los datos puede ayudarlo a determinarlo.
  • Características deficientes: es posible que las características que usamos no tuvieran una correlación lo suficientemente alta con los valores que estábamos tratando de predecir.

Conclusión

En este artículo estudiamos uno de los algoritmos de Machine Learning más fundamentales, es decir, la regresión lineal. Implementamos tanto la regresión lineal simple como la regresión lineal múltiple con la ayuda de la biblioteca de Machine Learning de Scikit-Learn.

 

About the author

Ramiro de la Vega

Bienvenido a Pharos.sh

Soy Ramiro de la Vega, Estadounidense con raíces Españolas. Empecé a programar hace casi 20 años cuando era muy jovencito.

Espero que en mi web encuentres la inspiración y ayuda que necesitas para adentrarte en el fantástico mundo de la programación y conseguir tus objetivos por difíciles que sean.

Add comment

Sobre mi

Últimos Post

Etiquetas

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con tus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, aceptas el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Más información
Privacidad