Ich glaube nicht, dass Sie einen Fehler im Code gemacht haben. Dies ist eine Frage der Interpretation der Ausgabe.
Das Lasso gibt nicht an, welche einzelnen Regressoren "prädiktiver" sind als andere. Es hat einfach eine eingebaute Tendenz, Koeffizienten als Null zu schätzen. Je größer der Strafkoeffizient ist, desto größer ist diese Tendenz.Log( λ )
Ihr Kreuzvalidierungsdiagramm zeigt, dass das Modell, wenn immer mehr Koeffizienten auf Null gesetzt werden, immer besser Teilmengen von Werten vorhersagt, die zufällig aus dem Datensatz entfernt wurden. Wenn die besten kreuzvalidierten Vorhersagefehler (hier als "Binomialabweichung" gemessen) erreicht werden, wenn alle Koeffizienten Null sind, sollten Sie vermuten, dass keine lineare Kombination einer Teilmenge der Regressoren zur Vorhersage der Ergebnisse nützlich sein kann.
Sie können dies überprüfen, indem Sie zufällige Antworten generieren, die von allen Regressoren unabhängig sind, und Ihr Anpassungsverfahren auf diese anwenden. Hier ist eine schnelle Möglichkeit, Ihren Datensatz zu emulieren:
n <- 570
k <- 338
set.seed(17)
X <- data.frame(matrix(floor(runif(n*(k+1), 0, 2)), nrow=n,
dimnames=list(1:n, c("y", paste0("x", 1:k)))))
Der Datenrahmen X
hat eine zufällige Binärspalte mit dem Namen "y" und 338 andere Binärspalten (deren Namen keine Rolle spielen). Ich habe Ihren Ansatz verwendet, um "y" gegen diese Variablen zu regressieren, aber - um vorsichtig zu sein - habe ich sichergestellt, dass der Antwortvektor y
und die Modellmatrix x
übereinstimmen (was möglicherweise nicht der Fall ist, wenn in den Daten Werte fehlen). ::
f <- y ~ . - 1 # cv.glmnet will include its own intercept
M <- model.frame(f, X)
x <- model.matrix(f, M)
y <- model.extract(M, "response")
fit <- cv.glmnet(x, y, family="binomial")
Das Ergebnis ist bemerkenswert ähnlich wie Ihres:
plot(fit)
In der Tat gibt das Lasso mit diesen vollständig zufälligen Daten immer noch neun Koeffizientenschätzungen ungleich Null zurück (obwohl wir konstruktionsbedingt wissen, dass die korrekten Werte alle Null sind). Aber wir sollten keine Perfektion erwarten. Da die Anpassung auf dem zufälligen Entfernen von Teilmengen der Daten zur Kreuzvalidierung basiert, erhalten Sie normalerweise nicht die gleiche Ausgabe von einem Lauf zum nächsten. In diesem Beispiel erzeugt ein zweiter Aufruf cv.glmnet
eine Anpassung mit nur einem Koeffizienten ungleich Null. Wenn Sie Zeit haben, ist es daher immer eine gute Idee, das Anpassungsverfahren mehrmals erneut auszuführen und zu verfolgen, welche Koeffizientenschätzungen durchweg ungleich Null sind. Für diese Daten - mit Hunderten von Regressoren - dauert es einige Minuten, bis sie neun weitere Male wiederholt werden.
sim <- cbind(as.numeric(coef(fit)),
replicate(9, as.numeric(coef(cv.glmnet(x, y, family="binomial")))))
plot(1:k, rowMeans(sim[-1,] != 0) + runif(k, -0.025, 0.025),
xlab="Coefficient Index", ylab="Frequency not zero (jittered)",
main="Results of Repeated Cross-Validated Lasso Fits")
Acht dieser Regressoren haben Schätzungen von ungleich Null in etwa der Hälfte der Anpassungen; Der Rest von ihnen hat niemals Schätzungen ungleich Null. Dies zeigt, inwieweit das Lasso auch dann noch Koeffizientenschätzungen ungleich Null enthält, wenn die Koeffizienten selbst wirklich Null sind.