Ein Kriterium für die Auswahl des optimalen Wertes von mit einem elastischen Netz oder einer ähnlichen bestraften Regression besteht darin, eine Auftragung der Abweichung gegen den Bereich von und auszuwählen, wenn die Abweichung minimiert ist (oder innerhalb eines Standardfehlers von Minimum).λ λ λ
Aber ich habe Schwierigkeiten zu verstehen , was genau glmnet
Displays mit plot.cv.glmnet
, weil die Handlung angezeigt überhaupt nicht die Ergebnisse der Auftragung die Devianz gegen ähnelt .
set.seed(4567)
N <- 500
P <- 100
coefs <- NULL
for(p in 1:P){
coefs[p] <- (-1)^p*100*2^(-p)
}
inv.logit <- function(x) exp(x)/(1+exp(x))
X <- matrix(rnorm(N*P), ncol=P, nrow=N)
Y <- rbinom(N, size=1, p=inv.logit(cbind(1, X)%*%c(-4, coefs)))
plot(test <- cv.glmnet(x=X, y=Y, family="binomial", nfolds=10, alpha=0.8))
plot(log(test$lambda), deviance(test$glmnet.fit))
Es scheint, dass das zweite Diagramm die elastische Nettostrafe nicht enthält und auch vertikal falsch skaliert ist. Ich begründe die Behauptung damit, dass die Form der Kurve für größere Werte von der der Ausgabe ähnelt . Wenn ich jedoch versucht habe, die Strafe selbst zu berechnen, scheint mein Versuch ebenfalls äußerst ungenau zu sein.glmnet
penalized.dev.fn <- function(lambda, alpha=0.2, data, cv.model.obj){
dev <- deviance(cv.model.obj$glmnet.fit)[seq_along(cv.model.obj$lambda)[cv.model.obj$lambda==lambda]]
beta <- coef(cv.model.obj, s=lambda)[rownames(coef(cv.model.obj))!="(Intercept)"]
penalty <- lambda * ( (1-alpha)/2*(beta%*%beta) + alpha*sum(abs(beta)) )
penalized.dev <- penalty+dev
return(penalized.dev)
}
out <- sapply(test$lambda, alpha=0.2, cv.model.obj=test, FUN=penalized.dev.fn)
plot(log(test$lambda), out)
Meine Frage ist: Wie berechnet man die im Standarddiagramm angegebene Abweichung manuell plot.cv.glmnet
? Wie lautet die Formel und was habe ich bei meinem Versuch, sie zu berechnen, falsch gemacht?
cv.glmnet
eine 10-fache Kreuzvalidierung durchgeführt wird, oder? Es wird also der mittlere +/- 1 Standardfehler der Abweichung auf die 10% Hold-Out-Daten aufgetragen?Antworten:
Ich wollte nur die Eingabe ergänzen, habe aber im Moment keine präzise Antwort und es ist zu lang für einen Kommentar. Hoffentlich gibt dies mehr Einblick.
Es scheint, dass sich die interessierende Funktion in der entpackten glmnet-Bibliothek befindet und als cv.lognet.R bezeichnet wird. Es ist schwierig, alles explizit zu verfolgen, wie dies im S3 / S4-Code der Fall ist, aber die obige Funktion wird als interne glmnet-Funktion aufgeführt , 'wird von den Autoren verwendet und scheint mit der Berechnung der Binomialabweichung durch cv.glmnet übereinzustimmen.
Ich habe es zwar nirgendwo in der Zeitung gesehen, von der Verfolgung des glmnet-Codes bis zu cv.lognet, aber ich habe festgestellt, dass es etwas verwendet, das hier als begrenzte binomiale Abweichung bezeichnet wird .
predmat ist eine Matrix der begrenzten Wahrscheinlichkeitswerte (E, 1-E), die für jedes Lambda ausgegeben werden und mit den Komplementwerten von y und y verglichen werden, was zu lp führt. Sie werden dann in die 2 * (ly-lp) Abweichungsform gebracht und über kreuzvalidierte Hold-out-Falten gemittelt, um cvm - den mittleren kreuzvalidierten Fehler - und cv-Bereiche zu erhalten, die Sie im ersten Bild dargestellt haben.
Ich denke, die manuelle Abweichungsfunktion (2. Plot) wird nicht so berechnet wie diese interne (1. Plot).
quelle
Also habe ich die CRAN-Site besucht und heruntergeladen, was meiner Meinung nach die Quelle des glmnet-Pakets ist . In ./glmnet/R/plot.cv.glmnet.R scheinen Sie den Quellcode zu finden, nach dem Sie suchen. Es ist ziemlich kurz, also füge ich es hier ein, aber es ist wahrscheinlich am besten, wenn Sie es selbst überprüfen, um sicherzugehen, dass tatsächlich der Code ausgeführt wird.
quelle
getS3method('plot', 'cv.glmnet')
ohne das Quellpaket herunterladen zu müssen. (Internglmnet
hat gerade eine Funktion namens aufgerufen,plot.cv.glmnet
aber nicht exportiert. Sie können sie weiterhin sehen, indem Sie mit dem:::
Operator in den Namespace spähen :)glmnet:::plot.cv.glmnet
.