Se utilizará una demostración en 2D con datos de juguetes para explicar lo que estaba sucediendo para una separación perfecta en la regresión logística con y sin regularización. Los experimentos comenzaron con un conjunto de datos superpuestos y gradualmente separamos dos clases. La función objetivo de contorno y optima (pérdida logística) se mostrará en la figura a la derecha. Los datos y el límite de decisión lineal se trazan en la figura secundaria izquierda.
Primero intentamos la regresión logística sin regularización.
- Como podemos ver con los datos que se separan, la función objetivo (pérdida logística) está cambiando drásticamente, y la optimización se está alejando a un valor mayor .
- Cuando hayamos completado la operación, el contorno no será una "forma cerrada". En este momento, la función objetivo siempre será más pequeña cuando la solución se mueva a la esquina superior derecha.
A continuación, intentamos la regresión logística con la regularización de L2 (L1 es similar).
Con la misma configuración, agregar una regularización L2 muy pequeña cambiará los cambios de la función objetivo con respecto a la separación de los datos.
En este caso, siempre tendremos el objetivo "convexo". No importa cuánta separación tengan los datos.
código (también uso el mismo código para esta respuesta: métodos de regularización para la regresión logística )
set.seed(0)
d=mlbench::mlbench.2dnormals(100, 2, r=1)
x = d$x
y = ifelse(d$classes==1, 1, 0)
logistic_loss <- function(w){
p = plogis(x %*% w)
L = -y*log(p) - (1-y)*log(1-p)
LwR2 = sum(L) + lambda*t(w) %*% w
return(c(LwR2))
}
logistic_loss_gr <- function(w){
p = plogis(x %*% w)
v = t(x) %*% (p - y)
return(c(v) + 2*lambda*w)
}
w_grid_v = seq(-10, 10, 0.1)
w_grid = expand.grid(w_grid_v, w_grid_v)
lambda = 0
opt1 = optimx::optimx(c(1,1), fn=logistic_loss, gr=logistic_loss_gr, method="BFGS")
z1 = matrix(apply(w_grid,1,logistic_loss), ncol=length(w_grid_v))
lambda = 5
opt2 = optimx::optimx(c(1,1), fn=logistic_loss, method="BFGS")
z2 = matrix(apply(w_grid,1,logistic_loss), ncol=length(w_grid_v))
plot(d, xlim=c(-3,3), ylim=c(-3,3))
abline(0, -opt1$p2/opt1$p1, col='blue', lwd=2)
abline(0, -opt2$p2/opt2$p1, col='black', lwd=2)
contour(w_grid_v, w_grid_v, z1, col='blue', lwd=2, nlevels=8)
contour(w_grid_v, w_grid_v, z2, col='black', lwd=2, nlevels=8, add=T)
points(opt1$p1, opt1$p2, col='blue', pch=19)
points(opt2$p1, opt2$p2, col='black', pch=19)