R: glm-Funktion mit Angabe von family = "binomial" und "weight"

13

Ich bin sehr verwirrt darüber, wie Gewicht in glm mit family = "binomial" funktioniert. Nach meinem Verständnis wird die Wahrscheinlichkeit des glm mit family = "binomial" wie folgt angegeben: wobeiyder "Anteil des beobachteten Erfolgs" ist undndie bekannte Anzahl von Versuchen ist.

f(y)=(nny)pny(1-p)n(1-y)=exp(n[yLogp1-p-(-Log(1-p))]+Log(nny))
yn

Nach meinem Verständnis wird die Erfolgswahrscheinlichkeit mit einigen linearen Koeffizienten β wie folgt parametrisiert: p = p ( β ) und glm-Funktion mit family = "binomial" suche nach: arg max β i log f ( y i ) . Dann kann dieses Optimierungsproblem vereinfacht werden als:pβp=p(β)

argmaxβichLogf(yich).

argmaxβichLogf(yich)=argmaxβichnich[yichLogp(β)1-p(β)-(-Log(1-p(β)))]+Log(nichnichyich)=argmaxβichnich[yichLogp(β)1-p(β)-(-Log(1-p(β)))]

Deshalb , wenn wir lassen für alle i = 1 , . . . , N für eine Konstante c , dann muss es auch wahr sein, dass: arg max β i log f ( y i ) = arg max β i n i [ y i log p ( β )nich=nichcich=1,...,Nc
argmaxβichLogf(yich)=argmaxβichnich[yichLogp(β)1-p(β)-(-Log(1-p(β)))]
Aus diesem Grundnichβyich dachte ich, dass die Skalierung der Anzahl von Versuchen n i mit einer Konstanten die Schätzungen der maximalen Wahrscheinlichkeit von β bei gegebenem Erfolgsanteil y i NICHT beeinflusst .

Die Hilfedatei von glm sagt:

 "For a binomial GLM prior weights are used to give the number of trials 
  when the response is the proportion of successes" 

Daher erwartete ich, dass die Skalierung des Gewichts das geschätzte angesichts des Erfolgsanteils als Antwort nicht beeinflussen würde . Die folgenden beiden Codes geben jedoch unterschiedliche Koeffizientenwerte zurück:β

 Y <- c(1,0,0,0) ## proportion of observed success
 w <- 1:length(Y) ## weight= the number of trials
 glm(Y~1,weights=w,family=binomial)

Dies ergibt:

 Call:  glm(formula = Y ~ 1, family = "binomial", weights = w)

 Coefficients:
 (Intercept)  
      -2.197     

Wenn ich alle Gewichte mit 1000 multipliziere, sind die geschätzten Koeffizienten unterschiedlich:

 glm(Y~1,weights=w*1000,family=binomial)

 Call:  glm(formula = Y ~ 1, family = binomial, weights = w * 1000)

 Coefficients:
 (Intercept)  
    -3.153e+15  

Ich habe viele andere Beispiele wie dieses gesehen, auch wenn die Gewichte mäßig skaliert waren. Was geht hier vor sich?

FairyOnIce
quelle
3
Für das, was es wert ist, weightsendet das Argument an zwei Stellen innerhalb der glm.fitFunktion (in glm.R ), was die Arbeit in R: 1) in den Abweichungsrestwerten über die C-Funktion binomial_dev_resids(in family.c ) ist. und 2) im IWLS-Schritt mit Cdqrls(in lm.c ). Ich kenne nicht genug C, um die Logik
besser nachvollziehen zu
3
Überprüfen Sie die Antworten hier .
Stat
@ssdecontrol Ich lese in glm.fit in dem Link, den Sie mir gegeben haben, aber ich kann nicht finden, wo die C-Funktion "binomial_dev_resids" in glm.fit aufgerufen wird. Würde es Ihnen etwas ausmachen, wenn Sie darauf hinweisen?
FairyOnIce
@ssdecontrol Oh, tut mir leid, ich glaube ich verstehe. Jede "Familie" ist eine Liste und eines der Elemente ist "dev.resids". Wenn ich binomial in R console eingebe, sehe ich die Definition des binomialen Objekts und es hat eine Zeile: dev.resids <- function (y, mu, wt) .Call (C_binomial_dev_resids, y, mu, wt)
FairyOnIce

Antworten:

3

Ihr Beispiel verursacht lediglich einen Rundungsfehler in R. Große Gewichte funktionieren in nicht gut glm. Es stimmt, dass eine Skalierung wmit praktisch jeder kleineren Zahl, wie beispielsweise 100, zu denselben Schätzungen führt wie die nicht skalierte w.

Wenn Sie ein zuverlässigeres Verhalten mit den weight-Argumenten wünschen, verwenden Sie die svyglmFunktion aus dem surveyPaket.

Siehe hier:

    > svyglm(Y~1, design=svydesign(ids=~1, weights=~w, data=data.frame(w=w*1000, Y=Y)), family=binomial)
Independent Sampling design (with replacement)
svydesign(ids = ~1, weights = ~w, data = data.frame(w = w * 1000, 
    Y = Y))

Call:  svyglm(formula = Y ~ 1, design = svydesign(ids = ~1, weights = ~w2, 
    data = data.frame(w2 = w * 1000, Y = Y)), family = binomial)

Coefficients:
(Intercept)  
     -2.197  

Degrees of Freedom: 3 Total (i.e. Null);  3 Residual
Null Deviance:      2.601 
Residual Deviance: 2.601    AIC: 2.843
AdamO
quelle
1

glm.fitfamily$initializeglm.fitWXXW

Der relevante $intializeCode lautet:

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!")
}

Hier ist eine vereinfachte Version, glm.fitdie meinen Standpunkt zeigt

> #####
> # 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"

Wir können den letzten Teil noch zweimal wiederholen, um festzustellen, dass die Newton-Raphson-Methode divergiert:

> #####
> # 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

Dies passiert nicht, wenn Sie mit weights <- 1:nrow(y)oder sagen weights <- 1:nrow(y) * 100.

Beachten Sie, dass Sie Abweichungen vermeiden können, indem Sie das mustartArgument setzen. ZB tun

> 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
Benjamin Christoffersen
quelle
Ich denke, dass Gewichte mehr als nur Argumente zur Initialisierung beeinflussen. Mit der logistischen Regression schätzt Newton Raphson die maximale Wahrscheinlichkeit, die vorhanden und eindeutig ist, wenn die Daten nicht getrennt werden. Wenn Sie dem Optimierer unterschiedliche Startwerte bereitstellen, werden keine unterschiedlichen Werte erreicht, aber es dauert möglicherweise länger, bis Sie dort ankommen.
AdamO
Msgstr "Unterschiedliche Startwerte an den Optimierer liefern, führt nicht zu unterschiedlichen Werten ..." . Nun, die Newton-Methode weicht nicht voneinander ab und findet das eindeutige Maximum im letzten Beispiel, in dem ich die Anfangswerte festgelegt habe (siehe das Beispiel, in dem ich das mustart Argument gebe). Es scheint eine Sache zu sein, die mit einer schlechten anfänglichen Schätzung zusammenhängt .
Benjamin Christoffersen