Anhand einer 2D-Demo mit Spielzeugdaten wird erklärt, was bei der logistischen Regression mit und ohne Regularisierung für eine perfekte Trennung vor sich ging. Die Experimente begannen mit einem überlappenden Datensatz und wir trennten nach und nach zwei Klassen. Die objektive Funktionskontur und die Optima (logistischer Verlust) werden in der rechten Unterabbildung gezeigt. Die Daten und die lineare Entscheidungsgrenze sind in der linken Unterabbildung aufgetragen.
Zuerst versuchen wir die logistische Regression ohne Regularisierung.
- Wie wir sehen können, ändert sich die Zielfunktion (logistischer Verlust) dramatisch, und der Optimierungsfaktor verschiebt sich zu einem größeren Wert .
- Wenn wir den Vorgang abgeschlossen haben, ist die Kontur keine "geschlossene Form". Zu diesem Zeitpunkt ist die Zielfunktion immer kleiner, wenn sich die Lösung in der oberen rechten Ecke befindet.
Als nächstes versuchen wir die logistische Regression mit L2-Regularisierung (L1 ist ähnlich).
Bei der gleichen Konfiguration ändert das Hinzufügen einer sehr kleinen L2-Regularisierung die Änderungen der Zielfunktion in Bezug auf die Trennung der Daten.
In diesem Fall haben wir immer das "konvexe" Ziel. Egal wie stark die Daten voneinander getrennt sind.
Code (Ich verwende denselben Code auch für diese Antwort: Regularisierungsmethoden für die logistische Regression )
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)