r
: indicador de presencia de oxalato de calcio. 0
: ausencia de oxalato en orina.1
: presencia de oxalato en orina.gravity
: gravedad específica de la orina.ph
: pH de la orina.osmo
: osmolaridad de la orina.cond
: conductivicad de la orina.urea
: concentración de urea en la orina.calc
: concentración de calcio (milimoles por litro).glm()
.glm()
) haciendo uso de la función cv.glm()
del paquete boot
. Esta función calcula el error de predicción a través de validación cruzada. Cuando el argumento K
no se especifica, por defecto será igual al número de observaciones (ayuda: ?cv.glm()). Este procedimiento también es posible realizarlo manualmente por medio de update()
.\[Y_i \sim\ B(p_i,\ n_i),\ para\ i=1,...,m\]
\[p(Y =1\ |\ X)=\frac{e^{(\beta_0+\beta_1x)}}{e^{(\beta_0+\beta_1x)}+1}\]
\[p(X) = \frac{e^{(\beta_0+\beta_1x)}}{e^{(\beta_0+\beta_1x)}+1}\\ p(e^{(\beta_0+\beta_1x)}+1) = e^{(\beta_0+\beta_1x)}\\ p \times e^{(\beta_0+\beta_1x)}\ +\ p = e^{(\beta_0+\beta_1x)}\\ p = e^{(\beta_0+\beta_1x)}\ -\ p \times e^{(\beta_0+\beta_1x)}\\ p = e^{(\beta_0+\beta_1x)}(1-p)\\ \frac{p}{1-p} = e^{(\beta_0+\beta_1x)}\]
\[ln(\frac{p}{1-p}) = \beta_0+\beta_1x\]
\[Y_i \sim\ B(p_i,\ n_i),\ para\ i=1,...,m\]
\[p(Y = 1|X)=\ \Phi(X^{T}\beta)\]
1
) y negativos (0
)library(broom)
tidy(apply(datos, MARGIN = 2, is.na)) %>%
gather(key = "variable", value = "valor") %>%
mutate(valor = as.numeric(valor)) %>%
group_by(variable) %>%
summarise(Total_NAs = sum(valor))
# Modelos Lineales Generalizados
mod_logit <- glm(r ~ ., data = datos, family = binomial(link = "logit"))
mod_probit <- glm(r ~ ., data = datos, family = binomial(link = "probit"))
# -------- Validación LOOCV (Manual)
out_logi_0.5 <- NULL
out_prob_0.5 <- NULL
for(i in 1:nrow(datos)){
out_logi_0.5[i] = predict(update(mod_logit, data = datos[-i, ]),
newdata = datos[i,], type = "response")
out_prob_0.5[i] = predict(update(mod_probit, data = datos[-i, ]),
newdata = datos[i,], type = "response")
}
# -------- Validación LOOCV (cv.glm())
## Función de coste con cutoff = 0.5
coste_0.5 <- function(r, pi = 0) mean(abs(r-pi)> 0.5)
## LOOCV
library(boot)
cv_error_logi_0.5 <- cv.glm(data = datos %>% filter(!is.na(osmo) & !is.na(cond)),
glmfit = mod_logit, cost = coste_0.5)
cv_error_prob_0.5 <- cv.glm(data = datos %>% filter(!is.na(osmo) & !is.na(cond)),
glmfit = mod_probit, cost = coste_0.5)
cv.glm()
requiere una función de coste para calcular el error. El objeto devuelto por la función del paquete boot
almacena el error con el nombre delta
; al restar 1 menos el error (delta) se obtendrá la precisión o accuracy del modelo, que es exactamente el mismo valor obtenido manualmente.
cv.glm()
.# Precisión manual - R. Logística (0.5)
manual_logi_0.5 <- if_else(out_logi_0.5 > 0.5, true = "1", false = "0")
manual_logi_0.5 <- mean(datos$r == manual_logi_0.5, na.rm = TRUE)
# Precisión con cv.glm() - R. Logística (0.5)
cv_logi_0.5 <- 1 - cv_error_logi_0.5$delta[1]
# Precisión manual - R. Probit (0.5)
manual_prob_0.5 <- if_else(out_prob_0.5 > 0.5, true = "1", false = "0")
manual_prob_0.5 <- mean(datos$r == manual_prob_0.5, na.rm = TRUE)
# Precisión con cv.glm() - R. Logística (0.5)
cv_prob_0.5 <- 1 - cv_error_prob_0.5$delta[1]
# Imprimiendo resultados
cat(paste0("R. Logística 0.5 Manual = ", manual_logi_0.5),
"y R. Logística 0.5 cv.glm() = ", cv_logi_0.5)
R. Logística 0.5 Manual = 0.74025974025974 y R. Logística 0.5 cv.glm() = 0.7402597
tidy(mod_logit) %>%
select(term, estimate, p.value) %>%
mutate(signif = if_else(p.value <= 0.05, true = "Significativo",
false = "No significativo"))
tidy(mod_probit) %>%
select(term, estimate, p.value) %>%
mutate(signif = if_else(p.value <= 0.05, true = "Significativo",
false = "No significativo"))
# Punto de corte 0.65 - clases 0 y 1
out_logi_0.65 <- if_else(condition = out_logi > 0.65, true = "1", false = "0")
out_prob_0.65 <- if_else(condition = out_prob > 0.65, true = "1", false = "0")
# Punto de corte 0.6 - clases 0 y 1
out_logi_0.6 <- if_else(condition = out_logi > 0.6, true = "1", false = "0")
out_prob_0.6 <- if_else(condition = out_prob > 0.6, true = "1", false = "0")
# Punto de corte 0.55 - clases 0 y 1
out_logi_0.55 <- if_else(condition = out_logi > 0.55, true = "1", false = "0")
out_prob_0.55 <- if_else(condition = out_prob > 0.55, true = "1", false = "0")
# Punto de corte 0.5 - clases 0 y 1
out_logi_0.5 <- if_else(condition = out_logi > 0.5, true = "1", false = "0")
out_prob_0.5 <- if_else(condition = out_prob > 0.5, true = "1", false = "0")
# Punto de corte 0.45 - clases 0 y 1
out_logi_0.45 <- if_else(condition = out_logi > 0.45, true = "1", false = "0")
out_prob_0.45 <- if_else(condition = out_prob > 0.45, true = "1", false = "0")
# Punto de corte 0.4 - clases 0 y 1
out_logi_0.4 <- if_else(condition = out_logi > 0.4, true = "1", false = "0")
out_prob_0.4 <- if_else(condition = out_prob > 0.4, true = "1", false = "0")
# Error de modelos
df_accuracy <- data.frame(
Modelo = c("R. Logística - (0.65)", "R. Probit - (0.65)",
"R. Logística - (0.6)", "R. Probit - (0.6)",
"R. Logística - (0.55)", "R. Probit - (0.55)",
"R. Logística - (0.5)", "R. Probit - (0.5)",
"R. Logística - (0.45)", "R. Probit - (0.45)",
"R. Logística - (0.4)", "R. Probit - (0.4)"),
Accucary = c(mean(datos$r == out_logi_0.65, na.rm = TRUE),
mean(datos$r == out_prob_0.65, na.rm = TRUE),
mean(datos$r == out_logi_0.6, na.rm = TRUE),
mean(datos$r == out_prob_0.6, na.rm = TRUE),
mean(datos$r == out_logi_0.55, na.rm = TRUE),
mean(datos$r == out_prob_0.55, na.rm = TRUE),
mean(datos$r == out_logi_0.5, na.rm = TRUE),
mean(datos$r == out_prob_0.5, na.rm = TRUE),
mean(datos$r == out_logi_0.45, na.rm = TRUE),
mean(datos$r == out_prob_0.45, na.rm = TRUE),
mean(datos$r == out_logi_0.4, na.rm = TRUE),
mean(datos$r == out_prob_0.4, na.rm = TRUE))
) %>%
separate(Modelo, into = c("Modelo", "Límite"), remove = FALSE, sep = "-")
df_accuracy
\[logit(oxalato = 1) = -355.3377 + 355.9437\times grav - 0.4957\times pH +\\ 0.0168\times osmo - 0.4328\times conduc - 0.0320\times urea + 0.7836 \times calcio\]
\[p(oxalato = 1) = \frac{e^{-355.3377 + 355.9437\times grav - 0.4957\times pH + 0.0168\times osmo - 0.4328\times conduc - 0.0320\times urea + 0.7836 \times calcio}}{1 + e^{-355.3377 + 355.9437\times grav - 0.4957\times pH + 0.0168\times osmo - 0.4328\times conduc - 0.0320\times urea + 0.7836 \times calcio}}\]