R: ฟังก์ชั่น glm พร้อมตระกูล = ข้อมูลจำเพาะ "ทวินาม" และ "น้ำหนัก"


14

ฉันสับสนมากกับการทำงานของน้ำหนักใน glm กับครอบครัว = "ทวินาม" ในความเข้าใจของฉันความเป็นไปได้ของ glm กับครอบครัว = "ทวินาม" ระบุไว้ดังนี้:

f(y)=(nny)pny(1p)n(1y)=exp(n[ylogp1p(log(1p))]+log(nny))
โดยที่yคือ "สัดส่วนของความสำเร็จที่สังเกต" และnคือจำนวนการทดลองที่ทราบ

ในความเข้าใจของฉันความน่าจะเป็นที่จะประสบความสำเร็จpถูกเปรียบเทียบกับสัมประสิทธิ์เชิงเส้นβเป็นp=p(β)และฟังก์ชัน glm กับครอบครัว = "ทวินาม" ค้นหา:

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ด้วยคงไม่ได้ส่งผลกระทบต่อประมาณการความน่าจะเป็นสูงสุดของβให้สัดส่วนของความสำเร็จyi y_i

ไฟล์ช่วยเหลือของ 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     

ในขณะที่ถ้าฉันคูณน้ำหนักทั้งหมด 1,000 ด้วยค่าสัมประสิทธิ์โดยประมาณจะแตกต่างกัน:

 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(ในตระกูล.c ) และ 2) ใน IWLS ทีละขั้นตอนCdqrls(ในlm.c ) ฉันไม่รู้ C มากพอที่จะช่วยในการติดตามตรรกะมากขึ้น
shadowtalker

3
ตรวจสอบคำตอบที่นี่
สถิติ

@ssdecontrol ฉันกำลังอ่านผ่าน glm.fit ในลิงก์ที่คุณให้ฉัน แต่ฉันไม่สามารถหาที่ฟังก์ชัน C "binomial_dev_resids" ซึ่งเรียกว่าใน glm.fit คุณจะรังเกียจไหมถ้าคุณชี้ให้เห็น?
FairyOnIce

@ssdecontrol โอ้ขอโทษฉันคิดว่าฉันเข้าใจ "family" แต่ละรายการคือรายการหนึ่งในองค์ประกอบคือ "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-การสลายตัวของที่เป็นเมทริกซ์ออกแบบและเป็นเส้นทแยงมุมกับรากที่สองของรายการตามที่อธิบายไว้ที่นี่ นั่นคือใช้วิธีการของ Newton-RaphsonXWXXW

$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

ฉันคิดว่าน้ำหนักมีผลกระทบมากกว่าการโต้แย้งเพื่อเริ่มต้น ด้วยการถดถอยโลจิสติกนิวตัน Raphson ประมาณการโอกาสสูงสุดที่มีอยู่และไม่ซ้ำกันเมื่อข้อมูลไม่ได้ถูกแยกออก การระบุค่าเริ่มต้นที่แตกต่างให้กับเครื่องมือเพิ่มประสิทธิภาพจะไม่มาถึงค่าที่แตกต่างกัน แต่อาจใช้เวลานานกว่านั้นในการไปถึงที่นั่น
AdamO

"การจัดหาค่าเริ่มต้นที่แตกต่างกันเพื่อเพิ่มประสิทธิภาพจะไม่มาถึงที่ค่าที่แตกต่างกัน ..." วิธีการของนิวตันนั้นไม่ได้แยกออกและหาค่าสูงสุดเฉพาะในตัวอย่างสุดท้ายที่ฉันตั้งค่าเริ่มต้น (ดูตัวอย่างที่ฉันให้mustart อาร์กิวเมนต์) ดูเหมือนว่าเรื่องที่เกี่ยวข้องกับแย่ประมาณในเบื้องต้น
Benjamin Christoffersen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.