Ich versuche, ein multivariates lineares Regressionsmodell mit ungefähr 60 Prädiktorvariablen und 30 Beobachtungen anzupassen , daher verwende ich das glmnet- Paket für die regulierte Regression, da p> n.
Ich habe Dokumentationen und andere Fragen durchgearbeitet, kann die Ergebnisse aber immer noch nicht interpretieren. Hier ist ein Beispielcode (mit 20 Prädiktoren und 10 Beobachtungen zur Vereinfachung):
Ich erstelle eine Matrix x mit num rows = num observations und num cols = num predictors und einem Vektor y, der die Antwortvariable darstellt
> x=matrix(rnorm(10*20),10,20)
> y=rnorm(10)
Ich passe ein Glmnet-Modell an und lasse Alpha als Standard (= 1 für Lasso-Strafe)
> fit1=glmnet(x,y)
> print(fit1)
Ich verstehe, dass ich mit abnehmenden Lambda-Werten (dh Strafe) unterschiedliche Vorhersagen erhalte.
Call: glmnet(x = x, y = y)
Df %Dev Lambda
[1,] 0 0.00000 0.890700
[2,] 1 0.06159 0.850200
[3,] 1 0.11770 0.811500
[4,] 1 0.16880 0.774600
.
.
.
[96,] 10 0.99740 0.010730
[97,] 10 0.99760 0.010240
[98,] 10 0.99780 0.009775
[99,] 10 0.99800 0.009331
[100,] 10 0.99820 0.008907
Jetzt sage ich meine Beta-Werte voraus und wähle zum Beispiel den kleinsten Lambda-Wert aus glmnet
> predict(fit1,type="coef", s = 0.008907)
21 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -0.08872364
V1 0.23734885
V2 -0.35472137
V3 -0.08088463
V4 .
V5 .
V6 .
V7 0.31127123
V8 .
V9 .
V10 .
V11 0.10636867
V12 .
V13 -0.20328200
V14 -0.77717745
V15 .
V16 -0.25924281
V17 .
V18 .
V19 -0.57989929
V20 -0.22522859
Wenn ich stattdessen Lambda mit wähle
cv <- cv.glmnet(x,y)
model=glmnet(x,y,lambda=cv$lambda.min)
Alle Variablen wären (.).
Zweifel und Fragen:
- Ich bin mir nicht sicher, wie ich Lambda wählen soll.
- Sollte ich die nicht (.) Variablen verwenden, um ein anderes Modell anzupassen? In meinem Fall möchte ich so viele Variablen wie möglich behalten.
- Woher kenne ich den p-Wert, dh welche Variablen sagen die Reaktion signifikant voraus?
Ich entschuldige mich für meine schlechten statistischen Kenntnisse! Und danke für jede Hilfe.
quelle
Antworten:
Hier ist eine nicht intuitive Tatsache - Sie sollten glmnet eigentlich keinen einzigen Wert von Lambda geben. Aus der Dokumentation hier :
cv.glmnet
wird Ihnen helfen, Lambda zu wählen, wie Sie in Ihren Beispielen angedeutet haben. Die Autoren des glmnet-Pakets schlagencv$lambda.1se
vorcv$lambda.min
, aber in der Praxis hatte ich Erfolg mit letzterem.Nachdem Sie cv.glmnet ausgeführt haben, müssen Sie glmnet nicht erneut ausführen! Jedes Lambda in der Tabelle (
cv$lambda
) wurde bereits ausgeführt. Diese Technik wird als „Warmstart“ bezeichnet und Sie können mehr darüber lesen Sie hier . Ausgehend von der Einführung reduziert die Warmstart-Technik die Laufzeit iterativer Methoden, indem die Lösung eines anderen Optimierungsproblems (z. B. glmnet mit einem größeren Lambda) als Startwert für ein späteres Optimierungsproblem (z. B. glmnet mit einem kleineren Lambda) verwendet wird ).cv.glmnet.fit
Versuchen Sie Folgendes, um den gewünschten Lauf zu extrahieren :Revision (28.01.2017)
Keine Notwendigkeit, sich an das glmnet-Objekt zu hacken, wie ich es oben getan habe; nehmen @ alex23lemm Rat unten und übergeben Sie die
s = "lambda.min"
,s = "lambda.1se"
oder eine andere Nummer (zBs = .007
) auf beidecoef
undpredict
. Beachten Sie, dass Ihre Koeffizienten und Vorhersagen von diesem Wert abhängen, der durch Kreuzvalidierung festgelegt wird. Verwenden Sie einen Samen für die Reproduzierbarkeit! Und vergessen Sie nicht, dass Sie die Standardeinstellung von verwenden , wenn Sie kein"s"
incoef
undpredict
angebens = "lambda.1se"
. Ich habe mich auf diese Standardeinstellung erwärmt, nachdem ich festgestellt habe, dass sie in einer Situation mit kleinen Datenmengen besser funktioniert.s = "lambda.1se"
Wenn Sie also mit Alpha> 0 arbeiten, tendieren Sie auch zu einem sparsameren Modell. Sie können auch einen numerischen Wert von s mit Hilfe von plot.glmnet auswählen, um irgendwo dazwischen zu gelangen (vergessen Sie nur nicht, die Werte von der x-Achse aus zu potenzieren!).quelle
small.lambda.betas <- coef(cv, s = "lambda.min")
Q1) Ich bin mir nicht sicher, wie ich Lambda wählen soll. F2) Soll ich die Nicht-Variablen (.) Verwenden, um ein anderes Modell anzupassen? In meinem Fall möchte ich so viele Variablen wie möglich behalten.
Gemäß der großartigen Antwort von @ BenOgorek lässt man die Anpassung normalerweise eine ganze Lambda-Sequenz verwenden, und verwendet dann beim Extrahieren der optimalen Koeffizienten den Lambda.1se-Wert (im Gegensatz zu dem, was Sie getan haben).
Solange Sie die folgenden drei Punkte einhalten, sollten Sie weder gegen die Regularisierung kämpfen noch das Modell optimieren: Wenn eine Variable weggelassen wurde, lag dies daran, dass die Gesamtstrafe geringer ausfiel. Die Vorsichtsmaßnahmen sind:
Damit die regulierten Coeffts sinnvoll sind, müssen Sie zuvor den Mittelwert und die Standardabweichung der Variablen explizit mit normalisieren
scale()
. Verlasse dich nicht aufglmnet(standardize=T)
. Zur Begründung siehe Ist eine Normung vor Lasso wirklich notwendig? ; Grundsätzlich kann eine Variable mit großen Werten bei der Regularisierung ungerechtfertigt bestraft werden.Um reproduzierbar zu sein, laufen Sie mit
set.seed
mehreren Zufallskeimen und überprüfen Sie die regulierten Koeffizienten auf Stabilität.Wenn Sie eine weniger harte Regularisierung wünschen, dh mehr Variablen enthalten, verwenden Sie Alpha <1 (dh das richtige elastische Netz) anstelle eines einfachen Kamms. Ich schlage vor , Sie Alpha von 0 auf 1 fegen Wenn Sie das tun werden, dann Überanpassung des Hyper alpha und die Regressionsfehler zu vermeiden, Sie verwenden müssen , Kreuzvalidierung, dh verwenden ,
cv.glmnet()
anstatt einfachglmnet()
:.
Wenn Sie eine solche Gittersuche mit CV automatisieren möchten, können Sie sie entweder selbst codieren oder das Caret-Paket über glmnet verwenden. Caret macht das gut. Zum
cv.glmnet nfolds
Parameterwert 3 (Minimum), wenn Ihr Datensatz klein ist, oder 5 oder 10, wenn er groß ist.F3) Woher kenne ich den p-Wert, dh welche Variablen sagen die Reaktion signifikant voraus?
Tun Sie nicht, sie sind nicht sinnvoll . Wie ausführlich in Warum ist es nicht ratsam, statistische Zusammenfassungsinformationen für Regressionskoeffizienten aus dem GLMNET-Modell abzurufen?
Lassen Sie
cv.glmnet()
einfach die Variablenauswahl automatisch machen. Mit den oben genannten Einschränkungen. Und natürlich sollte die Verteilung der Antwortvariablen normal sein (vorausgesetzt, Sie verwendenfamily='gaussian'
).quelle