Implementación de Regularización en Modelos de Regresión Lineal
Resumen
¿Cómo comenzar con la implementación de técnicas de regularización?
El uso de técnicas de regularización es esencial en la construcción de modelos predictivos sólidos en machine learning. En esta clase, nos enfocamos en implementar dichas técnicas utilizando regresores lineales que ya están integrados en scikit-learn, un módulo muy potente en Python para aprender máquinas. En particular, se trabaja con un conjunto de datos del Reporte de la Felicidad Mundial 2017, que incluye variables de diferentes países como el índice de corrupción y la expectativa de vida.
¿Cómo cargar los datos y preparar el entorno de trabajo?
Antes de comenzar con cualquier modelo, es crucial tener un entorno de desarrollo bien configurado. Aquí se utilizan librerías esenciales como pandas para la gestión de datos, y scikit-learn para los modelos predictivos. A través de pandas, se cargan los datos en un DataFrame, que permite manipular y explorar la información de manera efectiva mediante funciones como describe(), que ofrece descripciones estadísticas de las columnas.
import pandas as pd
import sklearn
from sklearn.linear_model import LinearRegression, Lasso, Ridge
...data = pd.read_csv('data/world_happiness_report_2017.csv')print(data.describe())
¿Cómo dividir los datos para entrenamiento y prueba?
Dividir los datos en conjuntos de entrenamiento y prueba es fundamental para evaluar la eficacia de un modelo. Esta separación te permite no solo ajustar el modelo, sino también validarlo con datos que no ha visto anteriormente.
from sklearn.model_selection import train_test_split
# Definición de características (features) y la variable objetivo (target)X = data[['gdp_per_capita','family','lifespan','freedom','corruption','generosity','dystopia']].values
y = data['happiness_score'].values
# Dividiendo los datos en conjuntos de entrenamiento y pruebaX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)
¿Cómo aplicar los modelos de regresión?
Scikit-learn ofrece varios modelos de regresión lineal, entre los que destacan el modelo lineal básico, Lasso y Ridge. Cada uno tiene sus particularidades en relación con cómo manejan la regularización.
# Modelo de regresión lineallinear_model = LinearRegression()linear_model.fit(X_train, y_train)y_pred_linear = linear_model.predict(X_test)# Modelo de regresión Lassolasso_model = Lasso(alpha=1.0)lasso_model.fit(X_train, y_train)y_pred_lasso = lasso_model.predict(X_test)# Modelo de regresión Ridgeridge_model = Ridge(alpha=1.0)ridge_model.fit(X_train, y_train)y_pred_ridge = ridge_model.predict(X_test)
¿Cómo evaluar los modelos?
La evaluación de los modelos se hace mediante el cálculo del error cuadrático medio (MSE), que mide la diferencia promedio al cuadrado entre los valores reales y las predicciones realizadas por el modelo.
from sklearn.metrics import mean_squared_error
# Cálculo del MSE para cada modelomse_linear = mean_squared_error(y_test, y_pred_linear)mse_lasso = mean_squared_error(y_test, y_pred_lasso)mse_ridge = mean_squared_error(y_test, y_pred_ridge)print('MSE Linear:', mse_linear)print('MSE Lasso:', mse_lasso)print('MSE Ridge:', mse_ridge)
¿Qué nos dicen los coeficientes de los modelos?
Los coeficientes en los modelos de regresión reflejan la importancia de cada característica. En Lasso, ciertos coeficientes pueden reducirse a cero, eliminando de facto algunas características. Por otro lado, Ridge ajusta los coeficientes hacia valores cercanos a cero, pero sin descartarlos por completo, lo que ayuda a manejar la multicolinealidad.
Este análisis de los coeficientes y la comparación de los MSE entre diferentes modelos te permitirá seleccionar el más adecuado, teniendo en cuenta cuán bien se ajusta el modelo a los datos y su capacidad de generalización a nuevas muestras.
¡Adelante! Continúa explorando y aprendiendo sobre machine learning. Cada paso es un avance hacia el dominio de esta poderosa tecnología.
Nota: el dataset de "whr2017" lo encontramos en los archivos del curso como "felicidad"
Gracias!!!
Así es igual en los recursos también está para descargarlo cómo whr2017
Les dejo mi código comentado por su por alguna razón no les corre:
# Importamos las bibliotecasimport pandas as pd
import sklearn
# Importamos los modelos de sklearn from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
# Importamos las metricas de entrenamiento y el error medio cuadradofrom sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
if __name__ =="__main__":# Importamos el dataset del 2017 dataset = pd.read_csv('./data/whr2017.csv')# Mostramos el reporte estadisticoprint(dataset.describe())# Vamos a elegir los features que vamos a usar X = dataset[['gdp','family','lifexp','freedom','corruption','generosity','dystopia']]# Definimos nuestro objetivo, que sera nuestro data set, pero solo en la columna score y = dataset[['score']]# Imprimimos los conjutos que creamos # En nuestros features tendremos definidos 155 registros, uno por cada pais, 7 colunas 1 por cada pais print(X.shape)# Y 155 para nuestra columna para nuestro target print(y.shape)# Aquí vamos a partir nuestro entrenaminto en training y test, no hay olvidar el orden# Con el test size elejimos nuestro porcetaje de datos para training X_train, X_test, y_train, y_test = train_test_split(X,y, test_size=0.25)# Aquí definimos nuestros regresores uno por 1 y llamamos el fit o ajuste modelLinear = LinearRegression().fit(X_train, y_train)# Vamos calcular la prediccion que nos bota con la funcion predict con la regresion lineal # y le vamos a mandar el test y_predict_linear = modelLinear.predict(X_test)# Configuramos alpha, que es valor labda y entre mas valor tenga alpha en lasso mas penalizacion # vamos a tener y lo entrenamos con la función fit modelLasso = Lasso(alpha=0.2).fit(X_train, y_train)# Hacemos una prediccion para ver si es mejor o peor de lo que teniamos en el modelo lineal sobre# exactamente los mismos datos que teníamos anteriormente y_predict_lasso = modelLasso.predict(X_test)# Hacemos la misma predicción, pero para nuestra regresion ridge modelRidge = Ridge(alpha=1).fit(X_train, y_train)# Calculamos el valor predicho para nuestra regresión ridge y_predict_ridge = modelRidge.predict(X_test)# Calculamos la perdida para cada uno de los modelos que entrenamos, empezaremos con nuestro modelo # lineal, con el error medio cuadratico y lo vamos a aplicar con los datos de prueba con la prediccion # que hicimos linear_loss = mean_squared_error(y_test, y_predict_linear)# Mostramos la perdida lineal con la variable que acabamos de calcularprint("Linear loss: ", linear_loss)# Mostramos nuestra perdida Lasso, con la variable lasso loss lasso_loss = mean_squared_error(y_test, y_predict_lasso)print("Lasso Loss. ", lasso_loss)# Mostramos nuestra perdida de Ridge con la variable lasso loss ridge_loss = mean_squared_error(y_test, y_predict_ridge)print("Ridge loss: ", ridge_loss)# Imprimimos las coficientes para ver como afecta a cada una de las regresiones # La lines "="*32 lo unico que hara es repetirme si simbolo de igual 32 veces print("="*32)print("Coeficientes lasso: ")# Esta informacion la podemos encontrar en la variable coef_ print(modelLasso.coef_)# Hacemos lo mismo con ridge print("="*32)print("Coeficientes ridge:")print(modelRidge.coef_)
Hola, una duda, porque aquí no normalizamos la información de los features, no me queda claro cuando si y cuado no escalar datos.
Gracias y saludos!
Gracias por la info Sebastian!!
Saludos!!
El normalizado se hace para cuando vayamos a utilizar lo del PCA o para crear redes neuronales.
"For machine learning, every dataset does not require normalization. It is required only when features have different ranges"
"For machine learning, every dataset does not require normalization. It is required only when features have different ranges"
Urvashi Jaitley
the best explanation in all the comments for this class, thanks a lot
Comportamiento de los tres modelos diseñados, vs nuestro Y de prueba
Mejor rendimiento: LinearRegression
Peor rendimiento: Lasso
Realizando las misma gráfica, Lasso me da muy similar a Lineal, incluso comprovando con sus perdidas
Perdida Modelo lineal: 0.000257
Perdida Modelo Lasso: 0.000246
Perdida Modelo Ridge: 0.08374
Alguien sabe porque la diferencia de alpha en Lasso(alpha=0,02) y en Ridge(alpha =1)?
14. Implementación de Lasso y Ridge
import pandas as pd
import sklearn
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
if __name__ =='__main__':# Load the dataset df = pd.read_csv('./data/felicidad.csv')print(df.describe())# Split the dataset into features (X) and target (y) X = df[['gdp','family','lifexp','freedom','corruption','generosity','dystopia']] y = df[['score']]# Print the shapes of X and yprint(X.shape)print(y.shape)# Split the dataset into training and testing sets X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25)# Fit a linear regression model to the training data modelLinear = LinearRegression().fit(X_train, y_train) y_predict_linear = modelLinear.predict(X_test)# Fit a LASSO regression model to the training data modelLasso = Lasso(alpha=0.02).fit(X_train, y_train) y_predict_lasso = modelLasso.predict(X_test)# Fit a Ridge regression model to the training data modelRidge = Ridge(alpha=1).fit(X_train, y_train) y_predict_ridge = modelRidge.predict(X_test)# Calculate the mean squared error for each model linear_loss = mean_squared_error(y_test, y_predict_linear)print('Linear Loss: ', linear_loss) lasso_loss = mean_squared_error(y_test, y_predict_lasso)print('Lasso Loss: ', lasso_loss) ridge_loss = mean_squared_error(y_test, y_predict_ridge)print('Ridge Loss: ', ridge_loss)# Print the coefficients for the LASSO and Ridge modelsprint('='*32)print('Coef LASSO')print(modelLasso.coef_)print('='*32)print('Coef RIDGE')print(modelRidge.coef_)
y si quisiera separar mis datos en train validation y test para aplicar mejores practicas cual seria la funcion?
Lo puedes hacer con el mismo train_test_split, solo que en vez de pasarle el dataset y target, le pasas el x_train y y_train. Te dejo el código:
Entonces... La regularización sólo aplica para regresiones lineales?
La regularización puede aplicar para la mayoría de modelos, ya sean de classificacion (logistic regression, random forest, etc) o regresión (linear model, etc).
En las redes neuronales tambien se pueden aplicar regularizaciones.
¿Este algoritmo se puede considerar como una forma de extraer una muestra significativa de nuestro conjunto de datos?
mmm si se refiere a lasso y ridge no. Una muestra significativa no es más que un conjunto de datos pequeño que represente el comportamiento de un conjunto mayor de datos. Lasso y Ridge son solo regularizaciones para que las predicciones hechas por el modelo no caigan fácilmente en el overfitting. Ahora si se refería más a que con los modelos se puedan obtener las variables más significativas, es decir las variables más importantes para el modelo, no es exactamente gracias a las variables está más relacionado con los parámetros en si. Para profundizar en esto le recomiendo estudiar más a profundidad la regresión lineal teórica en libros de probabilidad.
Tienes razón, creo que solo me confundí.
Tengo otra pregunta:
¿El algoritmo PCA si se puede considerar como una forma de extraer una muestra significativa de nuestro conjunto de datos?
En el contexto de la regularización, los valores de alpha para Lasso y Ridge tienen diferentes implicaciones. Lasso (L1) puede forzar coeficientes a cero, eliminando características y ayudando en la selección de variables. Un alpha más bajo (0.02) permite más flexibilidad en el ajuste, mientras que un alpha más alto para Ridge (1) penaliza menos la magnitud de los coeficientes, favoreciendo un modelo más robusto. La elección de diferentes valores busca encontrar el balance adecuado entre ajuste y complejidad del modelo.
P.S. El comentario es el resultado de preguntarle a la IA de Platzi, por que el profesor opto por utilizar un valor de alpha en 0.02 en Lasso, y un valor de 1 para Ridge.
Algo importante a considerar, y que quizás podríamos pasar por alto es la forma en la que scikit-learn nos devuelve los resultados.
Si por ejemplo quisiéramos hacer un DF con los coeficientes "Linear, Lasso, Ridge" debemos especificar con un "[0]" que nos referimos a la primera columna. En primara instancia podría sonar redundante, pero debemos tener en cuenta que el resultado que obtenemos es un array de dos dimensiones => [ [datos] ]
# DF con resultados de coeficientes
# DF con resultados de coeficientes
df_coef = pd.DataFrame({'Columna':X.columns,'Reg Lineal': model_linear.coef_[0],'Lasso': model_lasso.coef_[0],'Ridge': model_ridge.coef_[0]})```De otra forma nos dará un error: "`raise ValueError("Per-column arrays must each be 1-dimensional")"`
porque en este caso "Lasso" sí devuelve un array unidimensional. asi que no me hagan caso :D lalalal
import pandas as pd
from sklearn.model_selectionimporttrain_test_splitfrom sklearn.linear_modelimportLasso,Ridgefrom sklearn.preprocessingimportStandardScalerfrom sklearn.metricsimport mean_squared_error
# Carga del conjunto de datos
data = pd.read_csv('felicidad.csv')# Codificación one-hot para la columna 'country'data = pd.get_dummies(data, columns=['country'], drop_first=True)# Separación de características y etiquetas
X= data.drop(columns=['score'])y = data['score']# División en conjuntos de entrenamiento y prueba
X_train,X_test, y_train, y_test =train_test_split(X, y, test_size=0.2, random_state=42)# Estandarización de características
scaler =StandardScaler()X_train_scaled= scaler.fit_transform(X_train)X_test_scaled= scaler.transform(X_test)# Aplicación de Lasso(L1)lasso_model =Lasso(alpha=0.1)lasso_model.fit(X_train_scaled, y_train)y_pred_lasso = lasso_model.predict(X_test_scaled)lasso_mse =mean_squared_error(y_test, y_pred_lasso)# Aplicación de Ridge(L2)ridge_model =Ridge(alpha=0.1)ridge_model.fit(X_train_scaled, y_train)y_pred_ridge = ridge_model.predict(X_test_scaled)ridge_mse =mean_squared_error(y_test, y_pred_ridge)print(f'MSE Lasso: {lasso_mse}')print(f'MSE Ridge: {ridge_mse}')
Resumen:
Lasso (L1): Elimina características irrelevantes, útil para datasets con muchas variables.
Ridge (L2): Reduce la magnitud de los coeficientes, útil para datasets donde todas las características son relevantes, pero con diferentes niveles de influencia.
Hay un error importante en la clase. O no sé si se verá en aplicaciones futuros.
Al aplciar Ridge o Lasso se ha de asegurar que los parametros seleccionados sean los optimos. La idea sera crear una "malla" para cada parametro, comvertirlo en un hiperparametro y con este, trabajar.
No se explica el método de regularización ElasticNet. Porque?
Es correcto que se amplíe la teoriía y ejemplos con este otro método y de esta menra saber cuando usar cada uno.
vengo del futuro a decir que dos clases más adelante lo vemos
El futuro es ahora viejo jajajaja
version mas sencilla de seleccionar mismos features: