-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathResumenLogit.R
232 lines (168 loc) · 7.04 KB
/
ResumenLogit.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
if(!require("pacman")) install.packages("pacman")
pacman::p_load(tidyverse, glmulti, mfx, ROCR, broom, purrr, margins, stringr, sjPlot, rmarkdown)
MatConf <- function(m, d, y){
# Crea una matriz de confusión, el R^2, especificidad,
# sensibilidad, precisión y AUC, este último con la
# librería ROCR
#
# Args:
# m: modelo estimado
# d: data frame con los datos del modelo
# y: variable dependiente o target (caracter)
# Returns:
# una lista con la matriz de confusión, el R^2,
# especificidad, sensibilidad, precisión y AUC
#El tomar 0,5 como límite para determinar la probabilidad de una valoración alta es una decisión estándar pero
#arbitraria. Existen maneras de determinar si esta tasa es la adecuada empleando varios criterios, a continuación
#mostramos como varía la precisión del modelo con distintos limites.
variableTarget <- d[, y]
prediccion <- ROCR::prediction(fitted(m), variableTarget)
precision <- performance(prediccion,'acc')
ac.val = max(unlist([email protected]))
th0 = unlist([email protected])[unlist([email protected]) == ac.val]
th = th0[1]
#R2
pseudoR2 <- 1 - m$deviance/m$null.deviance
#matriz.confusion
matriz.confusion <- table(prediccion = predict(m, newdata = d, type='response')>th,
observado =variableTarget)
#Calculamos la precisión, especificidad y sensibilidad
A1 = matriz.confusion[1,1] / sum(matriz.confusion[,1])
A2 = matriz.confusion[2,2] / sum(matriz.confusion[,2])
A3 <- sum(diag(matriz.confusion)) / sum(matriz.confusion)
#AUC
auc.c2 = performance(prediccion, "auc")
auc.c2 = unlist([email protected])
list(matriz = matriz.confusion, R2 = pseudoR2, especificidad = A1,
sensibilidad = A2, precision = A3, AUC = auc.c2)
}
selecModelo <- function(d, y, x, C=TRUE){
# La función emplea el paquete glmulti para seleccionar
# los 3 mejores modelos logit a partir de una fuente de datos
# y genera un documento en formato pdf que resume los 3 modelos
# de la siguiente forma:
# - Una tabla con los coeficientes y el p-valor de los 3 mejores
# modelos obtenidos a través de una búsqueda exhaustiva empleando
# el paquete glmulti
# - Una tabla con los efectos marginales calculados con el paquete
# margins
# - Una tabla de evaluación donde se presentan el R2, especificidad,
# sensibilidad, precisión y AUC. Los datos se calculan en la función
# MatConf, para el cálculo del AUC se utiliza el paquete ROCR
# - Dos gráficos del paquete glmulti que presentan la importancia
# relativa de las variables y la selección del número de mejores
# modelos usando el criterior AIC
# - Los gráficos de las probabilidades relativas de los 3 mejores
# modelos utilizando el comando plot_modeldel paquete sjPlot
# - Los gráficos de los efectos marginales de los 3 mejores modelos
#
# Args:
# d: data frame con los datos del modelo
# y: variable dependiente o target (caracter)
# x: vector de variables independientes o features (caracter)
# Returns:
# Un documento en formato pdf con las tablas y gráficos
# arriba descritos
#Se estiman los modelos
set.seed(123)
glmulti.logistic.out <-
glmulti(y,
x,
data = d,
intercept = C, # Incluir constante
level = 1, # No interaction considered
method = "h", # Exhaustive approach
crit = "aic", # AIC as criteria
confsetsize = 100, # Keep n best models
plotty = F, report = T, # No plot or interim reports
fitfunction = "glm", # glm function
family = binomial(link = 'logit')) # binomial family for logistic regression
#Graficos del glmulti
jpeg(file = 'grafglmutl.jpeg', width = 480, height = 550)
par(mfrow=c(2,1))
plot(glmulti.logistic.out, type = "s")
plot(glmulti.logistic.out, type = "p")
dev.off()
#Se construyen las tablas
#Se inicializan las tablas como listas vacias
modelo1 <- list()
modelo2 <- list()
evaluacion <- list()
#Se rellenan las tablas con los 3 mejores modelos
for (i in 1:3) {
set.seed(123)
modeloBest <- paste(paste0(y,"~"),
as.character(glmulti.logistic.out@formulas[[i]][3]))
modeloLogit <- glm(modeloBest,
family = binomial(link = 'logit'),
data = d)
#Se elimina el -1 en la formula del modelo para que lo pueda leer la funcion logitmfx
ifelse(C == FALSE, modeloBest <- str_replace_all(modeloBest, '.-1 .', ''), modeloBest)
EfectMarg <- logitmfx(modeloBest
, data = d,
atmean = FALSE)
EfectMarg2 <- margins(modeloLogit)
MargGraf <- summary(EfectMarg2)
#Gráfico efectos marginales
jpeg(file = paste0('grafprob', i, '.jpeg'))
print(plot_model(modeloLogit, vline.color = "blue", sort.est = TRUE, show.values = TRUE, value.offset = .3))
dev.off()
ggplot(data = MargGraf) +
geom_point(aes(factor, AME)) +
geom_errorbar(aes(x = factor, ymin = lower, ymax = upper)) +
geom_hline(yintercept = 0) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45))
ggsave(paste0('grafmarg', i, '.jpeg'), width=6, height=6)
message(paste0("creando tabla ", i))
#Tabla modelos logit
modelo1[[i]] <- tidy(modeloLogit) %>%
dplyr::select(term, estimate, p.value) %>%
dplyr::rename(variable = term, coeficiente = estimate, pvalor = p.value)
#Tabla efectos marginales
modelo2[[i]] <- EfectMarg$mfxest %>%
as.data.frame() %>%
rownames_to_column() %>%
dplyr::rename(marginal = `dF/dx`, pvalor = `P>|z|`, variable = rowname) %>%
dplyr::select(variable, marginal, pvalor)
#Evaluacion
evalTemp <- MatConf(modeloLogit, d, y)
evaluacion[[i]] <- evalTemp[c(2:6)] %>%
unlist()
}
#Tabla de coeficientes
modelo_Coef <- modelo1 %>%
reduce(full_join, by = "variable")
for (i in seq(3,7,2)) {
modelo_Coef[,i] <- modelo_Coef[,i] %>%
map(function(x) round(x,5)) %>%
unlist()
}
for (i in seq(2,6,2)) {
colnames(modelo_Coef)[i] <- 'Coeficientes'
}
for (i in seq(3,7,2)) {
colnames(modelo_Coef)[i] <- 'pValor'
}
#Tabla de efectos marginales
modelo_Marg <- modelo2 %>%
reduce(full_join, by = "variable")
for (i in seq(3,7,2)) {
modelo_Marg[,i] <- modelo_Marg[,i] %>%
map(function(x) round(x,5)) %>%
unlist()
}
for (i in seq(2,6,2)) {
colnames(modelo_Marg)[i] <- 'Coeficientes'
}
for (i in seq(3,7,2)) {
colnames(modelo_Marg)[i] <- 'pValor'
}
#Tabla de Evaluacion
Modelo_Eval <- reduce(evaluacion, rbind)
rownames(Modelo_Eval) <- c('Modelo 1', 'Modelo 2', 'Modelo 3')
render("cuadros.rmd", output_file = 'cuadros.pdf')
list(coeficientes = modelo_Coef,
marginales = modelo_Marg,
evaluacionM = Modelo_Eval)
}