A continuación veremos cómo podemos implementar este modelo en Python. Para ello, utilizaremos la librería scikit-learn
.
Para ejemplificar la implementación de un modelo de regresión lineal simple utilizaremos un conjunto de datos con pocas instancias y que ya ha sido previamente tratado con un EDA completo.
import pandas as pd
train_data = pd.read_csv("https://raw.githubusercontent.com/4GeeksAcademy/machine-learning-content/master/assets/clean_salary_train.csv")
test_data = pd.read_csv("https://raw.githubusercontent.com/4GeeksAcademy/machine-learning-content/master/assets/clean_salary_test.csv")
train_data.head()
Como en este notebook no se ha mostrado el proceso de análisis exploratorio, a continuación y utilizando un diagrama de puntos se visualizará la relación entre la variable predictora y la objetivo (esto se ve en el análisis univariante):
import matplotlib.pyplot as plt
import seaborn as sns
fig, axis = plt.subplots(2, 1, figsize = (5, 7))
total_data = pd.concat([train_data, test_data])
sns.regplot(ax = axis[0], data = total_data, x = "YearsExperience", y = "Salary")
sns.heatmap(total_data[["Salary", "YearsExperience"]].corr(), annot = True, fmt = ".2f", ax = axis[1], cbar = False)
plt.tight_layout()
plt.show()
Existe una clara relación lineal entre la variable predictora y la objetivo, así que puede ser fácilmente modelable por este tipo de modelos. Si la correlación fuera inferior, el modelo no tendría una buena precisión.
El conjunto train lo utilizaremos para entrenar el modelo, mientras que el conjunto test lo evaluaremos para medir su grado de efectividad. Dividiremos también las predictoras de las características.
Además, al haber únicamente una variable predictora, no es necesario aplicar una normalización. En el caso de que hubiera varias, sí que habría que aplicarla.
X_train = train_data.drop(["Salary"], axis = 1)
y_train = train_data["Salary"]
X_test = test_data.drop(["Salary"], axis = 1)
y_test = test_data["Salary"]
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)
Después del proceso de entrenamiento podemos conocer los parámetros (variables y ) que ha ajustado el modelo:
print(f"Intercepto (a): {model.intercept_}")
print(f"Coeficientes (b): {model.coef_}")
En este caso hay solo un coeficiente, ya que la regresión lineal es simple.
y_pred = model.predict(X_test)
y_pred
Para comparar el valor predicho del original, podemos fácilmente realizar un gráfico comparativo como el siguiente:
fig, axis = plt.subplots(1, 2, figsize = (5, 3.5))
total_data = pd.concat([train_data, test_data])
# Utilizamos los parámetros ajustados en el entrenamiento para dibujar la línea de regresión en los gráficos
regression_equation = lambda x: 26354.43069701219 + 9277.78307971 * x
sns.scatterplot(ax = axis[0], data = test_data, x = "YearsExperience", y = "Salary")
sns.lineplot(ax = axis[0], x = test_data["YearsExperience"], y = regression_equation(test_data["YearsExperience"]))
sns.scatterplot(ax = axis[1], x = test_data["YearsExperience"], y = y_pred)
sns.lineplot(ax = axis[1], x = test_data["YearsExperience"], y = regression_equation(test_data["YearsExperience"])).set(ylabel = None)
plt.tight_layout()
plt.show()
Como vemos, el test predicho por el modelo siempre se ajustará a la ecuación de regresión, ya que es la que ha aprendido el modelo. La figura de la izquierda representa los valores reales, mientras que los de la derecha, los predichos. Vemos que algunos valores predichos coinciden con los reales, y los que no, tienen una diferencia notable. Veremos a continuación el valor de la métrica para conocer más acerca del rendimiento del algoritmo.
Para calcular la efectividad del modelo utilizaremos el error cuadrático medio (MSE) y el coeficiente de determinación (), unas de las métricas más populares:
from sklearn.metrics import mean_squared_error, r2_score
print(f"Error cuadrático medio: {mean_squared_error(y_test, y_pred)}")
print(f"Coeficiente de determinación: {r2_score(y_test, y_pred)}")
Cuanto menor sea el valor del RMSE, mejor será el modelo. Un modelo perfecto (un modelo hipotético que siempre pueda predecir el valor esperado exacto) tendría un valor para esta métrica de 0. Observamos que hay un descuadre de 37 millones, por lo que podríamos entender que es muy malo. Si nos apoyamos en el valor del , observamos que es de un 95%, un valor muy alto, luego el 95% de los datos están explicados por el modelo, por lo que es satisfactorio.
Este tipo de modelos no se pueden optimizar, debido a la ausencia de hiperparámetros.
Para ejemplificar la implementación de un modelo de regresión múltiple simple utilizaremos un conjunto de datos con pocas instancias y que ya ha sido previamente tratado con un EDA completo.
import pandas as pd
import matplotlib.pyplot as plt
train_data = pd.read_csv("https://raw.githubusercontent.com/4GeeksAcademy/machine-learning-content/master/assets/clean_weight-height_train.csv")
test_data = pd.read_csv("https://raw.githubusercontent.com/4GeeksAcademy/machine-learning-content/master/assets/clean_weight-height_test.csv")
train_data.head()
Para este problema, queremos calcular el peso (weight
) en función de la altura (height
) y del género (gender
) de la persona. Por lo tanto, el peso será la variable dependiente (variable objetivo) y la altura y el género, las variables independientes (variables predictoras). Al tratarse de una predicción numérica continua, hemos de resolver esto con un modelo de regresión logística múltiple.
Como en este notebook no se ha mostrado el proceso de análisis exploratorio, a continuación y utilizando un diagrama de puntos se visualizará la relación entre la variable predictora y las variables objetivo (esto se ve en el análisis univariante):
fig, axis = plt.subplots(2, 2, figsize = (10, 7))
total_data = pd.concat([train_data, test_data])
sns.regplot(ax = axis[0, 0], data = total_data, x = "Gender", y = "Weight")
sns.heatmap(total_data[["Weight", "Gender"]].corr(), annot = True, fmt = ".2f", ax = axis[1, 0], cbar = False)
sns.regplot(ax = axis[0, 1], data = total_data, x = "Height", y = "Weight")
sns.heatmap(total_data[["Weight", "Height"]].corr(), annot = True, fmt = ".2f", ax = axis[1, 1], cbar = False)
plt.tight_layout()
plt.show()
Existe una clara relación lineal entre la variable predictora y las objetivo, así que puede ser fácilmente modelable por este tipo de modelos. Si la correlación fuera inferior, el modelo no tendría una buena precisión.
X_train = train_data.drop(["Weight"], axis = 1)
y_train = train_data["Weight"]
X_test = test_data.drop(["Weight"], axis = 1)
y_test = test_data["Weight"]
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(X_train, y_train)
Después del proceso de entrenamiento podemos conocer los parámetros (variables y ) que ha ajustado el modelo:
print(f"Intercepto (a): {model.intercept_}")
print(f"Coeficientes (b1, b2): {model.coef_}")
y_pred = model.predict(X_test)
y_pred
from sklearn.metrics import mean_squared_error, r2_score
print(f"Error cuadrático medio: {mean_squared_error(y_test, y_pred)}")
print(f"Coeficiente de determinación: {r2_score(y_test, y_pred)}")
Si nos apoyamos en el valor del , observamos que es de un 90%, un valor muy alto, luego el 90% de los datos están explicados por el modelo, por lo que es satisfactorio.
Este tipo de modelos no se pueden optimizar, debido a la ausencia de hiperparámetros.