Este ejemplo es tomado del libro Hands on Machine Learning with Scikit-Learn, Keras and TensorFlow de Aurelien Geron. No obtengo de su pubiclación ningún beneficio económico, y solo lo hago por los motivos descritos aquí. Si desean aprender un montón más sobre este tema y conocer el contexto de este ejemplo, les recomiendo que busquen el libro.
Lo que hace el ejercicio es tomar unos datos relacionados con el dinero que ganan las personas en diferentes países y ver si la cantidad está relacionada con su satisfacción de vida, para lo cual se usa un modelo lineal que trate de explicar la relación. Posteriormente, ese modelo lineal se usa para hacer predicciones sobre la life satisfaction a partir de nuevos valores de GDP per capita.
Todos los códigos del libro y las bases de datos pueden encontrarlos en el perfil de GitHub de su autor. De igual manera, tanto las bases de datos como el código con algunas modificaciones y comentarios en español pueden encontrarlo aquí en mi perfil de GitHub.
Entonces, comencemos con la explicación del código (cada sección de código tiene un nombre que resume qué hace, no hace parte del código).
- Cargamos los módulos necesarios
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import sklearn.linear_model
2. Se define una función cuyo objetivo es manipular los datos y dejarlos listos para construir el modelo.
def prepare_country_stats(oecd_bli, gdp_per_capita):
#Filtramos y dejamos solo las filas de "INEQUALITY" con valor TOT
oecd_bli = oecd_bli[oecd_bli["INEQUALITY"]=="TOT"]
#Ponemos como índice la columna "Country". Los valores de la columna
#Indicator se van a convertir en columnas
oecd_bli = oecd_bli.pivot(index="Country", columns="Indicator", values="Value")
#Cambiamos el nombre de una de las columnas de gpd_per_capita
gdp_per_capita.rename(columns={"2015": "GDP per capita"}, inplace=True)
#Eliminamos el índice numérico generado automáticamente
gdp_per_capita.set_index("Country", inplace=True)
#Unimos ambos dataframes de manera horizontal (uno a la izquierda y el otro a
#la derecha)
full_country_stats = pd.merge(left=oecd_bli, right=gdp_per_capita,
left_index=True, right_index=True)
#Ordenamos el nuevo dataframe de acuerdo al valor de la columna
#GDP per capita
full_country_stats.sort_values(by="GDP per capita", inplace=True)
#Se van a eliminar las siguientes filas
remove_indices = [0, 1, 6, 8, 33, 34, 35]
keep_indices = list(set(range(36)) - set(remove_indices))
#Solo se retornan dos columnas
return full_country_stats[["GDP per capita", 'Life satisfaction']].iloc[keep_indices]
3. Cargamos los datos. Es interesante ver que al momento de leer la primera base de datos se especifica cuál es el separador de miles, y en el caso de la segunda se especifica el dilimitador, el tipo de codificación y la manera como se manipularán los valores inexistentes (n/a)
#Cargamos los archivos
oecd_bli = pd.read_csv(PATH +
"handson-ml2-master/datasets/lifesat/oecd_bli_2015.csv", thousands=',')
gdp_per_capita = pd.read_csv(PATH +
"handson-ml2-master/datasets/lifesat/gdp_per_capita.csv", thousands = ',',
delimiter='\t', encoding='latin1',na_values='n/a')
4. Llamamos a la función para que aliste los datos, y luego elegimos cuáles serán la variable independiente o predictora (el GDP per capita) y cuál la dependiente o predica (Life satisfaction)
#Preparamos los datos
country_stats = prepare_country_stats(oecd_bli, gdp_per_capita)
X = np.c_[country_stats["GDP per capita"]]
y = np.c_[country_stats["Life satisfaction"]]
5. Visualizamos los datos con una gráfica de dispersión. Se observa que existe una clara relación directamente proporcional entre la cantidad de dinero que ganan las personas y su satisfacción de vida.
#Visualizamos los datos
country_stats.plot(kind='scatter',x="GDP per capita", y='Life satisfaction')
6. Elegimos el modelo, lo entrenamos y lo usamos para hacer una predicción
#Seleccionamos un modelo lineal
model = sklearn.linear_model.LinearRegression()
#Entrenamos el modelo
model.fit(X,y)
#Se pueden obtener los parámetros del modelo (que son dos por ser un modelo líneal de una sola variable)
#usando las siguientes instruccions
model.intercept_ #array([4.8530528]) Un país con 0 GDP tendría una satisfacción de vida de 4.85
model.coef_ #array([[4.91154459e-05]]) La línea es casi plana, casi cero.
#Hacemos una predicción para Chipre
X_new = [[22587]] #GDP per capita de Chipre
print(model.predict(X_new)) #[[5.96242338]]