ฉันคิดว่ามันจะลงมาให้ค่าเริ่มต้นที่จะใช้ในการglm.fit
จากfamily$initialize
ซึ่งจะทำให้วิธีการ divergere เท่าที่ผมรู้ว่าglm.fit
การแก้ปัญหาโดยการสร้าง QR-การสลายตัวของที่เป็นเมทริกซ์ออกแบบและเป็นเส้นทแยงมุมกับรากที่สองของรายการตามที่อธิบายไว้ที่นี่ นั่นคือใช้วิธีการของ Newton-RaphsonX √W−−√XXW−−√
$intialize
รหัสที่เกี่ยวข้องคือ:
if (NCOL(y) == 1) {
if (is.factor(y))
y <- y != levels(y)[1L]
n <- rep.int(1, nobs)
y[weights == 0] <- 0
if (any(y < 0 | y > 1))
stop("y values must be 0 <= y <= 1")
mustart <- (weights * y + 0.5)/(weights + 1)
m <- weights * y
if (any(abs(m - round(m)) > 0.001))
warning("non-integer #successes in a binomial glm!")
}
นี่เป็นเวอร์ชั่นที่เรียบง่ายglm.fit
ซึ่งแสดงจุดของฉัน
> #####
> # setup
> y <- matrix(c(1,0,0,0), ncol = 1)
> weights <- 1:nrow(y) * 1000
> nobs <- length(y)
> family <- binomial()
> X <- matrix(rep(1, nobs), ncol = 1) # design matrix used later
>
> # set mu start as with family$initialize
> if (NCOL(y) == 1) {
+ n <- rep.int(1, nobs)
+ y[weights == 0] <- 0
+ mustart <- (weights * y + 0.5)/(weights + 1)
+ m <- weights * y
+ if (any(abs(m - round(m)) > 0.001))
+ warning("non-integer #successes in a binomial glm!")
+ }
>
> mustart # starting value
[,1]
[1,] 0.9995004995
[2,] 0.0002498751
[3,] 0.0001666111
[4,] 0.0001249688
> (eta <- family$linkfun(mustart))
[,1]
[1,] 7.601402
[2,] -8.294300
[3,] -8.699681
[4,] -8.987322
>
> #####
> # Start loop to fit
> mu <- family$linkinv(eta)
> mu_eta <- family$mu.eta(eta)
> z <- drop(eta + (y - mu) / mu_eta)
> w <- drop(sqrt(weights * mu_eta^2 / family$variance(mu = mu)))
>
> # code is simpler here as (X^T W X) is a scalar
> X_w <- X * w
> (.coef <- drop(crossprod(X_w)^-1 * ((w * z) %*% X_w)))
[1] -5.098297
> (eta <- .coef * X)
[,1]
[1,] -5.098297
[2,] -5.098297
[3,] -5.098297
[4,] -5.098297
>
> # repeat a few times from "start loop to fit"
เราสามารถทำซ้ำส่วนสุดท้ายอีกสองครั้งเพื่อดูวิธีการของ Newton-Raphson diverges:
> #####
> # Start loop to fit
> mu <- family$linkinv(eta)
> mu_eta <- family$mu.eta(eta)
> z <- drop(eta + (y - mu) / mu_eta)
> w <- drop(sqrt(weights * mu_eta^2 / family$variance(mu = mu)))
>
> # code is simpler here as (X^T W X) is a scalar
> X_w <- X * w
> (.coef <- drop(crossprod(X_w)^-1 * ((w * z) %*% X_w)))
[1] 10.47049
> (eta <- .coef * X)
[,1]
[1,] 10.47049
[2,] 10.47049
[3,] 10.47049
[4,] 10.47049
>
>
> #####
> # Start loop to fit
> mu <- family$linkinv(eta)
> mu_eta <- family$mu.eta(eta)
> z <- drop(eta + (y - mu) / mu_eta)
> w <- drop(sqrt(weights * mu_eta^2 / family$variance(mu = mu)))
>
> # code is simpler here as (X^T W X) is a scalar
> X_w <- X * w
> (.coef <- drop(crossprod(X_w)^-1 * ((w * z) %*% X_w)))
[1] -31723.76
> (eta <- .coef * X)
[,1]
[1,] -31723.76
[2,] -31723.76
[3,] -31723.76
[4,] -31723.76
นี้จะไม่เกิดขึ้นถ้าคุณเริ่มต้นด้วยหรือพูดweights <- 1:nrow(y)
weights <- 1:nrow(y) * 100
โปรดสังเกตว่าคุณสามารถหลีกเลี่ยงความแตกต่างได้โดยการตั้งค่าmustart
อาร์กิวเมนต์ เช่นทำ
> glm(Y ~ 1,weights = w * 1000, family = binomial, mustart = rep(0.5, 4))
Call: glm(formula = Y ~ 1, family = binomial, weights = w * 1000, mustart = rep(0.5,
4))
Coefficients:
(Intercept)
-2.197
Degrees of Freedom: 3 Total (i.e. Null); 3 Residual
Null Deviance: 6502
Residual Deviance: 6502 AIC: 6504
weights
อาร์กิวเมนต์จะสิ้นสุดในสองตำแหน่งภายในglm.fit
ฟังก์ชัน (ในglm.R ) ซึ่งเป็นสิ่งที่ทำงานใน R: 1) ในส่วนเบี่ยงเบนเบี่ยงเบนโดยใช้ฟังก์ชัน Cbinomial_dev_resids
(ในตระกูล.c ) และ 2) ใน IWLS ทีละขั้นตอนCdqrls
(ในlm.c ) ฉันไม่รู้ C มากพอที่จะช่วยในการติดตามตรรกะมากขึ้น