Esta base de datos recopila información sobre las condiciones ambientales y su posible relación con la presencia de plagas en cultivos de aguacate. Contiene variables como temperatura, humedad y velocidad del viento, las cuales pueden influir en la proliferación de plagas. Además, incluye datos sobre la cantidad de frutos afectados por un tipo específico de plaga, otros frutos dañados por plagas no identificadas y el total de frutos afectados.
Cada fila de la base representa una observación en un momento y lugar determinado, permitiendo analizar cómo los factores climáticos inciden en la presencia de plagas y el nivel de afectación en los frutos. Esta información es útil para identificar patrones y desarrollar estrategias de control que minimicen el impacto de las plagas en la producción de aguacate.
library(readxl)
library(knitr)
library(kableExtra)
library(magrittr)
aguacate <- read_excel("aguacate.xlsx")
temperatura=aguacate$Temperature
humedad=aguacate$`Relative Humidity`
viento=aguacate$`Wind Speed`
frutos_afectados=aguacate$Frutos_Afectados_Heilipus+aguacate$Frutos_Afectados_Stenoma
y=as.numeric(frutos_afectados>0)
df_frutos=data.frame(y,temperatura,humedad,viento)
df_frutos=na.omit(df_frutos)
modelo=glm(y~temperatura+humedad+viento,data = df_frutos,family = "binomial")
# Extraer coeficientes y valores p
resultado_modelo <- summary(modelo)$coefficients
# Convertir en data frame para mostrar en la tabla
tabla_resultado <- as.data.frame(resultado_modelo)
colnames(tabla_resultado) <- c("Estimado", "Error Estándar", "Z-valor", "P-valor")
# Función para asignar asteriscos de significancia
asignar_asteriscos <- function(pvalor) {
sapply(pvalor, function(p) {
if (p < 0.001) return("***")
else if (p < 0.01) return("**")
else if (p < 0.05) return("*")
else return("")
})
}
# Agregar columna de significancia
tabla_resultado$Significancia <- asignar_asteriscos(tabla_resultado$`P-valor`)
# Crear tabla en formato bonito
kable(tabla_resultado, format = "html", caption = "Resultados del Modelo Logístico") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover"))
Estimado | Error Estándar | Z-valor | P-valor | Significancia | |
---|---|---|---|---|---|
(Intercept) | 0.1045238 | 1.1395045 | 0.0917274 | 0.9269146 | |
temperatura | -0.0038533 | 0.0341731 | -0.1127595 | 0.9102212 | |
humedad | -0.0376945 | 0.0063140 | -5.9700140 | 0.0000000 | *** |
viento | -0.1480724 | 0.2115482 | -0.6999463 | 0.4839608 |
El análisis del modelo logístico muestra que la humedad es la única variable que influye de manera importante en la presencia de la plaga, ya que su p-valor es muy bajo (***), indicando una relación significativa. Dado que su coeficiente es negativo, esto significa que a mayor humedad, menor presencia de plaga, y viceversa, en condiciones más secas la plaga tiende a aumentar. Por otro lado, la temperatura y el viento no parecen tener un efecto claro, ya que sus p-valores son altos, lo que sugiere que no están relacionadas de manera fuerte con la presencia de la plaga. Estos resultados indican que controlar la humedad en los cultivos podría ser una estrategia clave para reducir el impacto de la plaga.
probas=modelo$fitted.values
presencia_plaga_modelo=probas>0.15
presencia_plaga_real=df_frutos$y
# Crear la matriz de confusión
matriz_confusion <- table(presencia_plaga_real, presencia_plaga_modelo)
# Crear la tabla de confusión
tabla <- table(Real = presencia_plaga_real, Modelo = presencia_plaga_modelo)
# Mostrar con títulos bien formateados
kable(tabla, format = "html", caption = "Matriz de Confusión") %>%
kable_styling(full_width = FALSE, bootstrap_options = c("striped", "hover"))
FALSE | TRUE | |
---|---|---|
0 | 1796 | 355 |
1 | 105 | 107 |
La matriz de confusión muestra el desempeño del modelo en la predicción de la presencia de plagas. De los casos en los que no hubo plaga (0), el modelo clasificó correctamente 1796 observaciones, pero se equivocó en 355 casos, etiquetándolos erróneamente como presencia de plaga. Por otro lado, de los casos donde sí hubo plaga (1), el modelo acertó en 107 casos, pero falló en 105, clasificándolos incorrectamente como ausencia de plaga. Esto indica que el modelo tiene una alta capacidad para identificar la ausencia de plaga, pero tiene dificultades para detectar correctamente su presencia, lo que sugiere la necesidad de mejorar la sensibilidad del modelo.
library(ggplot2)
umbral <- 0.15
calc_metricas <- function(umbral) {
presencia_plaga_modelo <- probas > umbral
presencia_plaga_real <- df_frutos$y
# Matriz de confusión
tabla <- table(presencia_plaga_real, presencia_plaga_modelo)
# Cálculo del desempeño
desempeño <- (tabla[1, 1] + tabla[2, 2]) / sum(tabla)
return(desempeño)
}
# Evaluación para diferentes umbrales
umbrales <- seq(0.05, 0.24, 0.01)
desempeños <- sapply(umbrales, calc_metricas)
# Crear data frame para ggplot
df_plot <- data.frame(Umbral = umbrales, Desempeño = desempeños)
# Graficar con formato igual al de sensibilidad
plot(umbrales, desempeños, type = "b", col = "cadetblue3", pch = 16, lwd = 2,
xlab = "Umbral de Clasificación", ylab = "Exactitud del Modelo",
main = "Desempeño del Modelo según el Umbral")
grid()
El gráfico muestra cómo varía la exactitud del modelo a medida que se ajusta el umbral de clasificación. Se observa que para umbrales bajos (cercanos a 0.05), la exactitud es inferior al 50%, lo que indica un alto nivel de errores en la clasificación. A medida que el umbral aumenta, la exactitud mejora progresivamente, alcanzando valores cercanos al 90% cuando el umbral está alrededor de 0.22.
Este comportamiento sugiere que, a menor umbral, el modelo clasifica más observaciones como presencia de plaga (posibles falsos positivos), mientras que con umbrales más altos, se vuelve más conservador y mejora la precisión, pero podría aumentar los falsos negativos. La elección del umbral óptimo debe equilibrar ambos tipos de errores según la aplicación específica del modelo.
# Definir umbral inicial
umbral = 0.15
# Función para calcular sensibilidad
calc_sensibilidad = function(umbral){
presencia_plaga_modelo = probas > umbral
presencia_plaga_real = df_frutos$y
# Matriz de confusión
tabla = table(presencia_plaga_real, presencia_plaga_modelo)
# Verificar que la matriz tiene la fila 2 (casos positivos)
if (nrow(tabla) < 2 || sum(tabla[2,]) == 0) {
return(NA) # Evita errores si no hay positivos en los datos
}
# Calcular sensibilidad
sensibilidad = tabla[2,2] / (tabla[2,2] + tabla[2,1])
return(sensibilidad)
}
# Generar secuencia de umbrales
umbrales = seq(0.05, 0.24, 0.01)
# Calcular sensibilidad para cada umbral
sensibilidades = sapply(umbrales, calc_sensibilidad)
# Graficar sensibilidad vs. umbral
plot(umbrales, sensibilidades, type = "b", col = "cadetblue3", pch = 16, lwd = 2,
xlab = "Umbral de Clasificación", ylab = "Sensibilidad",
main = "Sensibilidad del Modelo según el Umbral")
grid()
El gráfico muestra cómo varía la sensibilidad del modelo según el umbral de clasificación. Se observa que a medida que el umbral aumenta, la sensibilidad disminuye. Esto indica que al exigir una mayor probabilidad para clasificar un caso como positivo, se detectan menos verdaderos positivos, lo que reduce la sensibilidad. Un umbral bajo favorece la detección de la mayoría de los casos positivos, pero puede aumentar los falsos positivos. Por el contrario, un umbral alto disminuye los falsos positivos, pero también puede hacer que el modelo no detecte muchos casos reales de la plaga.
# Definir umbral inicial
umbral = 0.15
# Función para calcular especificidad
calc_especificidad = function(umbral){
presencia_plaga_modelo = probas > umbral
presencia_plaga_real = df_frutos$y
# Matriz de confusión
tabla = table(presencia_plaga_real, presencia_plaga_modelo)
# Verificar que la matriz tiene la fila 1 (casos negativos)
if (nrow(tabla) < 2 || sum(tabla[1,]) == 0) {
return(NA) # Evita errores si no hay negativos en los datos
}
# Calcular especificidad
especificidad = tabla[1,1] / (tabla[1,1] + tabla[1,2])
return(especificidad)
}
# Generar secuencia de umbrales
umbrales = seq(0.05, 0.24, 0.01)
# Calcular especificidad para cada umbral
especificidades = sapply(umbrales, calc_especificidad)
# Graficar especificidad vs. umbral
plot(umbrales, especificidades, type = "b", col = "cadetblue3", pch = 16, lwd = 2,
xlab = "Umbral de Clasificación", ylab = "Especificidad",
main = "Especificidad del Modelo según el Umbral")
grid()
El gráfico muestra la relación entre la especificidad del modelo y el umbral de clasificación. Se observa que a medida que el umbral aumenta, la especificidad también incrementa. Esto significa que al exigir una mayor probabilidad para clasificar un caso como positivo, el modelo comete menos falsos positivos, identificando mejor los casos negativos. Sin embargo, esto suele hacerse a costa de reducir la sensibilidad, como se vio en el gráfico anterior. Elegir un umbral adecuado implica encontrar un balance entre sensibilidad y especificidad, dependiendo del objetivo del modelo.
library(ggplot2)
umbral <- 0.15
calc_metricas <- function(umbral) {
presencia_plaga_modelo <- probas > umbral
presencia_plaga_real <- df_frutos$y
# Matriz de confusión
tabla <- table(presencia_plaga_real, presencia_plaga_modelo)
# Manejo de casos donde no haya positivos o negativos
if (nrow(tabla) < 2) return(NA)
# Cálculo de métricas
desempeño <- sum(diag(tabla)) / sum(tabla) # Exactitud
sensibilidad <- ifelse(sum(tabla[2,]) > 0, tabla[2,2] / (tabla[2,2] + tabla[2,1]), NA)
especificidad <- ifelse(sum(tabla[1,]) > 0, tabla[1,1] / (tabla[1,1] + tabla[1,2]), NA)
# Métrica compuesta (promedio de las tres métricas)
metrica_compuesta <- mean(c(desempeño, sensibilidad, especificidad), na.rm = TRUE)
return(metrica_compuesta)
}
# Evaluación para diferentes umbrales
umbrales <- seq(0.05, 0.24, 0.01)
metricas_compuestas <- sapply(umbrales, calc_metricas)
# Crear data frame para ggplot
df_plot <- data.frame(Umbral = umbrales, MetricaCompuesta = metricas_compuestas)
# Graficar con ggplot2
ggplot(df_plot, aes(x = Umbral, y = MetricaCompuesta)) +
geom_line(color = "cadetblue3", size = 1) +
geom_point(color = "chocolate4", size = 2) +
labs(
title = "Métrica Compuesta del Modelo según el Umbral",
x = "Umbral de Clasificación",
y = "Promedio de Desempeño, Sensibilidad y Especificidad"
) +
theme_minimal()
Este gráfico muestra el promedio entre la sensibilidad y la especificidad del modelo según el umbral de clasificación. Se observa que el desempeño del modelo mejora a medida que el umbral aumenta, alcanzando un máximo alrededor de 0.15, y luego comienza a disminuir. Esto indica que en este punto se logra el mejor balance entre sensibilidad y especificidad, asegurando un buen desempeño general. Elegir un umbral demasiado bajo puede generar muchos falsos positivos, mientras que uno muy alto reduce la detección de casos positivos.
Además, considerando la estabilidad de la métrica en valores cercanos al máximo, se puede establecer un rango adecuado entre 0.13 y 0.17, donde el modelo mantiene un rendimiento alto sin una caída significativa en su precisión.