Je me demande comment les valeurs de départ par défaut sont spécifiées dans glm
.
Ce message suggère que les valeurs par défaut sont définies comme des zéros. Celui- ci dit qu'il y a un algorithme derrière, cependant le lien pertinent est rompu.
J'ai essayé d'adapter un modèle de régression logistique simple avec une trace d'algorithme:
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)))
Tout d'abord, sans spécification des valeurs initiales:
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
Dans la première étape, les valeurs initiales sont NULL
.
Deuxièmement, j'ai défini des valeurs de départ comme des zéros:
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
Et nous pouvons voir que les itérations entre la première et la seconde approche diffèrent.
Pour voir les valeurs initiales spécifiées par glm
J'ai essayé d'ajuster le modèle avec une seule itération:
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
Les estimations des paramètres (sans surprise) correspondent aux estimations de la première approche dans la deuxième itération, c'est-à-dire que la [1] 0.386379 1.106234
définition de ces valeurs comme valeurs initiales conduit à la même séquence d'itérations que dans la première approche:
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
La question est donc de savoir comment ces valeurs sont calculées?
la source
start
valeurs, elles sont utilisées dans le calcul de ce qui est transmis à laC_Cdqrls
routine. Si vous ne le faites pas, les valeurs transmises sont calculées (y compris un appeleval(binomial()$initialize)
), maisglm.fit
ne calculent jamais explicitement les valeurs destart
. Prenez une heure ou deux et étudiez leglm.fit
code.glm.fit
code mais je n'ai toujours aucune idée de la façon dont les valeurs initiales sont calculées.Réponses:
TL; DR
start=c(b0,b1)
initialise eta àb0+x*b1
(mu à 1 / (1 + exp (-eta)))start=c(0,0)
initialise eta à 0 (mu à 0,5) quelle que soit la valeur y ou x.start=NULL
initialise eta = 1,098612 (mu = 0,75) si y = 1, quelle que soit la valeur x.start=NULL
initialise eta = -1,098612 (mu = 0,25) si y = 0, quelle que soit la valeur x.Une fois que eta (et par conséquent mu et var (mu)) a été calculé,
w
etz
est calculé et envoyé à un solveur QR, dans l'esprit deqr.solve(cbind(1,x) * w, z*w)
.Forme longue
S'appuyant sur le commentaire de Roland: J'ai fait un
glm.fit.truncated()
, où j'ai prisglm.fit
l'C_Cdqrls
appel, puis je l'ai commenté.glm.fit.truncated
renvoie les valeursz
etw
(ainsi que les valeurs des quantités utilisées pour calculerz
etw
) qui seraient ensuite transmises à l'C_Cdqrls
appel:Pour en savoir plus,
C_Cdqrls
cliquez ici . Heureusement, la fonctionqr.solve
de base R puise directement dans les versions de LINPACK sollicitées dansglm.fit()
.Nous courons donc
glm.fit.truncated
pour les différentes spécifications de valeur de départ, puis faisons un appel àqr.solve
avec les valeurs w et z, et nous voyons comment les "valeurs de départ" (ou les premières valeurs d'itération affichées) sont calculées. Comme Roland l'a indiqué, spécifierstart=NULL
oustart=c(0,0)
dans glm () affecte les calculs pour w et z, pas pourstart
.Pour le début = NULL:
z
est un vecteur où les éléments ont la valeur 2,431946 ou -2,431946 etw
est un vecteur où tous les éléments sont 0,4330127:Pour le début = c (0,0):
z
est un vecteur où les éléments ont la valeur 2 ou -2 etw
est un vecteur où tous les éléments sont 0,5:C'est bien beau, mais comment calculer le
w
etz
? Près du bas deglm.fit.truncated()
nous voyonsRegardez les comparaisons suivantes entre les valeurs produites des quantités utilisées pour calculer
z
etw
:Notez que
start.is.00
le vecteurmu
n'aura que les valeurs 0,5, car eta est défini sur 0 et mu (eta) = 1 / (1 + exp (-0)) = 0,5.start.is.null
définit ceux avec y = 1 à mu = 0,75 (ce qui correspond à eta = 1,098612) et ceux avec y = 0 à mu = 0,25 (ce qui correspond à eta = -1,098612), et donc levar_mu
= 0,75 * 0,25 = 0,1875.Cependant, il est intéressant de noter que j'ai tout changé et réanimé et le mu = 0,75 pour y = 1 et mu = 0,25 pour y = 0 (et donc les autres quantités sont restées les mêmes). C'est-à-dire que start = NULL donne la même chose
w
etz
indépendamment de cey
quex
sont et parce qu'ils initialisent eta = 1.098612 (mu = 0.75) si y = 1 et eta = -1.098612 (mu = 0.25) si y = 0.Il apparaît donc qu'une valeur de départ pour le coefficient d'interception et pour le coefficient X n'est pas définie pour start = NULL, mais plutôt des valeurs initiales sont données à eta en fonction de la valeur y et indépendamment de la valeur x. De là
w
etz
sont calculés, puis envoyés avecx
le qr.solver.Code à exécuter avant les morceaux ci-dessus:
la source