Trazar intervalos de confianza para las probabilidades predichas a partir de una regresión logística

20

Ok, tengo una regresión logística y he usado la predict()función para desarrollar una curva de probabilidad basada en mis estimaciones.

## LOGIT MODEL:
library(car)
mod1 = glm(factor(won) ~ as.numeric(bid), data=mydat, family=binomial(link="logit"))

## PROBABILITY CURVE:
all.x <- expand.grid(won=unique(won), bid=unique(bid))
y.hat.new <- predict(mod1, newdata=all.x, type="response")
plot(bid<-000:1000,predict(mod1,newdata=data.frame(bid<-c(000:1000)),type="response"), lwd=5, col="blue", type="l")

Esto es genial, pero tengo curiosidad por trazar los intervalos de confianza para las probabilidades. Lo intenté plot.ci()pero no tuve suerte. ¿Alguien puede señalarme algunas formas de hacer esto, preferiblemente con el carpaquete o la base R.

ATMathew
fuente
44
(+1) En respuesta a los votos para cerrar como tema: aparentemente, la base para esos votos es que la pregunta parece hacer una pregunta puramente relacionada con el software ("cómo trazar tal y tal en R"), un pregunta que de hecho debería aparecer en SO. Sin embargo, tenga en cuenta que en la respuesta actual hay fórmulas estadísticas para crear los puntos de trazado. Esto sugiere que hay un interés estadístico en la pregunta, por lo que soy reacio a votar por la migración. Una buena respuesta aquí destacaría y explicaría este punto estadístico.
whuber

Respuestas:

26

El código que usó estima un modelo de regresión logística usando la glmfunción. No incluiste datos, así que solo inventaré algunos.

set.seed(1234)
mydat <- data.frame(
    won=as.factor(sample(c(0, 1), 250, replace=TRUE)), 
    bid=runif(250, min=0, max=1000)
)
mod1 <- glm(won~bid, data=mydat, family=binomial(link="logit"))

Un modelo de regresión logística modela la relación entre una variable de respuesta binaria y, en este caso, un predictor continuo. El resultado es una probabilidad transformada de logit como una relación lineal con el predictor. En su caso, el resultado es una respuesta binaria correspondiente a ganar o no ganar en el juego y se predice por el valor de la apuesta. Los coeficientes de mod1se dan en probabilidades registradas (que son difíciles de interpretar), de acuerdo con:

logit(pag)=Iniciar sesión(pag(1-pag))=β0 0+β1X1

Para convertir las probabilidades registradas en probabilidades, podemos traducir lo anterior a

pag=Exp(β0 0+β1X1)(1+Exp(β0 0+β1X1))

Puede usar esta información para configurar la trama. Primero, necesita un rango de la variable predictora:

plotdat <- data.frame(bid=(0:1000))

Luego predict, usando , puede obtener predicciones basadas en su modelo

preddat <- predict(mod1, newdata=plotdat, se.fit=TRUE)

Tenga en cuenta que los valores ajustados también se pueden obtener a través de

mod1$fitted

Al especificar se.fit=TRUE, también obtiene el error estándar asociado con cada valor ajustado. El resultado data.framees una matriz con los siguientes componentes: las predicciones ajustadas ( fit), los errores estándar estimados ( se.fit) y un escalar que proporciona la raíz cuadrada de la dispersión utilizada para calcular los errores estándar ( residual.scale). En el caso de un logit binomial, el valor será 1 (que se puede ver mediante la introducción preddat$residual.scaleen R). Si desea ver un ejemplo de lo que ha calculado hasta ahora, puede escribir head(data.frame(preddat)).

El siguiente paso es configurar la trama. Me gusta configurar un área de trazado en blanco con los parámetros primero:

with(mydat, plot(bid, won, type="n", 
    ylim=c(0, 1), ylab="Probability of winning", xlab="Bid"))

Ahora puede ver dónde es importante saber cómo calcular las probabilidades ajustadas. Puede dibujar la línea correspondiente a las probabilidades ajustadas siguiendo la segunda fórmula anterior. Usando el preddat data.framepuede convertir los valores ajustados a probabilidades y usar eso para trazar una línea contra los valores de su variable predictiva.

with(preddat, lines(0:1000, exp(fit)/(1+exp(fit)), col="blue"))

