R: функція glm із специфікацією сімейства = “бінома” та “вага”


14

Мене дуже плутає те, як вага працює в glm з сім'єю = "двочлен". У моєму розумінні ймовірність glm з family = "binomial" визначається так:

f(y)=(nny)pny(1−p)n(1−y)=exp⁡(n[ylog⁡p1−p−(−log⁡(1−p))]+log⁡(nny))
де y - "частка спостережуваного успіху", а n - відома кількість випробувань.

Наскільки я розумію, ймовірність успіху p параметризується деякими лінійними коефіцієнтами β як p=p(β) а функція glm із сім'єю = "двочлен" шукає:

argmaxβ∑ilog⁡f(yi).
Тоді цю проблему оптимізації можна спростити як:

argmaxβ∑ilog⁡f(yi)=argmaxβ∑ini[yilog⁡p(β)1−p(β)−(−log⁡(1−p(β)))]+log⁡(niniyi)=argmaxβ∑ini[yilog⁡p(β)1−p(β)−(−log⁡(1−p(β)))]

Тому якщо дозволити ni∗=nic для всіх i=1,...,N для деякої постійної c , то також повинно бути правдою, що:
argmaxβ∑ilog⁡f(yi)=argmaxβ∑ini∗[yilog⁡p(β)1−p(β)−(−log⁡(1−p(β)))]
З цього я подумав, що масштабування кількості випробувань niз постійною НЕ впливає на максимальну оцінку ймовірності β враховуючи частку успіху yi .

Файл довідки про glm говорить:

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

Тому я очікував, що масштабування ваги не вплине на оцінену β враховуючи частку успіху як відповіді. Однак наступні два коди повертають різні значення коефіцієнта:

 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 ), що і робить роботу в R: 1) у відхиленнях залишків за допомогою функції C binomial_dev_resids(у family.c ) та 2) на етапі IWLS Cdqrls(в lm.c ). Я не знаю достатньо С, щоб допомогти в пошуку логіки
— shadowtalker

3
Перегляньте відповіді тут .
— Стати

@ssdecontrol Я читаю glm.fit у посиланні, яке ви мені дали, але я не можу знайти, де функція C "binomial_dev_resids" називається в glm.fit. Не заперечуєте, якщо на це вказуєте?
— Фея

@ssdecontrol О, вибачте, я думаю, що я розумію. Кожна «сім'я» - це список, а одним із елементів є «dev.resids». Коли я набираю двочлен на консолі R, я бачу визначення біноміального об'єкта, і він має рядок: dev.resids <- функція (y, mu, wt) .Call (C_binomial_dev_resids, y, mu, wt)
— FairyOnIce

Відповіді:


4

Ваш приклад просто спричиняє помилку округлення в Р. Великі ваги погано спрацьовують glm. Це правда, що масштабування wпрактично будь-якої меншої кількості, як-от 100, призводить до тих же оцінок, що і для невизначених w.

Якщо ви хочете більш надійної поведінки з аргументами ваг, спробуйте використовувати 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-розкладання де - матриця проектування, а - діагональ з квадратними коренями записів, як описано тут . Тобто використовується метод Ньютона-Рафсона.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"

Ми можемо повторити останню частину ще два рази, щоб побачити, що метод Ньютона-Рафсона розходиться:

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

Я думаю, що ваги впливають більше, ніж аргументи для ініціалізації. За допомогою логістичної регресії Ньютон Рафсон оцінює максимальну ймовірність, яка існує і є унікальною, коли дані не розділені. Поставлення оптимізатора різних вихідних значень не призведе до різних значень, але, можливо, знадобиться більше часу, щоб дістатися до нього.
— AdamO

Msgstr "Поставлення оптимізатора різних вихідних значень не досягне різних значень ..." . Ну метод Ньютона не розходиться і знаходить унікальний максимум в останньому прикладі, де я встановлюю початкові значення (див. Приклад, де я надаю mustart аргумент). Здається, це питання, пов'язане з поганою початковою оцінкою .
— Бенджамін Кристофферсен
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.