Definir que es una Funcion de Costo.
Repasar la nocion de underfitting/overfitting.
Introducir Regularizacion como un metodo para reducir el overfitting.
Describir las tecnicas de regularizacion LASSO, RIDGE y ELASTIC NET
Supongamos una variable $y$ que tiene una dependencia f(x) con las variables $x$ y sea $\epsilon$ la parte aleatoria inherente que no puede ser descripta (ruido).
Nuestro objetivo cuando realizamos un ajuste es encontrar una funcion $\hat{f}$ que permita realizar predicciones $\hat{y}$ que se asemejen a $y$
Dezconocemos la verdadera formula de $f(x)$ con las dependencia explicitas de las variables x. Una solucion muy simple a este problema es la propuesta $\hat{f}$ de la regresion lineal.
Cuando realizamos una regresion lineal, proponemos una funcion $\hat{f}$ que es combinacion lineal de las variables $x_n$:
El objetivo ahora es encontrar los parametros $\beta_n$ que reduzcan la diferencia entre la funcion real $f(x)$ (representada por los datos entrenamiento) y nuestra propuesta $\hat{f}$, en otras palabras queremos reducir el error en la prediccion a 0.
Si usamos la definicion de las predicciones $\hat{y}$ podemos reescribir el MSE como:
El supraindice indica la i-esima de N observaciones y $\bar{\beta}$ es el vector de coeficientes $(\beta_0 , \beta_1 , \beta_2 , ... , \beta_n)$ mientras $\bar{x}^{(i)}$ e $\bar{y}^{(i)}$ son nuestros datos de entrenamiento.
$y^{(i)}$ = valor de la variable target para la i-esima observacion (fila).
$x_j^{(i)}$ = valor de la j-esima varible explicativa (columna) para la i-esima observacion.
$\beta_j $ = coeficiente de la j-esima varible explicativa.
con $j$ va de 1 a N columnas.
$i$ va de 1 a n filas.
Cuando entrenamos un modelo de regresion lineal, buscamos reducir el MSE usando los datos de entrenamiento, $\bar{x}^{(i)}$ e $\bar{y}^{(i)}$ son nuestros datos de entrenamiento y la unica incognita es el vector de los coeficientes $ \bar{\beta}$
Buscamos minimizar el MSE, en el calculo diferencial buscar para que valores de sus argumentos una funcion es minima (o maxima) se lo conoce como "optimizacion". Sabemos que los extremos de una funcion se dan en los valores para los cuales la derivada primera es nula.
Cada algoritmo tiene su propia funcion de costo. A lo largo del curso vamos a ver otros algoritmos y sus funciones de costo.
Ajustar datos es minimizar una funcion de costo y asi encontrar los parametro que reduzcan el error en nuestra prediccion.
En teoria se podria derivar la funcion de costo y encontrar una relacion analitica entre los $\beta$ y los datos de entrenamieto.
En la practica, las implementaciones de estos algoritmos en diferentes lenguajes de programacion utilizan un metodo llamado Descenso Gradiente.
Este metodo busca iterativamente en el espacio de todos los posibles parametros $\beta_n$, la combinacion de $\beta_n^*$ que minimicen la funcion de costo. Esos seran los parametros que usaremos para nuestro modelo.
La manera en la que los encuentra es dar pequeños pasos (learning steps) en la direccion contraria, en el espacio de parametros, para la cual haya una mayor variacion de la funcion de costo.
Si el modelo es demasiado simple (pocos grados de libertad), entonces no importa cuán grande sea la muestra: tenemos sesgo o error sistemático en la prediccion (underfitting).
Si el modelo es demasiado complejo (demasiados grados de libertad), entonces el modelo se aprende de memoria irregularidades espurias de la muestra generando un sobre-ajuste (overfitting). El error en el test set es mayor que el error en el training set.
Como vimos en la practica, para una regresion lineal nada nos impide agregar o quitar variables, podemos hacer muy simple o muy complejo nuestro modelo.
Necesitamos algo que nos ayude a encontrar el balance optimo.
Como vimos en la practica, para una regresion lineal nada nos impide agregar o quitar variables, podemos hacer muy simple o muy complejo nuestro modelo.
Necesitamos algo que nos ayude a encontrar el balance optimo.
# betas reales!
a = 3
b = -1
c = 1
# funcion real:
x = np.linspace(-1, 4, 40)
y = a*x**2 + b*x + c + np.random.randn(40)*5
Las técnicas de regularización agregan una “penalidad” a la función de costo, condicionando el tamaño de los $\beta_n$:
Una primera ituicion sobre la norma de un vector es la distancia entre sus extremos, como ya vimos hay varias maneras de medir distancia (euclidia, manhattan). En este sentido podemos generalizar la nocion de norma euclidiana a norma-p:
Estas técnicas proponen cambiar ligeramente el problema de optimización de mínimos cuadrados, para intentar “achicar” (shrinkage en la literatura) el valor absoluto de los estimadores $\beta_n$.
Usemos de ejemplo Ridge (p=2 norma euclidiana):
Al igual que una Regresion comun, buscamos minizar la funcion de costo.
Sin embargo, existe un término de penalización, que es menor cuando los $ \beta_n $ se acercan a cero, por lo tanto tiene el efecto de achicar los mismos hacia cero (tanto si son negativos como positivos)
El hiperparámetro $\alpha$ nos permite ponderar cuan importante es el tamaño de los $ \beta_n $, cuando $\alpha = 0$ obtenemos la regresion comun.
¿Cuál es el mejor valor para $\alpha$? ¿Cómo elegíamos el valor óptimo de un hiperparámetro? Como siempre, lo hacemos a través de CROSS VALIDATION
Para un dataset crediticio de ejemplo donde se busca predecir en funcion de 4 variables (income, limit, rating y student) , se muestra como varian los coeficientes de la Regression Ridge en funcion del hiperparametro $\alpha$
En este ejemplo para otro dataset se grafica el MSE en la predicion (rojo) en funcion del hiperparametro $\alpha$ (recordar $\alpha = 0$ Regresion Lineal)
Recordemos que podemos reescribir el MSE ($MSE= Var + Bias^2 $) para poder analizar su variacion con respecto a $\alpha$
En verde la varianza en las predicciones, que vemos que disminuyen a medida que acentuamos la penalizacion en los coeficientes. Ganamos precision
En negro el bias en las predicciones del modelo, para $\alpha = 0$ es 0 (sobreajuste), a medida que acentuamos la penalizacion el bias aumenta. Perdemos exactitud.
Con la penalizacion Ridge logramos mejorar la varianza a costa de un aumento del bias. Con linea punteada el MSE de la regresion lineal sin penalizacion.
Como vimos la unica diferencia entre Lasso y Ridge es el coeficiente de la norma:
Como en la regresión ridge, Lasso “achica” los coeficientes $\beta_m$ hacia el cero.
Sin embargo, en el caso de Lasso, la norma L1 para valores de $\alpha$ suficientemente grandes permite obtener valores de $\beta_n = 0$
Si algunos $\beta_n = 0$ significa que algunas variables no van a estar presentes en el modelo final. De regalo Lasso hace selección de variables!
Al igual que en Ridge, la elección de un buen valor $\alpha$ es crítico en Lasso; nuevamente, cross-validation es el método para su elección.
Para un dataset crediticio de ejemplo donde se busca predecir en funcion de 4 variables (income, limit, rating y student) , se muestra como varian los coeficientes $\beta_n$ de la Regression Lasso en funcion del hiperparametro $\alpha$
Se puede ver que para $\alpha = 0$ los coeficientes son los mismos que para la regresion lineal comun.
Para $\alpha > 500$ los coeficientes son extrictamente 0. Van anulandose uno por uno.
Miremos un ejemplo con solo dos variables. Al minimizar la funcion de costo tanto de ridge como lasso, estamos buscando en el espacio de los $\beta_1$ y $\beta_2$ un punto que satisfaga ambos terminos de la funcion de costo. $ LOSS = \sum_{i}^N (\bar{\beta} \cdot \mathbf{x}^{(i)} -y^{(i)} )^2 + \alpha \left |\left | \bar{\beta} \right |\right |$
En ese espacio, el primer termino de la funcion de costo son las elipses en rojo. La norma L1 de Lasso tiene forma de rombo, por su parte la norma L2 de Ridge es un circulo.
Intuitivamente quedemonos con la idea de que solo la forma de la norma L1 permite que las soluciones a la optimizacion de la funcion de costo 'caigan' en los ejes, donde $\beta_n = 0$ (en el ejemplo $\beta_1 = 0$ y $\beta_2 \neq 0$)
¿Cómo funciona?
Hacemos el split train/validación y test
Dividimos el dataset de train/validación en k grupos (generalmente, 5 o 10 suele ser la medida convencional) del mismo tamaño.
En la iteración i-ésima, el i-esimo grupo generado funciona como un conjunto de validación; el resto de los grupos es el conjunto de training
Entrenamos un modelo sobre el conjunto de training definido en 3.
Hacemos las predicciones sobre el conjunto de validación definido en 3. y calculamos el error sobre este conjunto
Repetimos los pasos 3. a 5. k veces, variando así los conjuntos de entrenamiento y de validación en cada iteración.
Promediamos los k errores obtenidos (un valor de error en cada una de las iteraciones).
Que opciones tenemos?:
Ridge usa norma L2 reduce el tamaño de los $\beta_n$, pero no anula ninguno.
Lasso usa norma L1 reduce el tamaño de los $\beta_n$ hasta el punto de anular algunas variables.
Elastic-Net combina ambas.
Los metodos que vimos hoy tanto la estimación de los coeficientes como la predicción son sensibles a la escala.
Recordemos el problema de optimización que se resuelve (veamos como ejemplo Ridge):
Si una variable $x_m$ se encuentra en una escala que le da un valor absoluto mayor, esto va a afectar el cálculo de la suma de cuadrados del vector de coeficientes.
Por ejemplo, un dataset con $x_1$ una variable que tiene valores entre (10000 y 10 000 000) y $x_2$ una variable con valores entre ( 0.1 y 1.5). Cuando realizamos la suma en la funcion de costo: $5 000 000 + 0.1 \approx 5 000 000$, la variable $x_2$ pasa a ser despreciable, solo por que tiene otra escala.
Por esta razón es importante estandarizar todas las variables antes de aplicar algun algoritmo de regresion con regularizacion. Esto adimensionaliza las variables.
from sklearn import linear_model
lm = linear_model.LinearRegression()
ridge = linear_model.Ridge(alpha=0.5, normalize=True)
lasso = linear_model.Lasso(alpha=0.5, normalize=True)
alphalist=[0.00001, 0.00005, 0.0001, 0.0005, 0.001, 0.005, 0.01,0.05, 0.1, 1, 5, 10]
#tambien podemos generar un vector con np.logspace, 10^-2 a 10^3 en 1000 pasos: np.logspace(-2,3,1000)
ridge_cv = linear_model.RidgeCV(alphas=alphalist,normalize=True, cv=3)
lasso_cv = linear_model.LassoCV(alphas=alphalist,normalize=True, cv=3)
enet_cv = linear_model.ElasticNetCV(alphas=alphalist,normalize=True, cv=3)
Se tiene un dataset de entrenamiento dftrain.csv
y otro para testeardftest.csv
.
https://raw.githubusercontent.com/carabedo/carabedo.github.io/main/data/dftest.csv
https://raw.githubusercontent.com/carabedo/carabedo.github.io/main/data/dftrain.csv
Entrene un modelo de regresion lineal con los datos y compare la performance con en el dataset de testeo dftest.csv
. Que observa?
Utilice los metodos de Regularizacion Ridge y Lasso con alpha = 0.01
para ajustar los datos. Compare la performance (en el set de testeo) de ambos modelos con la regresion lineal simple. No olvide normalizar los datos!
Interprete los resultados.
Mire como cambian los coeficientes $\bar{\beta}$ para diferentes alphas=np.logspace(-2,1, 500)
usando la regresion Lasso. Puede hacer un loop con el vector de alphas y graficar como cambian los coeficientes en funcion del alpha. Que observa? Cual diria que es la variable mas importante?
Realice nuevamente la regression Ridge y Lasso, esta vez utilice cross-validation para elegir el valor de alpha
optimo.
import pandas as pd
dftrain=pd.read_csv('https://raw.githubusercontent.com/carabedo/carabedo.github.io/main/data/dftrain.csv')
dftest=pd.read_csv('https://raw.githubusercontent.com/carabedo/carabedo.github.io/main/data/dftest.csv')
train=dftrain.iloc[:,:4]
ytrain=dftrain.y
test=dftest.iloc[:,:4]
ytest=dftest.y
from sklearn import linear_model
lm = linear_model.LinearRegression()
model = lm.fit(train, ytrain)
print ("r^2 train :", model.score(train, ytrain))
print ("r^2 test :", model.score(test, ytest))
r^2 train : 0.8043225350695492 r^2 test : 0.523281082747244
#alpha = 0.01 muy poco peso para la penalizacion, no esperamos que cambie mucho
rlm = linear_model.Ridge(alpha=0.01, normalize=True);
model3 = rlm.fit(train, ytrain)
print('Ridge')
print ("r^2 train :", model3.score(train, ytrain))
print ("r^2 test :", model3.score(test, ytest))
Ridge r^2 train : 0.8035762698381405 r^2 test : 0.5434238376399874
lasso = linear_model.Lasso(alpha=0.01, normalize=True)
model4 = lasso.fit(train, ytrain)
print('Lasso')
print ("r^2 train :", model4.score(train, ytrain))
print ("r^2 test :", model4.score(test, ytest))
Lasso r^2 train : 0.8033493373226288 r^2 test : 0.5461009784731242
import numpy as np
coefs=[]
alphas=np.logspace(-2,1, 500)
for alpha in alphas:
lasso = linear_model.Lasso(alpha=alpha, normalize=True)
lasso.fit(train, ytrain)
coefs.append(lasso.coef_)
betas=pd.DataFrame(coefs,columns=dftrain.columns[:-1])
betas['alphas']=alphas
# esta es una manera de graficar varias columnas del mismo data set, usando melt
import plotly.express as px
px.line(betas.melt(id_vars=['alphas']),x='alphas',y='value',color='variable', log_x=True)
betas.melt(id_vars=['alphas'])
alphas | variable | value | |
---|---|---|---|
0 | 0.010000 | x_4 | -0.0 |
1 | 0.010139 | x_4 | -0.0 |
2 | 0.010281 | x_4 | -0.0 |
3 | 0.010424 | x_4 | -0.0 |
4 | 0.010569 | x_4 | 0.0 |
... | ... | ... | ... |
1995 | 9.461324 | x_1 | -0.0 |
1996 | 9.593209 | x_1 | -0.0 |
1997 | 9.726934 | x_1 | -0.0 |
1998 | 9.862522 | x_1 | -0.0 |
1999 | 10.000000 | x_1 | -0.0 |
2000 rows × 3 columns
rlmcv = linear_model.RidgeCV(alphas=np.logspace(-2,2, 1000), normalize=True);
model3 = rlmcv.fit(train, ytrain)
print('alpha: ', model3.alpha_)
print ("r^2 train :", model3.score(train, ytrain))
print ("r^2 test :", model3.score(test, ytest))
alpha: 0.14762814719093903 r^2 train : 0.7822519582013239 r^2 test : 0.6595498475093708
lassocv = linear_model.LassoCV(alphas=np.logspace(-2,2, 1000), normalize=True)
model4 = lassocv.fit(train, ytrain)
print('alpha: ', model4.alpha_)
print ("r^2 train :", model4.score(train, ytrain))
print ("r^2 test :", model4.score(test, ytest))
alpha: 0.23843904700937205 r^2 train : 0.7498661329054479 r^2 test : 0.6806564931029594
An Introduction to Statistical Learning Seccion 6.2 Los ejemplos de Ridge y Lasso
Descomposicion Bias, Variance del MSE
Una comparacion estadistica de LASSO y Ridge
Robust, Interpretable Statistical Models: Sparse Regression with the LASSO