Finalmente, responda su pregunta, los intervalos de confianza se pueden agregar a la gráfica calculando la probabilidad de los valores ajustados por +/- 1.96el error estándar:

with(preddat, lines(0:1000, exp(fit+1.96*se.fit)/(1+exp(fit+1.96*se.fit)), lty=2))
with(preddat, lines(0:1000, exp(fit-1.96*se.fit)/(1+exp(fit-1.96*se.fit)), lty=2))

La gráfica resultante (de los datos generados aleatoriamente) debería verse así:

ingrese la descripción de la imagen aquí

Por conveniencia, aquí está todo el código en un fragmento:

set.seed(1234)
mydat <- data.frame(
    won=as.factor(sample(c(0, 1), 250, replace=TRUE)), 
    bid=runif(250, min=0, max=1000)
)
mod1 <- glm(won~bid, data=mydat, family=binomial(link="logit"))
plotdat <- data.frame(bid=(0:1000))
preddat <- predict(mod1, newdata=plotdat, se.fit=TRUE)
with(mydat, plot(bid, won, type="n", 
    ylim=c(0, 1), ylab="Probability of winning", xlab="Bid"))
with(preddat, lines(0:1000, exp(fit)/(1+exp(fit)), col="blue"))
with(preddat, lines(0:1000, exp(fit+1.96*se.fit)/(1+exp(fit+1.96*se.fit)), lty=2))
with(preddat, lines(0:1000, exp(fit-1.96*se.fit)/(1+exp(fit-1.96*se.fit)), lty=2))

(Nota: esta es una respuesta muy editada en un intento de hacerla más relevante para stats.stackexchange).

smillig
fuente
¿Dónde se se.fitdefine la variable ?
Macro
En predict(..., se.fit=TRUE).
smillig
(-1) ¿Estos IC son para cada caso individual? Si es así, para un resultado binario, el único IC sensible para una probabilidad pronosticada es [0,1]. Aunque esto puede ser una respuesta técnicamente competente.
rolando2
Según el comentario de @ whuber, creo que una buena respuesta debería incluir una fórmula para calcular el SE. ¿Alguien podría quizás editar y mejorar la respuesta?
Heisenberg
1
Su respuesta parece dar solo el 'intervalo de predicción medio'. ¿Cómo agregaría el 'intervalo de predicción de puntos'?
Bob Hopez
0

Aquí hay una modificación de la solución de @ smillig. Aquí utilizo herramientas tidyverse, y también uso la linkinvfunción que forma parte del objeto modelo GLM mod1. De esa manera, no tiene que invertir manualmente la función logística, y este enfoque funcionará independientemente de qué GLM específico se ajuste.

library(tidyverse)
library(magrittr)


set.seed(1234)

# create fake data on gambling. Does prob win depend on bid size? 
mydat <- data.frame(
  won=as.factor(sample(c(0, 1), 250, replace=TRUE)), 
  bid=runif(250, min=0, max=1000)
)

# logistic regression model: 
mod1 <- glm(won~bid, data=mydat, family=binomial(link="logit"))

# new predictor values to use for prediction: 
plotdat <- data.frame(bid=(0:1000))

# df with predictions, lower and upper limits of CIs: 
preddat <- predict(mod1,
               type = "link",
               newdata=plotdat,
               se.fit=TRUE) %>% 
  as.data.frame() %>% 
  mutate(bid = (0:1000), 

         # model object mod1 has a component called linkinv that 
         # is a function that inverts the link function of the GLM:
         lower = mod1$family$linkinv(fit - 1.96*se.fit), 
         point.estimate = mod1$family$linkinv(fit), 
         upper = mod1$family$linkinv(fit + 1.96*se.fit)) 


# plotting with ggplot: 
preddat %>% ggplot(aes(x = bid, 
                   y = point.estimate)) + 
  geom_line(colour = "blue") + 
  geom_ribbon(aes(ymin = lower,
                  ymax = upper), 
              alpha = 0.5) + 
  scale_y_continuous(limits = c(0,1))
Nayef
fuente
3
Aunque la implementación a menudo se mezcla con contenido sustantivo en las preguntas, se supone que somos un sitio para proporcionar información sobre estadísticas, aprendizaje automático, etc., no código. También puede ser bueno proporcionar código, pero elabore su respuesta sustantiva en texto para las personas que no leen este idioma lo suficiente como para reconocer y extraer la respuesta del código.
gung - Restablece a Monica