Ich frage mich, wie die Standardstartwerte in angegeben werden glm
.
Dieser Beitrag schlägt vor, dass Standardwerte als Nullen festgelegt werden. Das man sagt , dass es ein Algorithmus dahinter jedoch relevante Verbindung unterbrochen wird.
Ich habe versucht, ein einfaches logistisches Regressionsmodell mit einem Algorithmus-Trace zu versehen:
set.seed(123)
x <- rnorm(100)
p <- 1/(1 + exp(-x))
y <- rbinom(100, size = 1, prob = p)
# to see parameter estimates in each step
trace(glm.fit, quote(print(coefold)), at = list(c(22, 4, 8, 4, 19, 3)))
Erstens ohne Angabe von Anfangswerten:
glm(y ~ x, family = "binomial")
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
NULL
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.386379 1.106234
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.3991135 1.1653971
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.3995188 1.1669508
Im ersten Schritt sind Anfangswerte NULL
.
Zweitens setze ich Startwerte auf Nullen:
glm(y ~ x, family = "binomial", start = c(0, 0))
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0 0
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.3177530 0.9097521
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.3909975 1.1397163
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.3994147 1.1666173
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.3995191 1.1669518
Und wir können sehen, dass sich die Iterationen zwischen dem ersten und dem zweiten Ansatz unterscheiden.
Um die von angegebenen Werte zu sehen, habe glm
ich versucht, das Modell mit nur einer Iteration anzupassen:
glm(y ~ x, family = "binomial", control = list(maxit = 1))
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
NULL
Call: glm(formula = y ~ x, family = "binomial", control = list(maxit = 1))
Coefficients:
(Intercept) x
0.3864 1.1062
Degrees of Freedom: 99 Total (i.e. Null); 98 Residual
Null Deviance: 134.6
Residual Deviance: 115 AIC: 119
Schätzungen von Parametern entsprechen (nicht überraschend) Schätzungen des ersten Ansatzes in der zweiten Iteration, dh das [1] 0.386379 1.106234
Festlegen dieser Werte als Anfangswerte führt zu derselben Iterationssequenz wie im ersten Ansatz:
glm(y ~ x, family = "binomial", start = c(0.386379, 1.106234))
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.386379 1.106234
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.3991135 1.1653971
Tracing glm.fit(x = structure(c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, .... step 22,4,8,4,19,3
[1] 0.3995188 1.1669508
Die Frage ist also, wie diese Werte berechnet werden.
quelle
start
Werte angeben, werden diese zur Berechnung der Übergabe an dieC_Cdqrls
Routine verwendet. Wenn Sie dies nicht tun, werden die übergebenen Werte berechnet (einschließlich eines Aufrufseval(binomial()$initialize)
),glm.fit
berechnen jedoch niemals explizit Werte fürstart
. Nehmen Sie sich ein oder zwei Stunden Zeit und studieren Sie denglm.fit
Code.glm.fit
Code zu studieren , aber ich habe immer noch keine Ahnung, wie die Anfangswerte berechnet werden.Antworten:
TL; DR
start=c(b0,b1)
initialisiert eta aufb0+x*b1
(mu auf 1 / (1 + exp (-eta)))start=c(0,0)
initialisiert eta auf 0 (mu auf 0,5) unabhängig vom y- oder x-Wert.start=NULL
initialisiert eta = 1,098612 (mu = 0,75), wenn y = 1 ist, unabhängig vom x-Wert.start=NULL
initialisiert eta = -1,098612 (mu = 0,25), wenn y = 0 ist, unabhängig vom x-Wert.Sobald eta (und folglich mu und var (mu)) berechnet wurde
w
undz
im Geiste von berechnet und an einen QR-Löser gesendet wirdqr.solve(cbind(1,x) * w, z*w)
.Lange Form
Aufbauend auf Rolands Kommentar: Ich habe einen gemacht
glm.fit.truncated()
, wo ichglm.fit
denC_Cdqrls
Anruf angenommen und ihn dann auskommentiert habe.glm.fit.truncated
gibt diez
undw
-Werte (sowie die Werte der zur Berechnung vonz
und verwendeten Mengenw
) aus, die dann an denC_Cdqrls
Aufruf übergeben werden:Mehr dazu
C_Cdqrls
hier . Glücklicherweise greift die Funktionqr.solve
in Basis R direkt auf die LINPACK-Versionen zu, die in aufgerufen werdenglm.fit()
.Wir laufen also
glm.fit.truncated
für die verschiedenen Startwertspezifikationen und rufen dannqr.solve
mit den w- und z-Werten auf, und wir sehen, wie die "Startwerte" (oder die ersten angezeigten Iterationswerte) berechnet werden. Wie Roland angedeutet hat, wirkt sich die Angabe vonstart=NULL
oderstart=c(0,0)
in glm () auf die Berechnungen für w und z aus, nicht fürstart
.Für den Start = NULL:
z
ist ein Vektor, bei dem die Elemente den Wert 2.431946 oder -2.431946 haben, undw
ist ein Vektor, bei dem alle Elemente 0.4330127 sind:Für den Start = c (0,0):
z
ist ein Vektor, bei dem die Elemente den Wert 2 oder -2 haben, undw
ist ein Vektor, bei dem alle Elemente 0,5 sind:Das ist alles schön und gut, aber wie berechnen wir das
w
undz
? Nahe dem Boden sehenglm.fit.truncated()
wirSehen Sie sich die folgenden Vergleiche zwischen den ausgegebenen Werten der zur Berechnung verwendeten Mengen an
z
undw
:Es ist zu beachten, dass
start.is.00
der Vektormu
nur die Werte 0,5 hat, da eta auf 0 gesetzt ist und mu (eta) = 1 / (1 + exp (-0)) = 0,5.start.is.null
setzt diejenigen mit y = 1 auf mu = 0,75 (was eta = 1,098612 entspricht) und diejenigen mit y = 0 auf mu = 0,25 (was eta = -1,098612 entspricht) und damitvar_mu
= 0,75 * 0,25 = 0,1875.Es ist jedoch interessant festzustellen, dass ich den Samen geändert und alles neu interpretiert habe und mu = 0,75 für y = 1 und mu = 0,25 für y = 0 (und somit die anderen Mengen gleich geblieben sind). Das heißt, start = NULL führt zu demselben
w
undz
unabhängig davon, wasy
undx
sind, weil sie eta = 1,098612 (mu = 0,75) initialisieren, wenn y = 1 und eta = -1,098612 (mu = 0,25), wenn y = 0.Es scheint also, dass ein Startwert für den Intercept-Koeffizienten und für den X-Koeffizienten nicht für start = NULL festgelegt wird, sondern dass eta abhängig vom y-Wert und unabhängig vom x-Wert Anfangswerte erhalten. Von dort aus
w
undz
berechnet wird , dann zusammen mit geschicktx
an der qr.solver.Code, der vor den obigen Chunks ausgeführt werden soll:
quelle