10. Selección y regularización de modelos lineales#
A pesar de su simplicidad, los modelos lineales tienen ventajas de interpretabilidad y con frecuencia muestran buen rendimiento en predicción
Esta sección aborda el cambiar el ajuste de mínimos cuadrados ordinarios (OLS) tradicional por métodos alternativos que se apalancan en OLS.
¿Por que usar alternativas a OLS?
Predictibilidad: Si la relación entre las variables es aproximadamente lineal y si
(el número de observaciones es más grande que el número de variables), entonces OLS tiene poco sesgo y rinde bien en datos test. Sin embargo, si no es tan grande respecto a , puede haber mucha variabilidad en OLS, lo que resulta en sobreajuste y mal rendimiento en test.
Algunos de los problemas que surgen cuando
Sobreajuste (Overfitting)
El error cuadrático medio (MSE) en el conjunto de entrenamiento se define como:
donde:
es el valor observado, es la predicción del modelo, es el número de observaciones.
Cuando el número de variables
Multicolinealidad
El problema de multicolinealidad se detecta cuando las variables explicativas están altamente correlacionadas entre sí. Un indicador común es el Factor de Inflación de la Varianza (VIF) para cada variable
donde
Cuando
Modelo No Identificable
En regresión lineal, los coeficientes de los parámetros
donde:
es el vector de observaciones (de dimensión ), es la matriz de diseño (de dimensión ), es el vector de coeficientes, es el término de error.
Para resolver
Varianza Alta
Cuando hay más variables que observaciones, el error estándar de los coeficientes de regresión se incrementa. La varianza de los coeficientes
donde
Interpretabilidad: Incluir variables independientes sin asociación con la variable dependiente en un modelo de regresión resulta en incluir complejidades innecesarias en el modelo. Si son removidas (se fijan sus coeficientes en cero), se puede obtener un modelo que es más interpretable. En OLS hay muy poca probabilidad de que se tengan coeficientes iguales a cero. Al eliminar variables estamos haciendo selección de variables o feature selection: selección de variables, contracción o regularización y reducción de dimensionalidad.
10.1. Selección de variables#
10.1.1. Selección de las mejores variables#
Algoritmo: Selección de las mejores variables |
---|
1. Sea |
2. Para |
|
|
3. Selecciona el mejor modelo de los |
Nota que este algoritmo no puede ser aplicado cuando
es grande.También puede tener problemas de estadísticos cuando
es grande. Cuanto mayor sea el espacio de búsqueda, mayor será la posibilidad de encontrar modelos que se vean bien en los datos de entrenamiento, aunque podrían no tener ningún poder predictivo sobre datos futuros.Por lo tanto, un espacio de búsqueda enorme puede dar lugar a un sobreajuste y a una alta varianza de las estimaciones de los coeficientes.
Por los motivos antes listado, los métodos stepwise o paso a paso son más atractivos.
donde
Criterio AIC
Se puede usar en modelos donde el ajuste se realiza con máxima verosimilitud:
Donde
donde
donde
10.1.2. Selección stepwise hacia adelante#
Algoritmo: Selección stepwise hacia adelante |
---|
1. Sea |
2. Para |
|
|
3. Selecciona el mejor modelo de los |
10.1.3. Selección stepwise hacia atrás#
Algoritmo: Selección stepwise hacia atrás |
---|
1. Sea |
2. Para |
|
|
3. Selecciona el mejor modelo de los |
10.1.3.1. Ejemplo#
La superintendencia de compañias del Ecuador tiene información de estados financieros de las empresas que regula. Vamos a predecir los ingresos por ventas de las empresas grandes del 2023. En la pestaña Recursos del siguiente enlace: https://appscvsmovil.supercias.gob.ec/ranking/reporte.html
import pandas as pd
import statsmodels.api as sm
uu = "https://raw.githubusercontent.com/vmoprojs/DataLectures/refs/heads/master/superciasGrandes2023.csv"
datos = pd.read_csv(uu)
datos.drop(columns = ['Unnamed: 0'],inplace = True)
# Supongamos que 'X' es tu conjunto de características y 'y' la variable dependiente.
X = datos.loc[:,datos.columns!='ingresos_ventas'] # tus datos de características
X = X.loc[:,X.columns!='costos_ventas_prod']
y = datos['ingresos_ventas']/1000000 # tu variable dependiente
#import sweetviz as sv
#my_report = sv.analyze(datos)
#my_report.show_html()# altas correlaciones
Notamos que existen variables con alta correlación, se eliminan correlaciones superiores a
import numpy as np
# Calcular la matriz de correlación
corr_matrix = X.corr().abs()
# Seleccionar las columnas con alta correlación (por ejemplo, > 0.9)
upper_triangle = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool))
# Encontrar las columnas que tienen alta correlación
high_corr_columns = [column for column in upper_triangle.columns if any(upper_triangle[column] > 0.8)]
# Eliminar las columnas con alta correlación de X
X = X.drop(columns=high_corr_columns)
# Mostrar las columnas eliminadas
print("Columnas eliminadas por alta correlación:\n", high_corr_columns)
Columnas eliminadas por alta correlación:
['patrimonio', 'impuesto_renta', 'utilidad_ejercicio', 'utilidad_neta', 'prueba_acida', 'end_largo_plazo', 'apalancamiento', 'apalancamiento_c_l_plazo', 'rot_activo_fijo', 'rent_ope_activo', 'roa', 'total_gastos']
start_model = sm.OLS(y, X).fit()
print(start_model.summary())
OLS Regression Results
=======================================================================================
Dep. Variable: ingresos_ventas R-squared (uncentered): 0.818
Model: OLS Adj. R-squared (uncentered): 0.816
Method: Least Squares F-statistic: 425.0
Date: Mon, 14 Apr 2025 Prob (F-statistic): 0.00
Time: 22:21:52 Log-Likelihood: -15624.
No. Observations: 2969 AIC: 3.131e+04
Df Residuals: 2938 BIC: 3.150e+04
Df Model: 31
Covariance Type: nonrobust
=============================================================================================
coef std err t P>|t| [0.025 0.975]
---------------------------------------------------------------------------------------------
activos 4.267e-07 1.98e-08 21.527 0.000 3.88e-07 4.66e-07
utilidad_an_imp 2.59e-07 8.59e-08 3.017 0.003 9.07e-08 4.27e-07
n_empleados 0.0252 0.002 13.497 0.000 0.022 0.029
liquidez_corriente 0.0171 0.014 1.227 0.220 -0.010 0.044
end_activo -0.1281 1.138 -0.113 0.910 -2.359 2.103
end_patrimonial -0.0379 0.089 -0.426 0.670 -0.212 0.136
end_activo_fijo -1.679e-05 5.77e-05 -0.291 0.771 -0.000 9.64e-05
end_corto_plazo 21.5596 1.986 10.855 0.000 17.665 25.454
cobertura_interes 4.176e-06 7.97e-06 0.524 0.600 -1.14e-05 1.98e-05
apalancamiento_financiero -0.0020 0.005 -0.403 0.687 -0.011 0.008
end_patrimonial_ct -0.0012 0.150 -0.008 0.994 -0.295 0.292
end_patrimonial_nct 0.6346 0.577 1.100 0.271 -0.496 1.765
rot_cartera 1.821e-05 1.95e-05 0.932 0.352 -2.01e-05 5.65e-05
rot_ventas 0.0416 0.039 1.078 0.281 -0.034 0.117
per_med_cobranza -8.883e-07 5.97e-07 -1.488 0.137 -2.06e-06 2.83e-07
per_med_pago 1.7e-08 1.25e-08 1.361 0.174 -7.49e-09 4.15e-08
impac_gasto_a_v -1.5197 0.725 -2.096 0.036 -2.941 -0.098
impac_carga_finan -107.0103 22.392 -4.779 0.000 -150.917 -63.104
rent_neta_activo 14.2754 5.624 2.539 0.011 3.249 25.302
margen_bruto -27.5007 3.178 -8.654 0.000 -33.732 -21.270
margen_operacional 6.395e-08 1.5e-08 4.254 0.000 3.45e-08 9.34e-08
rent_neta_ventas -32.6691 7.673 -4.258 0.000 -47.713 -17.625
rent_ope_patrimonio -0.0029 0.012 -0.236 0.814 -0.027 0.021
roe 0.0333 0.055 0.604 0.546 -0.075 0.141
fortaleza_patrimonial -0.4488 0.758 -0.592 0.554 -1.934 1.037
gastos_financieros 1.278e-06 4.1e-07 3.116 0.002 4.74e-07 2.08e-06
gastos_admin_ventas 1.142e-06 7.42e-08 15.384 0.000 9.96e-07 1.29e-06
depreciaciones -7.185e-07 5e-07 -1.437 0.151 -1.7e-06 2.62e-07
amortizaciones -3.584e-06 6.33e-07 -5.665 0.000 -4.82e-06 -2.34e-06
deuda_total 2.197e-06 1.38e-07 15.935 0.000 1.93e-06 2.47e-06
deuda_total_c_plazo 4.409e-06 4.75e-07 9.275 0.000 3.48e-06 5.34e-06
==============================================================================
Omnibus: 4187.902 Durbin-Watson: 2.054
Prob(Omnibus): 0.000 Jarque-Bera (JB): 2749251.147
Skew: 7.826 Prob(JB): 0.00
Kurtosis: 151.252 Cond. No. 3.07e+09
==============================================================================
Notes:
[1] R² is computed without centering (uncentered) since the model does not contain a constant.
[2] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[3] The condition number is large, 3.07e+09. This might indicate that there are
strong multicollinearity or other numerical problems.
Evaluación del modelo
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
def evaluate_model(y_true, y_pred):
mae = mean_absolute_error(y_true, y_pred)
mse = mean_squared_error(y_true, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_true, y_pred)
return mae, mse, rmse, r2
# Predicciones y evaluación para OLS
y_pred_ols = start_model.predict(X)
mae_ols, mse_ols, rmse_ols, r2_ols = evaluate_model(y, y_pred_ols)
# Mostrar evaluación
print("\nOLS Métricas de evaluación:")
print(f"Mean Absolute Error (MAE): {mae_ols:.2f}")
print(f"Mean Squared Error (MSE): {mse_ols:.2f}")
print(f"Root Mean Squared Error (RMSE): {rmse_ols:.2f}")
print(f"R-squared: {r2_ols:.2f}")
OLS Métricas de evaluación:
Mean Absolute Error (MAE): 16.09
Mean Squared Error (MSE): 2179.19
Root Mean Squared Error (RMSE): 46.68
R-squared: 0.80
Modelo hacia adelante:
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.linear_model import LinearRegression
# Crear el metodo para modelo de regresión lineal
model = LinearRegression()
# Crear un selector de características secuencial
sfs = SequentialFeatureSelector(model, n_features_to_select='auto', direction='forward')
# Ajustar el modelo
sfs.fit(X, y)
# Ver las características seleccionadas
selected_features = sfs.get_support()
# Ajustar el modelo final con las características seleccionadas
X_selected = X.loc[:, selected_features]
final_model = sm.OLS(y, X_selected).fit()
# Mostrar el resumen del modelo final
print(final_model.summary())
OLS Regression Results
=======================================================================================
Dep. Variable: ingresos_ventas R-squared (uncentered): 0.811
Model: OLS Adj. R-squared (uncentered): 0.810
Method: Least Squares F-statistic: 842.7
Date: Mon, 14 Apr 2025 Prob (F-statistic): 0.00
Time: 22:21:56 Log-Likelihood: -15680.
No. Observations: 2969 AIC: 3.139e+04
Df Residuals: 2954 BIC: 3.148e+04
Df Model: 15
Covariance Type: nonrobust
=========================================================================================
coef std err t P>|t| [0.025 0.975]
-----------------------------------------------------------------------------------------
activos 4.878e-07 1.4e-08 34.946 0.000 4.6e-07 5.15e-07
n_empleados 0.0208 0.002 12.851 0.000 0.018 0.024
end_corto_plazo 22.2718 1.836 12.130 0.000 18.672 25.872
end_patrimonial_ct -0.0346 0.086 -0.401 0.689 -0.204 0.135
rot_cartera 1.94e-05 1.98e-05 0.978 0.328 -1.95e-05 5.83e-05
per_med_pago 1.367e-08 1.26e-08 1.080 0.280 -1.11e-08 3.85e-08
impac_gasto_a_v -1.5230 0.731 -2.082 0.037 -2.957 -0.089
impac_carga_finan -98.7982 21.518 -4.591 0.000 -140.990 -56.606
rent_neta_activo 17.6911 5.258 3.364 0.001 7.381 28.001
margen_bruto -25.7358 3.143 -8.189 0.000 -31.898 -19.573
rent_neta_ventas -35.7664 7.223 -4.952 0.000 -49.928 -21.604
fortaleza_patrimonial -0.8198 0.719 -1.140 0.254 -2.230 0.591
gastos_admin_ventas 9.447e-07 5.34e-08 17.702 0.000 8.4e-07 1.05e-06
deuda_total 2.124e-06 1.33e-07 16.029 0.000 1.86e-06 2.38e-06
deuda_total_c_plazo 4.96e-06 4.71e-07 10.530 0.000 4.04e-06 5.88e-06
==============================================================================
Omnibus: 4174.333 Durbin-Watson: 2.035
Prob(Omnibus): 0.000 Jarque-Bera (JB): 2485003.184
Skew: 7.817 Prob(JB): 0.00
Kurtosis: 143.866 Cond. No. 2.81e+09
==============================================================================
Notes:
[1] R² is computed without centering (uncentered) since the model does not contain a constant.
[2] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[3] The condition number is large, 2.81e+09. This might indicate that there are
strong multicollinearity or other numerical problems.
# Predicciones y evaluación para Adelante
y_pred_adelante = final_model.predict(X_selected)
mae_adelante, mse_adelante, rmse_adelante, r2_adelante = evaluate_model(y, y_pred_adelante)
# Mostrar evaluación
print("\n(Adelante) Métricas de evaluación:")
print(f"Mean Absolute Error (MAE): {mae_adelante:.2f}")
print(f"Mean Squared Error (MSE): {mse_adelante:.2f}")
print(f"Root Mean Squared Error (RMSE): {rmse_adelante:.2f}")
print(f"R-squared: {r2_adelante:.2f}")
(Adelante) Métricas de evaluación:
Mean Absolute Error (MAE): 16.51
Mean Squared Error (MSE): 2263.94
Root Mean Squared Error (RMSE): 47.58
R-squared: 0.79
Modelo hacia atrás
from sklearn.feature_selection import SequentialFeatureSelector
from sklearn.linear_model import LinearRegression
# Crear el metodo para modelo de regresión lineal
model = LinearRegression()
# Crear un selector de características secuencial
sfs = SequentialFeatureSelector(model, n_features_to_select='auto', direction='backward')
# Ajustar el modelo
sfs.fit(X, y)
# Ver las características seleccionadas
selected_features = sfs.get_support()
# Ajustar el modelo final con las características seleccionadas
X_selected = X.loc[:, selected_features]
final_model = sm.OLS(y, X_selected).fit()
# Mostrar el resumen del modelo final
print(final_model.summary())
OLS Regression Results
=======================================================================================
Dep. Variable: ingresos_ventas R-squared (uncentered): 0.810
Model: OLS Adj. R-squared (uncentered): 0.809
Method: Least Squares F-statistic: 787.0
Date: Mon, 14 Apr 2025 Prob (F-statistic): 0.00
Time: 22:22:03 Log-Likelihood: -15685.
No. Observations: 2969 AIC: 3.140e+04
Df Residuals: 2953 BIC: 3.150e+04
Df Model: 16
Covariance Type: nonrobust
=======================================================================================
coef std err t P>|t| [0.025 0.975]
---------------------------------------------------------------------------------------
activos 4.838e-07 1.39e-08 34.757 0.000 4.56e-07 5.11e-07
n_empleados 0.0209 0.002 12.916 0.000 0.018 0.024
end_patrimonial -0.0832 0.088 -0.946 0.344 -0.256 0.089
end_corto_plazo 23.6055 1.800 13.114 0.000 20.076 27.135
end_patrimonial_ct 0.0500 0.142 0.353 0.724 -0.228 0.328
end_patrimonial_nct 0.6900 0.586 1.177 0.239 -0.460 1.840
rot_cartera 2.081e-05 1.99e-05 1.048 0.295 -1.81e-05 5.98e-05
per_med_pago 1.239e-08 1.27e-08 0.977 0.329 -1.25e-08 3.73e-08
impac_gasto_a_v -1.5354 0.733 -2.093 0.036 -2.973 -0.097
impac_carga_finan -102.0002 21.526 -4.738 0.000 -144.208 -59.793
margen_bruto -25.6326 3.150 -8.138 0.000 -31.809 -19.457
rent_neta_ventas -29.5289 6.929 -4.261 0.000 -43.116 -15.942
roe 0.0675 0.042 1.608 0.108 -0.015 0.150
gastos_admin_ventas 9.57e-07 5.33e-08 17.964 0.000 8.53e-07 1.06e-06
deuda_total 2.121e-06 1.33e-07 15.981 0.000 1.86e-06 2.38e-06
deuda_total_c_plazo 4.953e-06 4.72e-07 10.498 0.000 4.03e-06 5.88e-06
==============================================================================
Omnibus: 4163.035 Durbin-Watson: 2.040
Prob(Omnibus): 0.000 Jarque-Bera (JB): 2455536.160
Skew: 7.777 Prob(JB): 0.00
Kurtosis: 143.027 Cond. No. 2.81e+09
==============================================================================
Notes:
[1] R² is computed without centering (uncentered) since the model does not contain a constant.
[2] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[3] The condition number is large, 2.81e+09. This might indicate that there are
strong multicollinearity or other numerical problems.
# Predicciones y evaluación para Atras
y_pred_atras = final_model.predict(X_selected)
mae_atras, mse_atras, rmse_atras, r2_atras = evaluate_model(y, y_pred_atras)
# Mostrar evaluación
print("\n(Atrás) Métricas de evaluación:")
print(f"Mean Absolute Error (MAE): {mae_atras:.2f}")
print(f"Mean Squared Error (MSE): {mse_atras:.2f}")
print(f"Root Mean Squared Error (RMSE): {rmse_atras:.2f}")
print(f"R-squared: {r2_atras:.2f}")
(Atrás) Métricas de evaluación:
Mean Absolute Error (MAE): 16.66
Mean Squared Error (MSE): 2270.38
Root Mean Squared Error (RMSE): 47.65
R-squared: 0.79
10.2. Regularización#
La regularización es un método que nos permite restringir el proceso de estimación, se usa para evitar un posible sobre ajuste del modelo (overfitting).
Una forma de hacer regularización es donde los coeficientes de variables en el modelo no sean muy grandes (regresión ridge). Otra forma es contraer los coeficientes, llegando a tener coeficientes iguales a cero (regresión lasso).
Como regla general, el segundo enfoque suele ser mejor que el primero.
Los coeficientes regularizados se obtiene usando una función de penalidad
donde
Existen diferentes opciones para funciones de pérdida:
Exponencial:
Logística:
Error cuadrático:
Error absoluto:
Huber

