Welche Abweichung verwendet glmnet, um Werte von zu vergleichen ?

8

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 glmnetDisplays 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))

Geben Sie hier die Bildbeschreibung ein Geben Sie hier die Bildbeschreibung ein

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?

Sycorax sagt Reinstate Monica
quelle
Sie wissen, dass cv.glmneteine 10-fache Kreuzvalidierung durchgeführt wird, oder? Es wird also der mittlere +/- 1 Standardfehler der Abweichung auf die 10% Hold-Out-Daten aufgetragen?
Andrew M
Ich bin mir dessen bewusst, ja.
Sycorax sagt Reinstate Monica

Antworten:

6

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 .

- -[Y.Log10(E.)+(1- -Y.)Log10(1- -E.)]]

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).

    # from cv.lognet.R

    cvraw=switch(type.measure,
    "mse"=(y[,1]-(1-predmat))^2 +(y[,2]-predmat)^2,
    "mae"=abs(y[,1]-(1-predmat)) +abs(y[,2]-predmat),
    "deviance"= {
      predmat=pmin(pmax(predmat,prob_min),prob_max)
      lp=y[,1]*log(1-predmat)+y[,2]*log(predmat)
      ly=log(y)
      ly[y==0]=0
      ly=drop((y*ly)%*%c(1,1))
      2*(ly-lp)

   # cvm output
   cvm=apply(cvraw,2,weighted.mean,w=weights,na.rm=TRUE)
klopfen
quelle
Danke für die Antwort, pat. Dies behandelt alle Fragen, die ich zur Funktionsweise des Verfahrens und den zugrunde liegenden statistischen Konzepten hatte, nicht nur die Software.
Sycorax sagt Reinstate Monica
2

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.

plot.cv.glmnet=function(x,sign.lambda=1,...){
  cvobj=x
  xlab="log(Lambda)"
  if(sign.lambda<0)xlab=paste("-",xlab,sep="")
  plot.args=list(x=sign.lambda*log(cvobj$lambda),y=cvobj$cvm,ylim=range(cvobj$cvup,cvobj$cvlo),xlab=xlab,ylab=cvobj$name,type="n")
      new.args=list(...)
      if(length(new.args))plot.args[names(new.args)]=new.args
    do.call("plot",plot.args)
    error.bars(sign.lambda*log(cvobj$lambda),cvobj$cvup,cvobj$cvlo,width=0.01,col="darkgrey")
  points(sign.lambda*log(cvobj$lambda),cvobj$cvm,pch=20,col="red")
axis(side=3,at=sign.lambda*log(cvobj$lambda),labels=paste(cvobj$nz),tick=FALSE,line=0)
abline(v=sign.lambda*log(cvobj$lambda.min),lty=3)
    abline(v=sign.lambda*log(cvobj$lambda.1se),lty=3)
  invisible()
}
Diego
quelle
1
S3-Methoden sind in R leicht versteckt, aber um genau zu sehen, was ausgeführt wird, können Sie eingeben, getS3method('plot', 'cv.glmnet')ohne das Quellpaket herunterladen zu müssen. (Intern glmnethat gerade eine Funktion namens aufgerufen, plot.cv.glmnetaber nicht exportiert. Sie können sie weiterhin sehen, indem Sie mit dem :::Operator in den Namespace spähen :) glmnet:::plot.cv.glmnet.
Andrew M
(+1) Danke für die Antwort, Diego. Dies weist mich in die richtige Richtung und weist implizit darauf hin, wo ich falsch gelaufen bin. Ich werde mich jedoch vorerst zurückhalten, da dies die spezifische statistische Frage (Vize-Programmierung), die am Ende meines Beitrags angegeben ist, nicht beantwortet .
Sycorax sagt Reinstate Monica