El PCA se ha realizado con el propósito de reducir la complejidad de los datos inmobiliarios y destacar las características más influyentes que determinan los precios y la oferta en el mercado de las viviendas en la base de datos. Las cargas de los componentes indican que tanto las características físicas de las propiedades como ciertos indicadores de estatus, como el estrato, juegan roles significativos en la variabilidad de los datos.
El PCA proporciona una visión profunda de las dinámicas del mercado inmobiliario urbano. Los componentes identificados aquí presentados pueden guiar la toma de decisiones estratégicas para optimizar las inversiones.
# Instalación de paquetes (solo una vez)
install.packages("learnr")
install.packages("devtools")
devtools::install_github("dgonxalex80/paqueteMODELOS") # descarga paquete
# Carga de bibliotecas
library(paqueteMODELOS)
library(dplyr)
library(factoextra)
library(mice)
library(ggplot2)
library(ggrepel)
library(tidyverse)
library(cluster)
library(tibble)
# Carga de datos
data(vivienda)
str(vivienda)
# Verificar patrones de datos faltantes
md.pattern(vivienda)
# Calcular la cantidad de datos faltantes por cada variable
missing_values <- sapply(vivienda, function(x) sum(is.na(x)))
# Imprimir los valores faltantes por variable
print(missing_values)
# Eliminar filas con datos faltantes en las variables especificadas
vivienda_clean <- vivienda[!rowSums(is.na(vivienda[c("zona", "estrato", "areaconst",
"banios", "habitaciones", "tipo",
"barrio", "longitud", "latitud")])), ]
# Verificar patrones de datos faltantes
md.pattern(vivienda_clean)
# Seleccionar las variables numéricas para el PCA (excluyendo la primera columna 'id')
viviendaZ <- vivienda_clean %>%
select(estrato, areaconst, banios, habitaciones, preciom) %>%
scale()
# Ver los primeros registros de los datos estandarizados
head(viviendaZ)
# Aplicar PCA
pca_resultado <- prcomp(viviendaZ)
# Ver las desviaciones estándar de los componentes
pca_resultado$sdev
# Ver la matriz de rotación
pca_resultado$rotation
# Utilizar los resultados de tu PCA
# Asumiendo que ya has ejecutado pca_resultado <- prcomp(viviendaZ)
# Crear el gráfico de sedimentación (scree plot)
fviz_eig(pca_resultado, addlabels = TRUE)
# Visualizar la contribución de las variables a los componentes principales
fviz_pca_var(pca_resultado,
col.var = "contrib", # Colorear por contribuciones al componente principal
gradient.cols = c("#FF7F00", "#034D94"), # Colores para el gradiente
repel = TRUE # Evitar solapamiento de texto
)
# Asegúrate de que tienes los índices de los valores máximos y mínimos para 'preciom', 'areaconst', 'banios' y 'habitaciones'
max_preciom_idx <- which.max(vivienda_clean$preciom)
min_preciom_idx <- which.min(vivienda_clean$preciom)
max_areaconst_idx <- which.max(vivienda_clean$areaconst)
min_areaconst_idx <- which.min(vivienda_clean$areaconst)
max_banios_idx <- which.max(vivienda_clean$banios)
min_banios_idx <- which.min(vivienda_clean$banios)
max_habitaciones_idx <- which.max(vivienda_clean$habitaciones)
min_habitaciones_idx <- which.min(vivienda_clean$habitaciones)
# Crear un data frame con las coordenadas PCA y la etiqueta de la variable correspondiente a cada punto extremo
extremos_pca <- data.frame(
PC1 = pca_resultado$x[c(max_preciom_idx, min_preciom_idx, max_areaconst_idx, min_areaconst_idx,
max_banios_idx, min_banios_idx, max_habitaciones_idx, min_habitaciones_idx), 1],
PC2 = pca_resultado$x[c(max_preciom_idx, min_preciom_idx, max_areaconst_idx, min_areaconst_idx,
max_banios_idx, min_banios_idx, max_habitaciones_idx, min_habitaciones_idx), 2],
label = c("Max Preciom", "Min Preciom", "Max Areaconst", "Min Areaconst",
"Max Banios", "Min Banios", "Max Habitaciones", "Min Habitaciones")
)
# Crear el gráfico de PCA con etiquetas para los puntos extremos
p <- fviz_pca_ind(pca_resultado,
geom.ind = "point",
col.ind = "grey80",
alpha.ind = 0.5,
pointsize = 1,
repel = FALSE) +
geom_point(data = extremos_pca, aes(x = PC1, y = PC2, color = label), size = 4) +
scale_color_manual(values = c("Max Preciom" = "blue", "Min Preciom" = "blue",
"Max Areaconst" = "red", "Min Areaconst" = "red",
"Max Banios" = "green", "Min Banios" = "green",
"Max Habitaciones" = "purple", "Min Habitaciones" = "purple")) +
geom_label_repel(data = extremos_pca, aes(x = PC1, y = PC2, label = label, fill = label),
size = 3.5, box.padding = 0.35, point.padding = 0.5,
segment.color = 'grey50') +
theme_minimal() +
theme(legend.position = "none")
# Guardar el gráfico en un archivo PDF
ggsave("pca_plot_extremos_completo.pdf", plot = p, width = 12, height = 10)
El análisis de clustering se ha llevado a cabo para identificar segmentos distintos dentro del mercado inmobiliario urbano, utilizando un enfoque de K-Means para agrupar propiedades con características similares. El proceso ha revelado tres clusters principales que diferencian las propiedades en términos de estrato socioeconómico, precio y ubicación, ofreciendo una perspectiva clara sobre las dinámicas del mercado.
El análisis de clustering ha demostrado ser una herramienta valiosa para entender la segmentación del mercado inmobiliario urbano. Los resultados derivados de este estudio pueden guiar las decisiones estratégicas en diversas áreas, desde el marketing hasta el desarrollo y la inversión inmobiliaria, asegurando que se aborden de manera efectiva las necesidades y preferencias de cada segmento de mercado identificado.
# Paso 1: Cálculo de Distancias
dist_vivienda <- dist(viviendaZ, method = 'euclidean')
# Paso 2: Clustering Jerárquico
hc_vivienda <- hclust(dist_vivienda, method = 'complete')
# Visualización del dendrograma
plot(hc_vivienda, cex = 0.6, main = "Dendrograma de Propiedades Residenciales")
#Dado que no existe una adecuada visualización con el denograma en donde se permite identificar un grupo adecuado de clusters se hará un análisis no jerárquico con K means y el número de clusters se decidirá con el método del codo
# Calculamos K-Means para un rango de valores de k y almacenamos la suma de cuadrados dentro de los grupos (total within-cluster sum of squares)
wss <- sapply(1:10, function(k){
kmeans(viviendaZ, centers = k, nstart = 25)$tot.withinss
})
# Graficamos el método del codo
plot(1:10, wss, type = "b", pch = 19, frame = FALSE,
xlab="Número de clústeres K",
ylab="Total dentro de la suma de cuadrados (WSS)")
# Usamos fviz_nbclust para una mejor visualización
fviz_nbclust(viviendaZ, kmeans, method = "wss")
# Ejecutar K-Means con 3 clústeres
set.seed(123) # Asegura la reproducibilidad
kmeans_result_3 <- kmeans(viviendaZ, centers = 3, nstart = 25)
# Calcular los coeficientes de Silhouette para las asignaciones de clúster de K-Means con 3 clústeres
silhouette_scores_3 <- silhouette(kmeans_result_3$cluster, dist(viviendaZ))
# Visualizar los coeficientes de Silhouette para 3 clústeres
fviz_silhouette(silhouette_scores_3) + theme_minimal()
# Ejecutar K-Means con 4 clústeres
set.seed(123) # Asegura la reproducibilidad
kmeans_result <- kmeans(viviendaZ, centers = 4, nstart = 25)
# Calcular los coeficientes de Silhouette para las asignaciones de clúster de K-Means
silhouette_scores <- silhouette(kmeans_result$cluster, dist(viviendaZ))
# Visualizar los coeficientes de Silhouette
fviz_silhouette(silhouette_scores) + theme_minimal()
# Ejecutar K-Means con 5 clústeres
set.seed(123) # Asegura la reproducibilidad
kmeans_result_5 <- kmeans(viviendaZ, centers = 5, nstart = 25)
# Calcular los coeficientes de Silhouette para las asignaciones de clúster de K-Means con 5 clústeres
silhouette_scores_5 <- silhouette(kmeans_result_5$cluster, dist(viviendaZ))
# Visualizar los coeficientes de Silhouette para 5 clústeres
fviz_silhouette(silhouette_scores_5) + theme_minimal()
# Ejecutar K-Means con 2 clústeres
set.seed(123) # Asegura la reproducibilidad
kmeans_result_2 <- kmeans(viviendaZ, centers = 2, nstart = 25)
# Calcular los coeficientes de Silhouette para las asignaciones de clúster de K-Means con 5 clústeres
silhouette_scores_2 <- silhouette(kmeans_result_2$cluster, dist(viviendaZ))
# Visualizar los coeficientes de Silhouette para 5 clústeres
fviz_silhouette(silhouette_scores_2) + theme_minimal()
# Calcular criterios para 2 clústeres
k2 <- 2
set.seed(123) # Asegura la reproducibilidad
kmeans_result <- kmeans(viviendaZ, centers = k2, nstart = 25)
# Calcular la Suma de Cuadrados Dentro del Cluster (SSC)
ssc <- kmeans_result$tot.withinss
# Calcular la Suma de Cuadrados Entre Clusters (SSB)
sst <- sum(apply(viviendaZ, 2, var)) * (nrow(viviendaZ) - 1)
ssb <- sst - ssc
# Imprimir los resultados
cat("SSC:", ssc, "\n")
cat("SSB:", ssb, "\n")
# Calcular criterios para 3 clústeres
k3 <- 3
set.seed(123) # Asegura la reproducibilidad
kmeans_result <- kmeans(viviendaZ, centers = k3, nstart = 25)
# Calcular la Suma de Cuadrados Dentro del Cluster (SSC)
ssc <- kmeans_result$tot.withinss
# Calcular la Suma de Cuadrados Entre Clusters (SSB)
sst <- sum(apply(viviendaZ, 2, var)) * (nrow(viviendaZ) - 1)
ssb <- sst - ssc
# Imprimir los resultados
cat("SSC:", ssc, "\n")
cat("SSB:", ssb, "\n")
# Calcular criterios para 4 clústeres
k4 <- 4
set.seed(123) # Asegura la reproducibilidad
kmeans_result <- kmeans(viviendaZ, centers = k4, nstart = 25)
# Calcular la Suma de Cuadrados Dentro del Cluster (SSC)
ssc <- kmeans_result$tot.withinss
# Calcular la Suma de Cuadrados Entre Clusters (SSB)
sst <- sum(apply(viviendaZ, 2, var)) * (nrow(viviendaZ) - 1)
ssb <- sst - ssc
# Imprimir los resultados
cat("SSC:", ssc, "\n")
cat("SSB:", ssb, "\n")
# Calcular criterios para 5 clústeres
k5 <- 5
set.seed(123) # Asegura la reproducibilidad
kmeans_result <- kmeans(viviendaZ, centers = k5, nstart = 25)
# Calcular la Suma de Cuadrados Dentro del Cluster (SSC)
ssc <- kmeans_result$tot.withinss
# Calcular la Suma de Cuadrados Entre Clusters (SSB)
sst <- sum(apply(viviendaZ, 2, var)) * (nrow(viviendaZ) - 1)
ssb <- sst - ssc
#Se decide basandose en todo esto que es mejor 3 clusters
# Elegir el número de clústeres
num_clusters <- 3
# Realizar el clustering K-Means utilizando las dos primeras componentes principales
kmeans_resultado <- kmeans(pca_resultado$x[, 1:2], centers = num_clusters)
# Asignar las etiquetas de clúster al conjunto de datos original
vivienda_clean$cluster <- as.factor(kmeans_resultado$cluster)
# Visualizar los resultados del clustering en un gráfico
fviz_cluster(kmeans_resultado, data = pca_resultado$x[, 1:2])
# Mostrar un resumen de los clústeres
summary(vivienda_clean$cluster)
# Estadísticas para variables numéricas
estadisticas_num <- vivienda_clean %>%
group_by(cluster) %>%
summarise(across(where(is.numeric), list(mean = mean, median = median, sd = sd)))
# Estadísticas para variables categóricas
estadisticas_cat <- vivienda_clean %>%
group_by(cluster) %>%
summarise(across(where(is.character), ~names(sort(table(.)[length(table(.)):1])[1])))
# Mostrar resultados
print(estadisticas_num)
print(estadisticas_cat)
# Calcular estadísticas descriptivas para variables numéricas
estadisticas_num <- vivienda_clean %>%
group_by(cluster) %>%
summarise(across(where(is.numeric), list(mean = mean, median = median, sd = sd)))
# Calcular estadísticas descriptivas para variables categóricas
estadisticas_cat <- vivienda_clean %>%
group_by(cluster) %>%
summarise(across(where(is.character), ~names(sort(table(.)[length(table(.)):1])[1])))
# Combinar las estadísticas en una sola tabla
tabla_resumen <- left_join(estadisticas_num, estadisticas_cat, by = "cluster")
# Corregir el nombre de las columnas en 'select' si es necesario
tabla_final <- tabla_resumen %>%
select(cluster, estrato_mean, preciom_mean, tipo, zona, barrio) %>%
rename("Estrato Medio" = estrato_mean,
"Precio Medio" = preciom_mean,
"Tipo de Propiedad Más Común" = tipo,
"Zona Más Común" = zona,
"Barrio Más Común" = barrio)
# Ver la tabla final
print(tabla_final)
install.packages("sf")
library(sf)
# Asegúrate de que vivienda_clean tenga las columnas latitud, longitud y cluster
# Aquí se asume que las columnas se llaman 'latitud', 'longitud' y 'cluster'
ggplot(data = vivienda_clean) +
geom_sf(data = st_as_sf(vivienda_clean, coords = c("longitud", "latitud"), crs = 4326),
aes(color = factor(cluster))) +
theme_minimal() +
labs(title = "Distribución Geográfica de Clusters de Propiedades",
x = "Longitud",
y = "Latitud",
color = "Cluster") +
coord_sf() # Utiliza esto si tus datos ya están en un sistema de coordenadas geográficas
El Análisis de Correspondencia (AC) se ha ejecutado para profundizar en la comprensión de las interacciones entre diferentes categorías de las propiedades inmobiliarias, específicamente en relación con la zona, el estrato y el tipo de vivienda. Esta técnica multivariante proporciona una visualización adecuada de cómo estas categorías categóricas se relacionan entre sí, revelando patrones subyacentes en el mercado inmobiliario urbano que antes no eran fácilmente observables.
El Análisis de Correspondencia ha proporcionado una valiosa representación visual de las complejas relaciones entre las variables categóricas en el mercado inmobiliario. Estos resultados pueden informar estrategias de negocio más efectivas, alineando las ofertas de propiedades con los patrones específicos y las preferencias de los consumidores revelados a través del análisis.
# Convertir las variables en factores
vivienda_clean$estrato <- as.factor(vivienda_clean$estrato)
vivienda_clean$zona <- as.factor(vivienda_clean$zona)
vivienda_clean$tipo <- as.factor(vivienda_clean$tipo)
# Cargar el paquete mice y revisar los datos faltantes
md.pattern(vivienda_clean, rotate.names = TRUE)
# Crear una tabla de contingencia con tres variables
tabla_multidimensional <- table(vivienda_clean$zona, vivienda_clean$estrato, vivienda_clean$tipo)
# Ver la tabla de contingencia multidimensional
print(tabla_multidimensional)
# Realizar un Análisis de Correspondencia Múltiple (ACM)
# Cargar los paquetes necesarios
library(FactoMineR)
library(factoextra)
# Cargar el paquete FactoMineR para el análisis y factoextra para visualización
library(FactoMineR)
library(factoextra)
# Realizar el Análisis de Correspondencia Múltiple (ACM)
acm_resultado <- MCA(vivienda_clean, graph = FALSE)
# Crear el gráfico con los ajustes deseados
mca_biplot <- fviz_mca_biplot(acm_resultado,
col.var = "red", # Color para las categorías de las variables
col.ind = "grey", # Color para los individuos
alpha.ind = 0.5, # Transparencia para los individuos
repel = TRUE, # Evitar solapamiento de etiquetas
gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), # Colores para los ejes
theme = theme_minimal() # Tema minimalista para el gráfico
) +
theme(legend.position = "bottom") # Mover la leyenda abajo
# Guardar el gráfico en un archivo PNG
ggsave("mca_biplot.png", mca_biplot, width = 12, height = 8, units = "in")
#FIN