Hay dos tipos de funciones de penalidad:
: esta función de penalidad restringe la suma de cuadrados de los coeficientes,
Cuando
: Los coeficientes se restringen tal que su suma de valores absolutos,
sea menor que un valor dado. La evidencia empírica sugiere que la penalización
10.2.1. Regresión Ridge#
En mínimos cuadrados ordinarios, las estimaciones de
La regresión ridge es muy similar al enfoque de mínimos cuadrados, pero los coeficientes de la regresión ridge
donde ridge
siempre generará un modelo que incluya todos los predictores. Incrementar el valor de
10.2.2. Regresión Lasso#
La penalización
10.2.2.1. Ejemplo#
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge, Lasso
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error
from sklearn.preprocessing import StandardScaler
# Dividir los datos en entrenamiento y prueba
#X = X_selected
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=85)
# Escalar los datos
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Crear modelos de Ridge y Lasso
ridge = Ridge(alpha=1.0) # Alpha controla la penalización
lasso = Lasso(alpha=5.0)
regOLS = LinearRegression()
# Entrenar los modelos
ridge.fit(X_train_scaled, y_train)
lasso.fit(X_train_scaled, y_train)
regOLS.fit(X_train_scaled, y_train)
# Predicciones
y_pred_ridge_tr = ridge.predict(X_train_scaled)
y_pred_lasso_tr = lasso.predict(X_train_scaled)
y_pred_ols_tr = regOLS.predict(X_train_scaled)
# Calcular el error cuadrático medio (MSE) TRAIN
num_factor = 1
mse_ridge_tr = mean_squared_error(y_train, y_pred_ridge_tr)/num_factor
mse_lasso_tr = mean_squared_error(y_train, y_pred_lasso_tr)/num_factor
mse_ols_tr = mean_squared_error(y_train, y_pred_ols_tr)/num_factor
# Resultados
print("Evaluación del modelo en TRAIN:\n")
print(f"MSE Ridge: {mse_ridge_tr:.2f}")
print(f"MSE Lasso: {mse_lasso_tr:.2f}")
print(f"MSE OLS: {mse_ols_tr:.2f}")
# Predicciones
y_pred_ridge = ridge.predict(X_test_scaled)
y_pred_lasso = lasso.predict(X_test_scaled)
y_pred_ols = regOLS.predict(X_test_scaled)
# Calcular el error cuadrático medio (MSE) TEST
mse_ridge = mean_squared_error(y_test, y_pred_ridge)/num_factor
mse_lasso = mean_squared_error(y_test, y_pred_lasso)/num_factor
mse_ols = mean_squared_error(y_test, y_pred_ols)/num_factor
# Resultados
print("\nEvaluación del modelo en TEST:\n")
print(f"MSE Ridge: {mse_ridge:.2f}")
print(f"MSE Lasso: {mse_lasso:.2f}")
print(f"MSE OLS: {mse_ols:.2f}")
Evaluación del modelo en TRAIN:
MSE Ridge: 1852.46
MSE Lasso: 2083.61
MSE OLS: 1852.46
Evaluación del modelo en TEST:
MSE Ridge: 3527.83
MSE Lasso: 3663.03
MSE OLS: 3527.39
# Mostrar coeficientes con nombres
ridge_coefficients = pd.DataFrame(ridge.coef_, index=X.columns, columns=['Ridge Coefficients'])
lasso_coefficients = pd.DataFrame(lasso.coef_, index=X.columns, columns=['Lasso Coefficients'])
ols_coefficients = pd.DataFrame(regOLS.coef_, index=X.columns, columns=['OLS Coefficients'])
# Combinar coeficientes en un solo DataFrame
coefficients = pd.concat([ridge_coefficients, lasso_coefficients,ols_coefficients], axis=1)
print("\nCoeficientes:")
print(coefficients)
Coeficientes:
Ridge Coefficients Lasso Coefficients \
activos 46.452401 51.339290
utilidad_an_imp 7.140067 2.802706
n_empleados 20.230335 15.067053
liquidez_corriente 1.097188 -0.000000
end_activo -0.310678 0.000000
end_patrimonial -2.044002 0.000000
end_activo_fijo -0.244253 -0.000000
end_corto_plazo 3.527861 0.000000
cobertura_interes 0.281633 -0.000000
apalancamiento_financiero -0.502044 -0.000000
end_patrimonial_ct 0.527377 0.000000
end_patrimonial_nct 1.076781 0.000000
rot_cartera 0.157103 0.000000
rot_ventas 1.052480 0.000000
per_med_cobranza -0.919068 -0.000000
per_med_pago 1.745660 0.000000
impac_gasto_a_v -2.108877 -0.000000
impac_carga_finan -4.171406 -0.037732
rent_neta_activo 2.607665 0.000000
margen_bruto -8.536271 -4.644804
margen_operacional 5.138157 0.000000
rent_neta_ventas -4.865955 -0.924355
rent_ope_patrimonio -0.019458 -0.000000
roe 2.066205 0.000000
fortaleza_patrimonial -0.921451 -0.000000
gastos_financieros 3.886436 0.000000
gastos_admin_ventas 31.292825 23.488379
depreciaciones -3.459897 -0.000000
amortizaciones -6.807988 -0.000000
deuda_total 17.489693 14.618748
deuda_total_c_plazo 11.799476 10.246291
OLS Coefficients
activos 46.520173
utilidad_an_imp 7.103579
n_empleados 20.224461
liquidez_corriente 1.098485
end_activo -0.310745
end_patrimonial -2.056202
end_activo_fijo -0.244556
end_corto_plazo 3.530621
cobertura_interes 0.281992
apalancamiento_financiero -0.502272
end_patrimonial_ct 0.530975
end_patrimonial_nct 1.078609
rot_cartera 0.157290
rot_ventas 1.052782
per_med_cobranza -0.924138
per_med_pago 1.746044
impac_gasto_a_v -2.110272
impac_carga_finan -4.169610
rent_neta_activo 2.610887
margen_bruto -8.539168
margen_operacional 5.150837
rent_neta_ventas -4.872438
rent_ope_patrimonio -0.020343
roe 2.076751
fortaleza_patrimonial -0.920677
gastos_financieros 3.868392
gastos_admin_ventas 31.299005
depreciaciones -3.459313
amortizaciones -6.817272
deuda_total 17.486285
deuda_total_c_plazo 11.794246
# Graficar los resultados
plt.figure(figsize=(12, 6))
plt.scatter(y_test, y_pred_ridge, color='blue', label="Predicciones Ridge", alpha=0.5)
plt.scatter(y_test, y_pred_lasso, color='red', label="Predicciones Lasso", alpha=0.5)
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='black', linestyle='--', label="Línea de referencia")
plt.xlabel("Valores reales")
plt.ylabel("Valores predichos")
plt.title("Comparación de Predicciones: Ridge vs Lasso")
plt.legend()
plt.show()

Ajuste con el mejor
from sklearn.model_selection import GridSearchCV
from sklearn.model_selection import KFold
# Definir el rango de valores de alpha (lambda) a evaluar
param_grid = {'alpha': [0.1, 0.5, 0.9, 1, 2,3,4,5,10,20,30,40,50,100,150,200,300,400,500]}
# Crear el modelo de Ridge y Lasso
ridge = Ridge()
lasso = Lasso()
# Crear un KFold con shuffle y random_state
kfold = KFold(n_splits=5, shuffle=True, random_state=42)
# Implementar GridSearchCV para Ridge
ridge_search = GridSearchCV(ridge, param_grid, scoring='neg_mean_squared_error', cv=kfold) #cv=5 sería determinista
ridge_search.fit(X_train_scaled, y_train)
# Implementar GridSearchCV para Lasso
lasso_search = GridSearchCV(lasso, param_grid, scoring='neg_mean_squared_error', cv=kfold)
lasso_search.fit(X_train_scaled, y_train)
# Obtener el mejor valor de alpha y el MSE para Ridge
best_ridge_alpha = ridge_search.best_params_['alpha']
best_ridge_mse = -ridge_search.best_score_/num_factor # Negativo para convertirlo en MSE normal
# Obtener el mejor valor de alpha y el MSE para Lasso
best_lasso_alpha = lasso_search.best_params_['alpha']
best_lasso_mse = -lasso_search.best_score_/num_factor # Negativo para convertirlo en MSE normal
import matplotlib.pyplot as plt
import numpy as np
# Obtener los resultados de Ridge y Lasso
ridge_results = ridge_search.cv_results_
lasso_results = lasso_search.cv_results_
# Valores de alpha
alphas = ridge_results['param_alpha'].data
# MSE para Ridge
ridge_mse = -ridge_results['mean_test_score']
# MSE para Lasso
lasso_mse = -lasso_results['mean_test_score']
# Crear la figura
plt.figure(figsize=(14, 7))
# Graficar Ridge
plt.subplot(1, 2, 1)
plt.plot(alphas, ridge_mse, marker='o', label='MSE Ridge', color='blue')
plt.axvline(x=best_ridge_alpha, color='red', linestyle='--', label=f'Best alpha: {best_ridge_alpha}')
plt.xscale('log') # Escala logarítmica para los ejes
plt.title('Ridge Regression: MSE vs. Alpha')
plt.xlabel('Alpha (log scale)')
plt.ylabel('Mean Squared Error')
plt.legend()
plt.grid(True)
# Graficar Lasso
plt.subplot(1, 2, 2)
plt.plot(alphas, lasso_mse, marker='o', label='MSE Lasso', color='green')
plt.axvline(x=best_lasso_alpha, color='red', linestyle='--', label=f'Best alpha: {best_lasso_alpha}')
plt.xscale('log') # Escala logarítmica para los ejes
plt.title('Lasso Regression: MSE vs. Alpha')
plt.xlabel('Alpha (log scale)')
plt.ylabel('Mean Squared Error')
plt.legend()
plt.grid(True)
# Mostrar la gráfica
plt.tight_layout()
plt.show()

