R : 패밀리 = "이항"및 "무게"사양의 glm 기능


14

family = "binomial"과 함께 glm에서 무게가 어떻게 작동하는지 매우 혼동됩니다. 내 이해에 따르면 family = "binomial"인 glm의 가능성은 다음과 같이 지정됩니다.

f(y)=(nny)pny(1p)n(1y)=exp(n[ylogp1p(log(1p))]+log(nny))
여기서 y 는 "관측 성공률"이고 n 은 알려진 횟수입니다.

내 이해에 따르면 성공 확률 pp = p (\ beta) 와 같은 선형 계수 \ beta 와 family = "binomial"로 glm 함수를 사용하여 매개 변수화됩니다 : \ textrm {arg} \ max _ {\ beta} \ sum_i \ log f (y_i). 그런 다음이 최적화 문제를 다음과 같이 단순화 할 수 있습니다.βp=p(β)

argmaxβilogf(yi).

argmaxβilogf(yi)=argmaxβini[yilogp(β)1p(β)(log(1p(β)))]+log(niniyi)=argmaxβini[yilogp(β)1p(β)(log(1p(β)))]

따라서 우리 해주면 ni=nic 모든 i=1,...,N 어떤 정수에 대해 c , 그것은 또한 충족되어야한다 :
argmaxβilogf(yi)=argmaxβini[yilogp(β)1p(β)(log(1p(β)))]
으로부터, 시행 횟수의 스케일링 ni상수 y 는 성공률 y_i 의 비율을 고려할 때 \ beta 의 최대 우도 추정에는 영향을 미치지 않습니다βyi .

glm의 도움말 파일은 다음과 같이 말합니다.

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

따라서 무게의 스케일링은 반응의 성공 비율을 감안할 때 추정 된 \ beta에 영향을 미치지 않을 것으로 예상했습니다 β. 그러나 다음 두 코드는 다른 계수 값을 반환합니다.

 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)

결과는 다음과 같습니다.

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

 Coefficients:
 (Intercept)  
      -2.197     

모든 가중치에 1000을 곱하면 추정 계수가 다릅니다.

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

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

 Coefficients:
 (Intercept)  
    -3.153e+15  

나는 약간의 무게 스케일로도 이와 같은 다른 많은 예를 보았습니다. 무슨 일이야?


3
무엇의 가치를 들면, weights인수는 내부에 두 곳에서 끝나는 glm.fit기능 (에서 glm.R C 함수의 방법으로는 일탈 잔류 1) : R의 작업을 수행합니다 것입니다), binomial_dev_resids에 ( family.c ) 및 2) IWLS 단계 Cdqrls에서 ( lm.c로 ). 나는 논리 추적에 더 많은 도움을 줄 수있는 충분한 C를 모른다
shadowtalker

3
여기 에서 답장을 확인 하십시오 .
Stat

@ssdecontrol 나는 당신이 나에게 준 링크에서 glm.fit을 읽고 있지만 glm.fit에서 C 함수 "binomial_dev_resids"가 어디에서 호출되는지 찾을 수 없습니다. 지적 해 주시겠습니까?
FairyOnIce

@ ssdecontrol 아, 죄송합니다 이해합니다. 각 "family"는 목록이고 요소 중 하나는 "dev.resids"입니다. I는 R 콘솔 이항 입력하면, I는 이항 오브젝트의 정의를 참조하며 선을 가지고 dev.resids <- 함수 (Y, MU, 중량) .Call (C_binomial_dev_resids, Y, 뮤 중량)
FairyOnIce

답변:


4

귀하의 예는 단순히 R에서 반올림 오류를 발생시킵니다. 큰 가중치는에서 잘 수행되지 않습니다 glm. w100과 같이 사실상 더 작은 수로 스케일링 하면 unscaled와 동일한 추정치가 발생합니다 w.

weights 인수로보다 안정적인 동작을 원하면 패키지 에서 svyglm함수를 사용해보십시오 survey.

여길 봐:

    > 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

1

나는에서 사용되는 초기 값으로 내려 오는 생각 glm.fit으로부터 family$initialize메소드 divergere을 만든다. 내가 아는 한,glm.fit 의 QR 분해를 형성하여 문제를 해결하십시오. 여기서 는 설계 행렬이고 는 여기에 설명 된대로 항목의 제곱근이있는 대각선입니다 . 즉, Newton-Raphson 방법을 사용합니다.WXXW

관련 $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 방법이 분기되는 것을 확인하기 위해 마지막 부분을 두 번 더 반복 할 수 있습니다.

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

나는 가중치가 초기화하는 인수 이상에 영향을 미친다고 생각합니다. 로지스틱 회귀 분석을 통해 Newton Raphson은 데이터가 분리되지 않은 경우 존재하고 고유 한 최대 가능성을 추정합니다. 옵티 마이저에 다른 시작 값을 제공하면 다른 값에 도달하지 않지만 도달하는 데 시간이 더 오래 걸립니다.
AdamO

"최적화기에 다른 시작 값을 제공하면 다른 값에 도달하지 않습니다 ..." . 글쎄요, 뉴턴 방법은 초기 값을 설정 한 마지막 예에서 발산하지 않고 고유 한 최대 값을 찾습니다 ( mustart 인수를 제공하는 예 참조 ). 초기 추정좋지 않은 문제인 것 같습니다 .
Benjamin Christoffersen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.