Me pregunto cómo se especifican los valores iniciales predeterminados glm
.
Esta publicación sugiere que los valores predeterminados se establecen como ceros. Esto se dice que hay un algoritmo detrás de él, sin embargo enlace correspondiente se rompe.
Traté de ajustar el modelo de regresión logística simple con rastreo de algoritmo:
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)))
Primero, sin especificación de valores iniciales:
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
En el primer paso, los valores iniciales son NULL
.
En segundo lugar, configuro los valores iniciales como ceros:
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
Y podemos ver que las iteraciones entre el primer y el segundo enfoque difieren.
Para ver los valores iniciales especificados por glm
Traté de ajustar el modelo con solo una iteración:
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
Las estimaciones de los parámetros (no es sorprendente) corresponden a las estimaciones del primer enfoque en la segunda iteración, es decir, [1] 0.386379 1.106234
establecer estos valores como valores iniciales conduce a la misma secuencia de iteraciones que en el primer enfoque:
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
Entonces la pregunta es, ¿cómo se calculan estos valores?
fuente
start
valores, se utilizan en el cálculo de lo que se pasa a laC_Cdqrls
rutina. Si no lo hace, los valores que se pasan se calculan (incluida una llamadaeval(binomial()$initialize)
), peroglm.fit
nunca calcula explícitamente los valores parastart
. Tómate una o dos horas y estudia elglm.fit
código.glm.fit
código pero todavía no tengo idea de cómo se calculan los valores iniciales.Respuestas:
TL; DR
start=c(b0,b1)
inicializa eta ab0+x*b1
(mu a 1 / (1 + exp (-eta)))start=c(0,0)
inicializa eta a 0 (mu a 0.5) independientemente del valor de y o x.start=NULL
inicializa eta = 1.098612 (mu = 0.75) si y = 1, independientemente del valor de x.start=NULL
inicializa eta = -1.098612 (mu = 0.25) si y = 0, independientemente del valor de x.Una vez eta (y por consiguiente mu y var (mu)) se ha calculado,
w
yz
se calculan y se envía a un solucionador de QR, en el espíritu deqr.solve(cbind(1,x) * w, z*w)
.Forma larga
A partir del comentario de Roland: hice un
glm.fit.truncated()
, dondeglm.fit
atendí laC_Cdqrls
llamada y luego lo comenté.glm.fit.truncated
genera los valoresz
yw
(así como los valores de las cantidades utilizadas para calcularz
yw
) que luego se pasarían a laC_Cdqrls
llamada:Más se puede leer sobre
C_Cdqrls
aquí . Afortunadamente, la funciónqr.solve
en la base R aprovecha directamente las versiones de LINPACK que se invocan englm.fit()
.Así que corremos
glm.fit.truncated
para las diferentes especificaciones de valores iniciales, y luego hacemos una llamada aqr.solve
los valores w y z, y vemos cómo se calculan los "valores iniciales" (o los primeros valores de iteración mostrados). Como indicó Roland, especificarstart=NULL
ostart=c(0,0)
en glm () afecta los cálculos para w y z, no parastart
.Para el inicio = NULL:
z
es un vector donde los elementos tienen el valor 2.431946 o -2.431946 yw
es un vector donde todos los elementos son 0.4330127:Para el inicio = c (0,0):
z
es un vector donde los elementos tienen el valor 2 o -2 yw
es un vector donde todos los elementos son 0.5:Eso está muy bien, pero ¿cómo calculamos el
w
yz
? Cerca del fondo deglm.fit.truncated()
vemosObserve las siguientes comparaciones entre los valores de salida de las cantidades utilizadas para calcular
z
yw
:Tenga en cuenta que
start.is.00
tendrá un vectormu
con solo los valores 0.5 porque eta se establece en 0 y mu (eta) = 1 / (1 + exp (-0)) = 0.5.start.is.null
establece que aquellos con y = 1 sean mu = 0.75 (que corresponde a eta = 1.098612) y aquellos con y = 0 sean mu = 0.25 (que corresponde a eta = -1.098612), y por lo tantovar_mu
= 0.75 * 0.25 = 0.1875.Sin embargo, es interesante notar que cambié la semilla y volví a clasificar todo y mu = 0.75 para y = 1 y mu = 0.25 para y = 0 (y, por lo tanto, las otras cantidades permanecieron iguales). Es decir, start = NULL da lugar a la misma
w
yz
con independencia de lo quey
yx
son, porque se inicializan eta = 1.098612 (mu = 0,75), si y = 1 y eta = -1.098612 (mu = 0,25) si y = 0.Por lo tanto, parece que un valor inicial para el coeficiente de intercepción y para el coeficiente X no se establece para start = NULL, sino que se dan valores iniciales a eta dependiendo del valor y e independientemente del valor x. A partir de ahí
w
yz
se calculan, luego se envían junto conx
el qr.solver.Código para ejecutar antes de los fragmentos anteriores:
fuente