# Imprimir los mejores resultados
print("\nEvaluación del modelo en CV:\n")
print(f"Mejor alpha para Ridge: {best_ridge_alpha}")
print(f"Mejor MSE para Ridge: {best_ridge_mse:.2f} ")
print(f"Mejor alpha para Lasso: {best_lasso_alpha}")
print(f"Mejor MSE para Lasso: {best_lasso_mse:.2f} ")
# Ajustar los modelos nuevamente con los mejores alpha
ridge_best = Ridge(alpha=best_ridge_alpha)
lasso_best = Lasso(alpha=best_lasso_alpha)
ridge_best.fit(X_train_scaled, y_train)
lasso_best.fit(X_train_scaled, y_train)
# Predicciones con los mejores modelos TRAIN
y_pred_ridge_best_tr = ridge_best.predict(X_train_scaled)
y_pred_lasso_best_tr = lasso_best.predict(X_train_scaled)
# Calcular el MSE en el conjunto TRAIN
mse_ridge_best_tr = mean_squared_error(y_train, y_pred_ridge_best_tr)/num_factor
mse_lasso_best_tr = mean_squared_error(y_train, y_pred_lasso_best_tr)/num_factor
# Mostrar los resultados
print("\nEvaluación del modelo en TRAIN:\n")
print(f"\nMSE Ridge con mejor alpha: {mse_ridge_best_tr:.2f}")
print(f"MSE Lasso con mejor alpha: {mse_lasso_best_tr:.2f} ")
# Predicciones con los mejores modelos
y_pred_ridge_best = ridge_best.predict(X_test_scaled)
y_pred_lasso_best = lasso_best.predict(X_test_scaled)
# Calcular el MSE en el conjunto de prueba
mse_ridge_best = mean_squared_error(y_test, y_pred_ridge_best)/num_factor
mse_lasso_best = mean_squared_error(y_test, y_pred_lasso_best)/num_factor
# Mostrar los resultados
print("\nEvaluación del modelo en TEST:\n")
print(f"\nMSE Ridge con mejor alpha: {mse_ridge_best:.2f}")
print(f"MSE Lasso con mejor alpha: {mse_lasso_best:.2f} ")
Evaluación del modelo en CV:
Mejor alpha para Ridge: 300
Mejor MSE para Ridge: 2282.32
Mejor alpha para Lasso: 0.9
Mejor MSE para Lasso: 2374.17
Evaluación del modelo en TRAIN:
MSE Ridge con mejor alpha: 1903.47
MSE Lasso con mejor alpha: 1871.67
Evaluación del modelo en TEST:
MSE Ridge con mejor alpha: 3617.36
MSE Lasso con mejor alpha: 3534.08