Regresi贸n lineal en Python con Scikit-Learn

    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.

     

    Etiquetas:

    Deja una respuesta

    Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *