El dataset Iris fue introducido por Ronald Fisher en 1936 y contiene 150 observaciones de flores pertenecientes a tres especies de iris (Iris setosa, Iris versicolor y Iris virginica). Cada registro incluye cuatro variables predictoras: longitud y ancho del sépalo, así como longitud y ancho del pétalo.
data <- read.csv("a4_iris.csv")
data <- data %>% mutate(variety = as.factor(variety))
resumen <- data.frame(
Variable = c("Longitud del sepalo", "Ancho del Sepalo", "Longitud del Petalo", "Ancho del Petalo"),
Min = sapply(data[,1:4], min),
Q1 = sapply(data[,1:4], function(x) quantile(x, 0.25)),
Median = sapply(data[,1:4], median),
Mean = sapply(data[,1:4], mean),
Q3 = sapply(data[,1:4], function(x) quantile(x, 0.75)),
Max = sapply(data[,1:4], max)
)
kable(resumen, caption = "Resumen de estadísticas")
| Variable | Min | Q1 | Median | Mean | Q3 | Max | |
|---|---|---|---|---|---|---|---|
| sepal.length | Longitud del sepalo | 4.3 | 5.1 | 5.80 | 5.843333 | 6.4 | 7.9 |
| sepal.width | Ancho del Sepalo | 2.0 | 2.8 | 3.00 | 3.057333 | 3.3 | 4.4 |
| petal.length | Longitud del Petalo | 1.0 | 1.6 | 4.35 | 3.758000 | 5.1 | 6.9 |
| petal.width | Ancho del Petalo | 0.1 | 0.3 | 1.30 | 1.199333 | 1.8 | 2.5 |
Se aprecia que las medias y medianas de las variables son consistentes, sin valores extremos evidentes. Los pétalos presentan mayor variabilidad que los sépalos, especialmente en longitud.
Setosa se distingue fácilmente por sus pétalos cortos y estrechos.
Versicolor y Virginica se diferencian mejor por el largo del pétalo que por el sépalo.
Graficando:
iris_long <- reshape2::melt(data, id.vars = "variety")
ggplot(iris_long, aes(x = value, fill = variety)) +
geom_histogram(alpha = 0.6, bins = 25, position = "identity") +
facet_wrap(~variable, scales = "free", ncol = 2) +
labs(title = "Distribuciones de las variables morfológicas",
x = "Valor", y = "Frecuencia") +
theme_minimal() +
theme(plot.title = element_text(face = "bold", hjust = 0.5))
Se observa que las variables de pétalo (petal.length y petal.width)
presentan distribuciones más diferenciadas entre especies, lo que
sugiere una alta capacidad discriminativa.
En cambio, las variables de sépalo muestran mayor solapamiento, especialmente entre versicolor y virginica.
Esto sugiere una posible correlación entre las variables, verificaremos este hecho
cor_matrix <- cor(data[, 1:4])
cor_long <- as.data.frame(as.table(cor_matrix))
ggplot(cor_long, aes(Var1, Var2, fill = Freq)) +
geom_tile(color = "white") +
scale_fill_gradient2(low = "#00FFFF", high = "#EE6A50", mid = "white",
midpoint = 0, limit = c(-1,1), name = "Correlación") +
labs(title = "Matriz de correlación entre variables morfológicas",
x = "", y = "") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1),
plot.title = element_text(face = "bold", hjust = 0.5))
Se observa una correlación positiva fuerte entre petal.length y
petal.width, lo que sugiere que ambas variables crecen conjuntamente y
podrían estar relacionadas funcionalmente. En contraste, se aprecia una
correlación negativa entre sepal.width y petal.length, lo que indica que
a medida que una aumenta, la otra tiende a disminuir.
Ahora graficaremos todas las combinaciones posibles entre las variables morfológicas del dataset: sepal.length, sepal.width, petal.length y petal.width. Cada celda representa una relación bivariada o un resumen univariado
ggpairs(data[, 1:4],
title = "Matriz de gráficos: combinaciones entre variables morfológicas")
Sepal Length
- Distribución unimodal con “pico” alrededor de 5.8–6.0 cm.
Sepal Width
- Distribución unimodal y simétrica, con valores centrados en 3.0–3.2
cm.
Petal Length
- Distribución casi bimodal, reflejando diferencias entre especies.
Petal Width
- Distribución bimodal muy marcada.
Sepal Width vs. Sepal Length
- Relación débil y ligeramente negativa.
Petal Length vs. Sepal Length
- Relación positiva clara; se distinguen agrupaciones por especie.
Petal Width vs. Sepal Length
- Relación creciente, a veces curvilínea.
Petal Length vs. Sepal Width
- Tendencia negativa.
Petal Width vs. Sepal Width
- Relación negativa débil.
Petal Width vs. Petal Length
- Relación muy fuerte y positiva, con tres grupos lineales
(especies).
Observamos que la gráfica correspondiente a la longitud y el ancho del sépalo aparenta una relación entre ambas variables, posiblemente lineal lo cual es reforzado por la correlación que presenta, para verificarlo podemos ver la siguiente gráfica:
data <- read.csv("a4_iris.csv")
data <- data %>% mutate(variety = as.factor(variety))
ggplot(data, aes(x = petal.length, y = petal.width, color = variety)) +
geom_point(alpha = 0.7, size = 3) +
labs(title = "Relación entre Longitud y Ancho del petalo",
x = "Longitud",
y = "Ancho",
color = "Especie") +
theme_minimal() +
theme(plot.title = element_text(face = "bold", hjust = 0.5))
Podemos asegurar que las tres especies presentan distribuciones claramente separadas. Distinguiendo que Setosa es la más aislada en todas las relaciones. Versicolor exhibe las correlaciones más fuertes, especialmente entre variables de pétalos. Virginica mantiene relaciones similares, aunque con mayor variabilidad.
Con esto nos plantearemos las siguientes preguntas:
Comenzaremos haciendo la clasificación Setosa vs No-Setosa y realizaremos la comparación entre los siguientes dos modelos:
\[ p = P(\text{Setosa} \mid \text{petal.length}, \text{petal.width}) = \frac{1}{1 + e^{-(\beta_{0} + \beta_{1} \cdot \text{petal.length} + \beta_{2} \cdot \text{petal.width})}} \]
\[ p = P(\text{Setosa} \mid \text{petal.length}, \text{petal.width}) = \frac{1}{1 + e^{-(\beta_{0} + \beta_{1} \cdot \text{petal.length})}} \]
Es decir que lo que se plantea es que el modelo utilice dos variables predictoras: la longitud y el ancho del pétalo.
La combinación lineal \[ \text{logit}(p) = \ln\left(\frac{p}{1-p}\right) = \beta_{0} + \beta_{1} \cdot \text{petal.length} + \beta_{2} \cdot \text{petal.width} \] se transforma mediante la función logística (sigmoide) para dar una probabilidad entre 0 y 1. El modelo estima la probabilidad de que una flor sea Setosa en función de ambas características morfológicas del pétalo. En contraste el segundo modelo considera la combinación lineal: \[ \text{logit}(p) = \ln\left(\frac{p}{1-p}\right) = \beta_{0} + \beta_{1} \cdot \text{petal.length} \]
Evaluaremos ambos modelos y validaremos cual es mejor.
data <- data %>%
mutate(versicolor_vs_virginica = case_when(
variety == "Versicolor" ~ 1,
variety == "Virginica" ~ 0,
TRUE ~ NA_real_ # Setosa queda como NA
)) %>%
mutate(setosa_vs_not = ifelse(variety == "Setosa", 1, 0))
set.seed(1602)
train_index <- sample(1:nrow(data), 0.5*nrow(data),replace = FALSE)
train <- data[train_index, ]
test <- data[-train_index, ]
glm_setosa <- glm(setosa_vs_not ~ petal.length + petal.width,
data = train,
family = binomial)
tidy(glm_setosa) %>%
kable(digits = 3, caption = "Resumen del modelo logístico Setosa vs No-Setosa")
| term | estimate | std.error | statistic | p.value |
|---|---|---|---|---|
| (Intercept) | 71.379 | 130225.3 | 0.001 | 1 |
| petal.length | -22.292 | 136347.0 | 0.000 | 1 |
| petal.width | -18.834 | 332546.6 | 0.000 | 1 |
Las medidas mostradas nos confirmar de manera contundente que el modelo clasifica absolutamente todas las observaciones de prueba de manera correcta. No hay falsos positivos ni falsos negativos. Cabe resaltar que se utilizó validación simple tomando solo el 50% de los datos.
Ahora exploraremos la suposición de que solo la longitud del pétalo es suficiente para clasificar la especie de las plantas. Para esto verificaremos el impacto que tiene el ancho del pétalo en el modelo.
glm_setosa_reduced <- glm(setosa_vs_not ~ petal.length,
data = train, family = binomial)
anova_result <- anova(glm_setosa_reduced, glm_setosa, test = "Chisq")
kable(summary(anova_result), caption = "Comparación de modelos logísticos (Setosa vs No-Setosa)") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"),
full_width = FALSE, position = "center")
| Resid. Df | Resid. Dev | Df | Deviance | Pr(>Chi) | |
|---|---|---|---|---|---|
| Min. :72.00 | Min. :2.540e-09 | Min. :1 | Min. :0 | Min. :1 | |
| 1st Qu.:72.25 | 1st Qu.:2.558e-09 | 1st Qu.:1 | 1st Qu.:0 | 1st Qu.:1 | |
| Median :72.50 | Median :2.576e-09 | Median :1 | Median :0 | Median :1 | |
| Mean :72.50 | Mean :2.576e-09 | Mean :1 | Mean :0 | Mean :1 | |
| 3rd Qu.:72.75 | 3rd Qu.:2.595e-09 | 3rd Qu.:1 | 3rd Qu.:0 | 3rd Qu.:1 | |
| Max. :73.00 | Max. :2.613e-09 | Max. :1 | Max. :0 | Max. :1 | |
| NA | NA | NA’s :1 | NA’s :1 | NA’s :1 |
Lo que observamos es que ambos modelos tienen una devianza residual prácticamente igual a cero la diferencia entre los dos modelos es insignificante y la prueba de razón de verosimilitud indica que añadir el ancho del pétalo no mejora significativamente el modelo.
Esto significa que la longitud del pétalo por sí sola ya separa perfectamente las clases y al añadir el ancho, el modelo no gana poder explicativo. Por eso la prueba devuelve un \(p\)-valor = 1: no hay evidencia de que el ancho del pétalo aporte información adicional.
Con esto hemos dado respuesta a las primeras dos preguntas:
De acuerdo con nuestros hallazgos basta solo con la longitud del pétalo.
Ahora verificaremos si es posible clasificar Versicolor y Virginica.
train_non_setosa <- train %>% filter(setosa_vs_not == 0)
glm_versi_virgi <- glm(versicolor_vs_virginica ~ petal.length + petal.width,
data = train_non_setosa,
family = binomial)
tidy(glm_versi_virgi) %>%
kable(digits = 3, caption = "Modelo logístico: Versicolor vs Virginica")
| term | estimate | std.error | statistic | p.value |
|---|---|---|---|---|
| (Intercept) | 42.195 | 16.269 | 2.594 | 0.009 |
| petal.length | -5.045 | 2.428 | -2.077 | 0.038 |
| petal.width | -10.432 | 4.707 | -2.216 | 0.027 |
Con lo visto hasta ahora podemos concluir que nuestros modelos nos permiten mostrar que en caso de que una flor no sea Setosa se puede utilizar el segundo modelo para clasificar si es Versicolor o Virginica.
Podemos complementarlo a partir de lo siguiente:
glm_setosa <- glm(setosa_vs_not ~ petal.length + petal.width, data = train, family = binomial)
or_setosa <- tidy(glm_setosa) %>%
mutate(odds_ratio = exp(estimate),
conf.low = exp(estimate - 1.96*std.error),
conf.high = exp(estimate + 1.96*std.error))
kable(or_setosa, digits = 3,
caption = "Odds Ratios del modelo logístico: Setosa vs No-Setosa")
| term | estimate | std.error | statistic | p.value | odds_ratio | conf.low | conf.high |
|---|---|---|---|---|---|---|---|
| (Intercept) | 71.379 | 130225.3 | 0.001 | 1 | 9.990014e+30 | 0 | Inf |
| petal.length | -22.292 | 136347.0 | 0.000 | 1 | 0.000000e+00 | 0 | Inf |
| petal.width | -18.834 | 332546.6 | 0.000 | 1 | 0.000000e+00 | 0 | Inf |
or_versi_virgi <- tidy(glm_versi_virgi) %>%
mutate(odds_ratio = exp(estimate),
conf.low = exp(estimate - 1.96*std.error),
conf.high = exp(estimate + 1.96*std.error))
kable(or_versi_virgi, digits = 3,
caption = "Odds Ratios del modelo logístico: Versicolor vs Virginica")
| term | estimate | std.error | statistic | p.value | odds_ratio | conf.low | conf.high |
|---|---|---|---|---|---|---|---|
| (Intercept) | 42.195 | 16.269 | 2.594 | 0.009 | 2.113405e+18 | 29946.01 | 1.491511e+32 |
| petal.length | -5.045 | 2.428 | -2.077 | 0.038 | 6.000000e-03 | 0.00 | 7.520000e-01 |
| petal.width | -10.432 | 4.707 | -2.216 | 0.027 | 0.000000e+00 | 0.00 | 2.990000e-01 |
Se corrobora que:
Los odds ratios aparecen como valores extremos (casi cero o infinito), lo que sugiere problemas de separación perfecta.
Mientras que para el segundo modelo los errores estándar son razonables y los \(p\)-values < 0.05, lo que indica que tanto la longitud como el ancho del pétalo son significativos para diferenciar Versicolor de Virginica.
Los coeficientes negativos implican que a medida que aumentan la longitud y el ancho del pétalo, disminuye la probabilidad de que la flor sea Versicolor, favoreciendo la clasificación como Virginica.
Los odds ratios menores que 1 confirman esto: * Para cada unidad extra en la longitud del pétalo, las probabilidades de ser Versicolor se reducen en un 99.4%. * Para cada unidad extra en el ancho del pétalo, las probabilidades de ser Versicolor se reducen casi a cero.
Ahora exploraremos la última pregunta:
| Estimate | Std. Error | t value | Pr(>|t|) | |
|---|---|---|---|---|
| (Intercept) | -0.3631 | 0.0398 | -9.1312 | 0 |
| petal.length | 0.4158 | 0.0096 | 43.3872 | 0 |
Modelo:
Ancho del pétalo = \(\beta_0 + \beta_1*\)Longitud del pétalo
Muestra un intercepto (\(\beta_0\) = -0.363) Cuando la longitud del pétalo es 0, el ancho esperado es -0.363 (no tiene interpretación biológica directa, pero es parte del ajuste).
Pendiente (\(\beta_1\) = 0.416) Por cada unidad que aumenta la longitud del pétalo, el ancho aumenta en promedio 0.416.
Significancia Ambos coeficientes son altamente significativos (p < 2e-16).
Bondad de ajuste
\(R^2\) = 0.927: el 92.7% de la variabilidad en el ancho del pétalo se explica por la longitud.
Estadístico F = 1882: prueba global del modelo, también muy significativa.
Residuales estandarizado = 0.206: indica que los residuos son pequeños en comparación con la escala de la variable.
Verificaremos los supuestos del modelo:
## `geom_smooth()` using formula = 'y ~ x'
Las gráficas muestran una relación lineal muy fuerte y positiva entre ambas variables. Los puntos se ajustan de manera estrecha alrededor de la recta estimada, indicando que el Ancho del pétalo puede ser predicha con alta precisión a partir de la Longitud del pétalo.
La gráfica Residuals vs Fitted sugiere que la varianza de los residuos no es completamente constante, especialmente hacia los valores ajustados más altos. Este patrón indica la presencia de heterocedasticidad leve a moderada, reforzada por la tendencia creciente observada en la gráfica Scale–Location, donde la dispersión de los residuos aumenta conforme crecen los valores ajustados.
La gráfica Q–Q Residuals indica que los residuos presentan buena normalidad, aunque se observa una ligera desviación en las colas, lo que sugiere colas más pesadas que la distribución normal.
Finalmente, la gráfica Residuals vs Leverage indica que, aunque no hay evidencia de puntos extremadamente influyentes —ya que ninguna observación supera las curvas de la distancia de Cook—, existen algunos casos que merecen atención. En particular, las observaciones 135, 108 y 123 presentan valores de leverage o residuos estandarizados relativamente altos.
\[ \mu_{\text{Setosa}} < \mu_{\text{Versicolor}} < \mu_{\text{Virginica}} \]
Clasificación perfecta de Setosa
vs. No-Setosa.
El modelo logístico logra una clasificación sin errores (Accuracy,
Precision, Recall, Specificity y F1 = 1). Este resultado refleja el
fenómeno de separación perfecta, donde las variables
explicativas separan completamente las clases. Aunque el desempeño es
impecable, los coeficientes carecen de estabilidad estadística.
Suficiencia de la longitud del pétalo. El análisis comparativo entre el modelo completo (longitud + ancho) y el reducido (solo longitud) muestra que el ancho no aporta información adicional. La longitud del pétalo, por sí sola, es suficiente para separar perfectamente las clases.
Dependencia lineal entre ancho y longitud.
El modelo lineal evidencia una relación muy fuerte entre ambas
variables:
\[ \text{Ancho del pétalo} = \beta_0 + \beta_1 \cdot \text{Longitud del pétalo} \]
con \(\beta_1 = 0.416\) altamente significativo y un coeficiente de determinación \(R^2 = 0.927\). Esto explica por qué el ancho resulta redundante respecto a la longitud.
Se ha confirmado que la longitud del pétalo es la variable clave para distinguir a la especie Setosa de las demás, y que el ancho del pétalo no aporta información adicional. La clasificación obtenida es perfecta en el conjunto de prueba, lo que convierte este caso en un ejemplo paradigmático de separación perfecta en regresión logística. Este ejercicio muestra cómo combinar análisis descriptivo, pruebas de significancia y modelos predictivos para llegar a conclusiones sólidas, y al mismo tiempo alerta sobre los riesgos de sobreajuste y la necesidad de validación externa.