#BASE DE DATOS: IRIS
#LIBRERÍAS
library(cluster)
library(stats)
library(factoextra)
library(dendextend)
library(rattle)
library(clustertend)
library(purrr)
library(clValid)
library(GGally)
library(tidyverse)
library(NbClust)
library(ggplot2)
library(corrplot)
library(lmtest)
library(car)
library(palmerpenguins)
La base de datos Palmer Penguins (penguins) contiene datos reales recopilados por la Dra. Kristen Gorman y el programa de Investigación Ecológica a Largo Plazo (LTER) de la Estación Palmer en la Antártida. Registra 344 observaciones de pingüinos.
Las variables se dividen en dos grupos.
Las cuatro variables numéricas continuas son las que procesarás matemáticamente para calcular las distancias euclídeas y aplicar los métodos de agrupamiento (Ward y K-means):
bill_length_mm: Longitud del pico (culmen) en milímetros.
bill_depth_mm: Profundidad del pico en milímetros.
flipper_length_mm: Longitud de la aleta en milímetros.
*body_mass_g: Masa corporal en gramos.
Las variables categóricas no entran en el cálculo de distancias, pero te dan el contexto biológico:
species: La especie del pingüino (Adélie, Chinstrap o Gentoo). Esta es la agrupación natural que tus algoritmos intentarán descubrir “a ciegas”.
*island: La isla del Archipiélago Palmer donde fue observado (Biscoe, Dream o Torgersen).
sex: Sexo biológico (macho o hembra).
year: Año de la recolección de datos (2007 a 2009).
Esta base contiene valores nulos (NA) y variables categóricas que deben filtrarse antes de calcular distancias euclídeas.
Objetivo del estudio: Determinar si las características morfológicas medidas son suficientes para segmentar estadísticamente a los individuos mediante algoritmos jerárquicos y no jerárquicos, descubriendo agrupaciones naturales y respondiendo a la interrogante de cuántos perfiles distintos existen en la muestra.
# Cargar y limpiar datos
data("penguins")
penguins_clean <- na.omit(penguins)
# Seleccionar solo las variables numéricas (medidas morfológicas)
dat_penguins <- penguins_clean %>%
select(bill_length_mm, bill_depth_mm, flipper_length_mm, body_mass_g)
# Escalar los datos para igualar las magnitudes
dat_penguins_e <- scale(dat_penguins)
# Resumen estadístico (Vector de promedios)
summary(dat_penguins)
## bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
## Min. :32.10 Min. :13.10 Min. :172 Min. :2700
## 1st Qu.:39.50 1st Qu.:15.60 1st Qu.:190 1st Qu.:3550
## Median :44.50 Median :17.30 Median :197 Median :4050
## Mean :43.99 Mean :17.16 Mean :201 Mean :4207
## 3rd Qu.:48.60 3rd Qu.:18.70 3rd Qu.:213 3rd Qu.:4775
## Max. :59.60 Max. :21.50 Max. :231 Max. :6300
# Transformar datos a formato largo para graficar
dat_long <- dat_penguins %>%
pivot_longer(cols = everything(), names_to = "Variable", values_to = "Valor")
# Boxplot de variables numéricas
ggplot(dat_long, aes(x = Variable, y = Valor, fill = Variable)) +
geom_boxplot() +
theme_minimal() +
labs(title = "Boxplot de medidas morfológicas en pingüinos")
# Gráfico de densidades
ggplot(dat_long, aes(x = Valor, fill = Variable)) +
geom_density(alpha = 0.5) +
facet_wrap(~Variable, scales = "free") +
theme_minimal() +
labs(title = "Densidad de las variables")
Análisis exploratorio: El resumen estadístico y los gráficos de caja muestran que las variables están en diferentes escalas de magnitud (la masa corporal se mide en miles de gramos, mientras que las medidas del pico en decenas de milímetros), lo que justifica el escalado previo de los datos para no sesgar el cálculo de las distancias. Adicionalmente, los gráficos de densidad muestran distribuciones bimodales o multimodales (como en la longitud de la aleta), lo que insinúa fuertemente la existencia de distintos subgrupos dentro de la población.
Genera la matriz y el gráfico multivariante inicial.
# Matriz de correlaciones
matriz_cor <- cor(dat_penguins)
corrplot(matriz_cor, method = "number", type = "upper", tl.col = "black")
# Gráfico de estrellas (muestra las primeras 30 observaciones para no saturar)
stars(dat_penguins_e[1:30, ], key.loc = c(10, 2), radius = TRUE,
main = "Morfología de pingüinos (Muestra)", draw.segments = TRUE, cex = 0.7)
Análisis de correlaciones y agrupaciones a priori: La matriz revela variables fuertemente correlacionadas de manera positiva, destacando una correlación muy alta entre la masa corporal y la longitud de la aleta. Por otro lado, el gráfico de estrellas muestra visualmente la formación de patrones morfológicos distintos; algunas observaciones presentan polígonos grandes y extendidos (individuos robustos), mientras que otros tienen formas puntiagudas dominadas por las dimensiones del pico, sugiriendo a priori la presencia de al menos tres morfologías diferentes.
# Matriz de distancias euclídeas
matdist <- get_dist(dat_penguins_e, method = "euclidean")
# Matriz de distancias euclídeas (sin etiquetas para que se vea limpio)
fviz_dist(matdist, gradient = list(low = "blue", mid = "white", high = "red"), show_labels = FALSE)
# Agrupamiento jerárquico (Método Ward)
chc <- hclust(matdist, method = "ward.D2")
# Dendrograma cortado en 3 grupos (coincide con el número de especies reales)
grups_jer <- cutree(chc, k = 3)
fviz_dend(x = chc, k = 3, rect = TRUE,
main = "Dendrograma - Pingüinos",
ylab = "Distancia",
k_colors = c("#2E9FDF", "#00AFBB", "#E7B800"))
Análisis del Dendrograma: Se empleó la distancia euclídea y el método de agrupamiento jerárquico de Ward (mínima varianza). Al observar el dendrograma, la decisión de cortar el árbol y retener 3 grupos se justifica porque los saltos más significativos en el eje de la distancia (eje vertical) ocurren justo antes de esta fusión. Esto asegura que los grupos internamente sean homogéneos y compactos, sin forzar la unión de individuos con diferencias morfológicas extremas.
# Biplot
pca_penguins <- prcomp(dat_penguins, scale. = TRUE)
fviz_pca_biplot(pca_penguins, repel = FALSE, geom = "point",
col.var = "red", col.ind = as.factor(grups_jer),
title = "Biplot de Observaciones y Variables")
Análisis del Biplot: Este gráfico permite visualizar la relación entre las observaciones y las variables originales dentro del espacio factorial. Se observa cómo los vectores de masa corporal y longitud de aleta tiran fuertemente de un grupo específico hacia la derecha, separándolo claramente del resto de las observaciones. Los otros dos grupos se diferencian principalmente sobre el eje vertical, influenciados por las proporciones del pico.
Determina el número de grupos y aplica el algoritmo K-means iterativo.
# Gráfico de sedimentación (Elbow Method)
fviz_nbclust(dat_penguins_e, kmeans, method = "wss") +
labs(title = "Método del Codo para K-means")
# Aplicar K-means con 3 grupos
set.seed(123)
km_penguins <- kmeans(dat_penguins_e, centers = 3, nstart = 25)
# Visualización de los grupos K-means
fviz_cluster(km_penguins, data = dat_penguins_e, geom = "point",
ellipse.type = "convex", main = "Clustering K-means")
Análisis de Conglomerados No Jerárquico: El gráfico de sedimentación (Elbow Method) presenta un cambio de pendiente evidente o “codo” en k=3, lo que justifica estadísticamente la selección de 3 clústeres para el modelo iterativo. Al aplicar K-means, los agrupamientos resultantes logran segmentar a la población en tres áreas bien definidas, confirmando la estabilidad matemática de los grupos encontrados en el método jerárquico.
Este es el cierre del proyecto donde comparas perfiles y consolidas los datos.
# Unir grupos a la base original
bd_final <- data.frame(dat_penguins,
Jerarquico = as.factor(grups_jer),
Kmeans = as.factor(km_penguins$cluster))
# Mostrar los primeros registros
head(bd_final)
## bill_length_mm bill_depth_mm flipper_length_mm body_mass_g Jerarquico Kmeans
## 1 39.1 18.7 181 3750 1 2
## 2 39.5 17.4 186 3800 1 2
## 3 40.3 18.0 195 3250 1 2
## 4 36.7 19.3 193 3450 1 2
## 5 39.3 20.6 190 3650 1 2
## 6 38.9 17.8 181 3625 1 2
# Resumen estadístico por grupo de K-means
resumen_km <- bd_final %>%
group_by(Kmeans) %>%
summarise(across(1:4, mean))
print(resumen_km)
## # A tibble: 3 × 5
## Kmeans bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
## <fct> <dbl> <dbl> <dbl> <dbl>
## 1 1 47.7 18.7 197. 3898.
## 2 2 38.3 18.1 189. 3594.
## 3 3 47.6 15.0 217. 5092.
# Boxplot comparativo por grupo
bd_final %>%
pivot_longer(cols = 1:4, names_to = "Variable", values_to = "Valor") %>%
ggplot(aes(x = Kmeans, y = Valor, fill = Kmeans)) +
geom_boxplot() +
facet_wrap(~Variable, scales = "free") +
labs(title = "Distribución de variables por grupo (K-means)")
# Gráfico de líneas y promedios por grupo (Perfiles)
resumen_km %>%
pivot_longer(cols = 2:5, names_to = "Variable", values_to = "Promedio") %>%
ggplot(aes(x = Variable, y = Promedio, color = Kmeans, group = Kmeans)) +
geom_line(size = 1.2) +
geom_point(size = 3) +
theme_minimal() +
labs(title = "Perfiles morfológicos de los Conglomerados",
y = "Promedio", x = "Variables")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once per session.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
Análisis de los clústeres formados: Al observar la
tabla de resumen estadístico y los diagramas de caja, se confirma que
K-means separó a los pingüinos en tres grupos con características
morfológicas estadísticamente distintas:
- El Grupo 3 destaca por agrupar a los individuos más
grandes y pesados de toda la muestra, superando a los demás en masa
corporal y longitud de aleta. Curiosamente, son los que tienen el pico
menos profundo.
- El Grupo 2 concentra a los pingüinos más pequeños,
con la menor masa corporal, aletas más cortas y, de forma muy
distintiva, los picos más cortos.
- El Grupo 1 se ubica en un punto intermedio en cuanto
a peso y tamaño de aleta, pero comparte con el Grupo 3 la característica
de tener un pico largo y, simultáneamente, comparte con el Grupo 2 una
gran profundidad de pico.
Conclusión General y Perfiles Morfológicos: El
análisis multivariado demostró que las variables seleccionadas son
suficientes para segmentar la base de datos en tres conglomerados
consistentes. El gráfico de líneas nos permite definir los perfiles
finales de la siguiente manera:
- Perfil 1 (Pingüinos de pico grande y tamaño medio):
Individuos con un peso promedio de 3,898 g. Su rasgo más distintivo es
que tienen picos grandes en ambas dimensiones (largos y
profundos).
- Perfil 2 (Pingüinos pequeños y de pico corto): Es la
población de menor tamaño (promedio de 3,594 g) y aletas cortas (189
mm). Su morfología se define claramente por poseer los picos más cortos
de toda la muestra (38.3 mm).
- Perfil 3 (Pingüinos robustos): Son los individuos más
masivos (5,092 g) y con mayor envergadura de aleta (217 mm). Aunque su
pico es alargado, es el más estrecho o menos profundo (15.0 mm). Estos
tres perfiles estadísticos descubiertos por los algoritmos responden
directamente al objetivo inicial del estudio, comprobando que las
diferencias morfológicas logran agrupar naturalmente a la población
analizada.