Este documento presenta un análisis exploratorio detallado del
dataset Boston, contenido en el paquete
MASS. El conjunto de datos contiene información sobre 506
suburbios de Boston, recopilada por el Servicio de Censo de Estados
Unidos, y es ampliamente utilizado para estudiar la relación entre
características socioeconómicas y el valor de las viviendas.
El objetivo de este análisis es comprender la estructura, distribución y relaciones entre las variables mediante técnicas estadísticas descriptivas y visualizaciones.
Cargamos los paquetes necesarios para el análisis. Utilizamos
pacman para gestionar las librerías de manera
eficiente.
# Instalar pacman si es necesario
if (!require(pacman)) install.packages("pacman")
# Cargar y/o instalar paquetes
library(pacman)
p_load(
MASS, # Contiene el dataset Boston
tidyverse, # Manipulación y visualización
GGally, # Matriz de correlación extendida
skimr, # Resúmenes estadísticos completos
gridExtra, # Organizar múltiples gráficos
corrplot # Visualización de correlaciones
)
# Cargar el dataset
data("Boston")
# Dimensiones del dataset
cat("Dimensiones del dataset:", dim(Boston)[1], "filas y", dim(Boston)[2], "columnas\n")
## Dimensiones del dataset: 506 filas y 14 columnas
# Estructura de los datos
str(Boston)
## 'data.frame': 506 obs. of 14 variables:
## $ crim : num 0.00632 0.02731 0.02729 0.03237 0.06905 ...
## $ zn : num 18 0 0 0 0 0 12.5 12.5 12.5 12.5 ...
## $ indus : num 2.31 7.07 7.07 2.18 2.18 2.18 7.87 7.87 7.87 7.87 ...
## $ chas : int 0 0 0 0 0 0 0 0 0 0 ...
## $ nox : num 0.538 0.469 0.469 0.458 0.458 0.458 0.524 0.524 0.524 0.524 ...
## $ rm : num 6.58 6.42 7.18 7 7.15 ...
## $ age : num 65.2 78.9 61.1 45.8 54.2 58.7 66.6 96.1 100 85.9 ...
## $ dis : num 4.09 4.97 4.97 6.06 6.06 ...
## $ rad : int 1 2 2 3 3 3 5 5 5 5 ...
## $ tax : num 296 242 242 222 222 222 311 311 311 311 ...
## $ ptratio: num 15.3 17.8 17.8 18.7 18.7 18.7 15.2 15.2 15.2 15.2 ...
## $ black : num 397 397 393 395 397 ...
## $ lstat : num 4.98 9.14 4.03 2.94 5.33 ...
## $ medv : num 24 21.6 34.7 33.4 36.2 28.7 22.9 27.1 16.5 18.9 ...
Interpretación: - 506
observaciones: Representan diferentes zonas censales o
suburbios de Boston. - 14 variables: Incluyen
características como tasa de criminalidad, proporción de áreas
residenciales, número de habitaciones, etc. - La mayoría de las
variables son numéricas (num), mientras que
chas (colindancia con el río Charles) e rad
(accesibilidad a autopistas) son enteros (int).
# Mostrar las primeras 6 filas
head(Boston) %>%
knitr::kable(caption = "Primeras 6 observaciones del dataset Boston")
| crim | zn | indus | chas | nox | rm | age | dis | rad | tax | ptratio | black | lstat | medv |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0.00632 | 18 | 2.31 | 0 | 0.538 | 6.575 | 65.2 | 4.0900 | 1 | 296 | 15.3 | 396.90 | 4.98 | 24.0 |
| 0.02731 | 0 | 7.07 | 0 | 0.469 | 6.421 | 78.9 | 4.9671 | 2 | 242 | 17.8 | 396.90 | 9.14 | 21.6 |
| 0.02729 | 0 | 7.07 | 0 | 0.469 | 7.185 | 61.1 | 4.9671 | 2 | 242 | 17.8 | 392.83 | 4.03 | 34.7 |
| 0.03237 | 0 | 2.18 | 0 | 0.458 | 6.998 | 45.8 | 6.0622 | 3 | 222 | 18.7 | 394.63 | 2.94 | 33.4 |
| 0.06905 | 0 | 2.18 | 0 | 0.458 | 7.147 | 54.2 | 6.0622 | 3 | 222 | 18.7 | 396.90 | 5.33 | 36.2 |
| 0.02985 | 0 | 2.18 | 0 | 0.458 | 6.430 | 58.7 | 6.0622 | 3 | 222 | 18.7 | 394.12 | 5.21 | 28.7 |
skimrskim(Boston)
| Name | Boston |
| Number of rows | 506 |
| Number of columns | 14 |
| _______________________ | |
| Column type frequency: | |
| numeric | 14 |
| ________________________ | |
| Group variables | None |
Variable type: numeric
| skim_variable | n_missing | complete_rate | mean | sd | p0 | p25 | p50 | p75 | p100 | hist |
|---|---|---|---|---|---|---|---|---|---|---|
| crim | 0 | 1 | 3.61 | 8.60 | 0.01 | 0.08 | 0.26 | 3.68 | 88.98 | ▇▁▁▁▁ |
| zn | 0 | 1 | 11.36 | 23.32 | 0.00 | 0.00 | 0.00 | 12.50 | 100.00 | ▇▁▁▁▁ |
| indus | 0 | 1 | 11.14 | 6.86 | 0.46 | 5.19 | 9.69 | 18.10 | 27.74 | ▇▆▁▇▁ |
| chas | 0 | 1 | 0.07 | 0.25 | 0.00 | 0.00 | 0.00 | 0.00 | 1.00 | ▇▁▁▁▁ |
| nox | 0 | 1 | 0.55 | 0.12 | 0.38 | 0.45 | 0.54 | 0.62 | 0.87 | ▇▇▆▅▁ |
| rm | 0 | 1 | 6.28 | 0.70 | 3.56 | 5.89 | 6.21 | 6.62 | 8.78 | ▁▂▇▂▁ |
| age | 0 | 1 | 68.57 | 28.15 | 2.90 | 45.02 | 77.50 | 94.07 | 100.00 | ▂▂▂▃▇ |
| dis | 0 | 1 | 3.80 | 2.11 | 1.13 | 2.10 | 3.21 | 5.19 | 12.13 | ▇▅▂▁▁ |
| rad | 0 | 1 | 9.55 | 8.71 | 1.00 | 4.00 | 5.00 | 24.00 | 24.00 | ▇▂▁▁▃ |
| tax | 0 | 1 | 408.24 | 168.54 | 187.00 | 279.00 | 330.00 | 666.00 | 711.00 | ▇▇▃▁▇ |
| ptratio | 0 | 1 | 18.46 | 2.16 | 12.60 | 17.40 | 19.05 | 20.20 | 22.00 | ▁▃▅▅▇ |
| black | 0 | 1 | 356.67 | 91.29 | 0.32 | 375.38 | 391.44 | 396.22 | 396.90 | ▁▁▁▁▇ |
| lstat | 0 | 1 | 12.65 | 7.14 | 1.73 | 6.95 | 11.36 | 16.96 | 37.97 | ▇▇▅▂▁ |
| medv | 0 | 1 | 22.53 | 9.20 | 5.00 | 17.02 | 21.20 | 25.00 | 50.00 | ▂▇▅▁▁ |
Observaciones clave del resumen: - La variable
tax (tasa de impuesto a la propiedad) presenta la mayor
dispersión, con valores entre 187 y 711. - crim (tasa de
criminalidad) está altamente sesgada: la media es 3.61, pero la mediana
es solo 0.256, indicando la presencia de valores extremos. -
medv (valor mediano de viviendas) tiene un máximo de 50,
que podría ser un valor censurado (techado).
summary(Boston) %>%
knitr::kable(caption = "Resumen estadístico de las 14 variables")
| crim | zn | indus | chas | nox | rm | age | dis | rad | tax | ptratio | black | lstat | medv | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Min. : 0.00632 | Min. : 0.00 | Min. : 0.46 | Min. :0.00000 | Min. :0.3850 | Min. :3.561 | Min. : 2.90 | Min. : 1.130 | Min. : 1.000 | Min. :187.0 | Min. :12.60 | Min. : 0.32 | Min. : 1.73 | Min. : 5.00 | |
| 1st Qu.: 0.08205 | 1st Qu.: 0.00 | 1st Qu.: 5.19 | 1st Qu.:0.00000 | 1st Qu.:0.4490 | 1st Qu.:5.886 | 1st Qu.: 45.02 | 1st Qu.: 2.100 | 1st Qu.: 4.000 | 1st Qu.:279.0 | 1st Qu.:17.40 | 1st Qu.:375.38 | 1st Qu.: 6.95 | 1st Qu.:17.02 | |
| Median : 0.25651 | Median : 0.00 | Median : 9.69 | Median :0.00000 | Median :0.5380 | Median :6.208 | Median : 77.50 | Median : 3.207 | Median : 5.000 | Median :330.0 | Median :19.05 | Median :391.44 | Median :11.36 | Median :21.20 | |
| Mean : 3.61352 | Mean : 11.36 | Mean :11.14 | Mean :0.06917 | Mean :0.5547 | Mean :6.285 | Mean : 68.57 | Mean : 3.795 | Mean : 9.549 | Mean :408.2 | Mean :18.46 | Mean :356.67 | Mean :12.65 | Mean :22.53 | |
| 3rd Qu.: 3.67708 | 3rd Qu.: 12.50 | 3rd Qu.:18.10 | 3rd Qu.:0.00000 | 3rd Qu.:0.6240 | 3rd Qu.:6.623 | 3rd Qu.: 94.08 | 3rd Qu.: 5.188 | 3rd Qu.:24.000 | 3rd Qu.:666.0 | 3rd Qu.:20.20 | 3rd Qu.:396.23 | 3rd Qu.:16.95 | 3rd Qu.:25.00 | |
| Max. :88.97620 | Max. :100.00 | Max. :27.74 | Max. :1.00000 | Max. :0.8710 | Max. :8.780 | Max. :100.00 | Max. :12.127 | Max. :24.000 | Max. :711.0 | Max. :22.00 | Max. :396.90 | Max. :37.97 | Max. :50.00 |
Seleccionamos tres variables fundamentales para un análisis detallado: - medv: Valor mediano de viviendas ocupadas por propietarios (en miles de USD). - rm: Número promedio de habitaciones por vivienda. - lstat: Porcentaje de población con estatus socioeconómico bajo.
# Preparar datos para histogramas
Boston_long <- Boston %>%
select(medv, rm, lstat) %>%
pivot_longer(cols = everything(),
names_to = "variable",
values_to = "valor")
# Crear histogramas
ggplot(Boston_long, aes(x = valor, fill = variable)) +
geom_histogram(color = "white", bins = 20, alpha = 0.7) +
facet_wrap(~variable, scales = "free", ncol = 1) +
scale_fill_manual(values = c(medv = "#2E86AB", rm = "#A23B72", lstat = "#F18F01")) +
labs(title = "Distribución de Variables Clave",
subtitle = "Histogramas de frecuencia",
x = "Valor", y = "Frecuencia") +
theme_minimal() +
theme(legend.position = "none",
strip.text = element_text(size = 12, face = "bold"))
Análisis de distribuciones:
medv (Valor de viviendas): Distribución asimétrica positiva, con una concentración de valores en torno a 20-24 mil USD. Se observa un pico en el valor máximo de 50, sugiriendo posible censura de datos.
rm (Habitaciones): Aproximadamente normal, centrada alrededor de 6.2 habitaciones. La mayoría de las viviendas tienen entre 5 y 7 habitaciones.
lstat (Estatus bajo): Distribución asimétrica positiva, con mayoría de zonas con bajo porcentaje de población de estatus bajo (<10%), pero con una cola larga hacia valores altos.
# Histograma individual de medv
p1 <- ggplot(Boston, aes(x = medv)) +
geom_histogram(fill = "#2E86AB", color = "white", bins = 25) +
labs(title = "Distribución de medv",
x = "Valor mediano de viviendas (miles USD)",
y = "Frecuencia") +
theme_minimal()
# Histograma individual de rm
p2 <- ggplot(Boston, aes(x = rm)) +
geom_histogram(fill = "#A23B72", color = "white", bins = 25) +
labs(title = "Distribución de rm",
x = "Número promedio de habitaciones",
y = "Frecuencia") +
theme_minimal()
# Histograma individual de lstat
p3 <- ggplot(Boston, aes(x = lstat)) +
geom_histogram(fill = "#F18F01", color = "white", bins = 25) +
labs(title = "Distribución de lstat",
x = "Porcentaje de población con estatus bajo",
y = "Frecuencia") +
theme_minimal()
# Organizar gráficos
grid.arrange(p1, p2, p3, ncol = 3)
# Boxplots comparativos
ggplot(Boston_long, aes(x = variable, y = valor, fill = variable)) +
geom_boxplot(alpha = 0.8, outlier.color = "red", outlier.shape = 16, outlier.size = 2) +
scale_fill_manual(values = c(medv = "#2E86AB", rm = "#A23B72", lstat = "#F18F01")) +
labs(title = "Diagramas de Caja: medv, rm y lstat",
subtitle = "Comparación de dispersión y valores atípicos",
x = "Variable", y = "Valor") +
theme_minimal() +
theme(legend.position = "none")
Observaciones de los boxplots:
Para entender las relaciones entre variables, seleccionamos un conjunto de 5 variables clave: - medv: Variable respuesta (valor de viviendas) - crim: Tasa de criminalidad - lstat: Porcentaje de estatus bajo - rm: Número de habitaciones - tax: Tasa de impuestos
# Seleccionar variables
vars_seleccionadas <- Boston %>%
select(medv, crim, lstat, rm, tax)
# Calcular matriz de correlación
matriz_cor <- cor(vars_seleccionadas)
# Visualizar con corrplot
corrplot(matriz_cor,
method = "color",
type = "upper",
order = "hclust",
tl.col = "black",
tl.srt = 45,
addCoef.col = "black",
number.cex = 0.8,
col = colorRampPalette(c("#BB4444", "#EE9988", "#FFFFFF", "#77AADD", "#4477AA"))(200),
title = "Matriz de Correlación - Variables Seleccionadas",
mar = c(0,0,2,0))
# Gráficos de dispersión con medv como variable respuesta
Boston %>%
select(medv, crim, lstat, rm, tax) %>%
pivot_longer(cols = -medv,
names_to = "predictor",
values_to = "valor") %>%
ggplot(aes(x = valor, y = medv)) +
geom_point(alpha = 0.5, color = "#2E86AB", size = 1.5) +
geom_smooth(method = "lm", se = TRUE, color = "#A23B72", fill = "#F18F01", alpha = 0.2) +
facet_wrap(~predictor, scales = "free_x", ncol = 2) +
labs(title = "Relación entre medv y Variables Predictoras",
subtitle = "Cada punto representa un suburbio. Línea azul: tendencia lineal con IC 95%",
x = "Valor del predictor", y = "medv (miles USD)") +
theme_minimal() +
theme(strip.text = element_text(size = 11, face = "bold"))
Boston %>%
select(rm, medv, lstat, crim, tax) %>%
pivot_longer(cols = -rm,
names_to = "variable",
values_to = "valor") %>%
ggplot(aes(x = valor, y = rm)) +
geom_point(alpha = 0.5, color = "#A23B72", size = 1.5) +
geom_smooth(method = "lm", se = TRUE, color = "#2E86AB", fill = "#F18F01", alpha = 0.2) +
facet_wrap(~variable, scales = "free_x", ncol = 2) +
labs(title = "Relación entre rm (Habitaciones) y Otras Variables",
x = "Valor de la variable", y = "rm (número de habitaciones)") +
theme_minimal()
Boston %>%
select(lstat, medv, rm, crim, tax) %>%
pivot_longer(cols = -lstat,
names_to = "variable",
values_to = "valor") %>%
ggplot(aes(x = valor, y = lstat)) +
geom_point(alpha = 0.5, color = "#F18F01", size = 1.5) +
geom_smooth(method = "lm", se = TRUE, color = "#A23B72", fill = "#2E86AB", alpha = 0.2) +
facet_wrap(~variable, scales = "free_x", ncol = 2) +
labs(title = "Relación entre lstat (Estatus Bajo) y Otras Variables",
x = "Valor de la variable", y = "lstat (%)") +
theme_minimal()
Boston %>%
select(crim, medv, rm, lstat, tax) %>%
pivot_longer(cols = -crim,
names_to = "variable",
values_to = "valor") %>%
ggplot(aes(x = valor, y = crim)) +
geom_point(alpha = 0.5, color = "#D55E00", size = 1.5) +
geom_smooth(method = "loess", se = TRUE, color = "#2E86AB", fill = "#F18F01", alpha = 0.2) +
facet_wrap(~variable, scales = "free_x", ncol = 2) +
labs(title = "Relación entre crim (Criminalidad) y Otras Variables",
x = "Valor de la variable", y = "crim (tasa de criminalidad)") +
theme_minimal()
Boston %>%
select(tax, medv, rm, lstat, crim) %>%
pivot_longer(cols = -tax,
names_to = "variable",
values_to = "valor") %>%
ggplot(aes(x = valor, y = tax)) +
geom_point(alpha = 0.5, color = "#009E73", size = 1.5) +
geom_smooth(method = "lm", se = TRUE, color = "#A23B72", fill = "#F18F01", alpha = 0.2) +
facet_wrap(~variable, scales = "free_x", ncol = 2) +
labs(title = "Relación entre tax (Impuestos) y Otras Variables",
x = "Valor de la variable", y = "tax (tasa impositiva)") +
theme_minimal()
| Relación | Tipo | Fuerza | Interpretación |
|---|---|---|---|
| rm ↔︎ medv | Positiva | Fuerte | A más habitaciones, mayor valor de vivienda |
| lstat ↔︎ medv | Negativa | Fuerte | Mayor porcentaje de estatus bajo reduce el valor |
| crim ↔︎ medv | Negativa | Moderada | Alta criminalidad se asocia con menor valor |
| tax ↔︎ medv | Negativa | Débil | Impuestos altos ligeramente asociados a menor valor |
| rm ↔︎ lstat | Negativa | Moderada | Zonas con menos habitaciones tienen más población de estatus bajo |
| lstat ↔︎ crim | Positiva | Moderada | Zonas con más pobreza tienen más criminalidad |
Este análisis exploratorio proporciona una base sólida para comprender la estructura del dataset Boston y las relaciones fundamentales entre sus variables, sirviendo como punto de partida para modelados estadísticos más complejos. ```