El análisis de componentes principales (PCA) se ha llevado a cabo para simplificar los datos relacionados con el mercado inmobiliario, identificando las características clave que influyen en los precios y la oferta de viviendas presentes en la base de datos. Los pesos de los componentes revelan que tanto las propiedades físicas de los inmuebles como algunos indicadores de estatus, como el nivel socioeconómico, tienen una influencia considerable en la variabilidad observada en los datos.
El análisis de componentes principales (PCA) ha revelado aspectos clave sobre las dinámicas del mercado inmobiliario urbano, proporcionando una visión detallada de los factores que más influyen en la valoración y demanda de propiedades. Los componentes identificados en este análisis no solo ayudan a comprender mejor el mercado, sino que también ofrecen una base sólida para tomar decisiones estratégicas más informadas. Estas decisiones pueden abarcar desde el desarrollo y la comercialización de nuevos proyectos inmobiliarios hasta la segmentación precisa del mercado. Al aplicar estos conocimientos, es posible optimizar las inversiones y mejorar la alineación de las ofertas con las necesidades y preferencias de los consumidores, lo que en última instancia puede conducir a un mayor éxito en un mercado competitivo.
# Instalación de paquetes (solo una vez)
install.packages("learnr")
install.packages("devtools")
devtools::install_github("dgonxalex80/paqueteMODELOS") # descarga paquete
install.packages("factoextra")
install.packages("mice")
# 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", "#034D22"), # 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
# Renombrar las variables en extremos_pca
extremos_pca$label <- recode(extremos_pca$label,
"Max Preciom" = "Max Precio",
"Min Preciom" = "Min Precio",
"Max Areaconst" = "Max Área Construida",
"Min Areaconst" = "Min Área Construida",
"Max Banios" = "Max Baños",
"Min Banios" = "Min Baños",
"Max Habitaciones" = "Max Habitaciones",
"Min Habitaciones" = "Min Habitaciones")
# Crear el plot
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 Precio" = "red", "Min Precio" = "red",
"Max Área Construida" = "blue", "Min Área Construida" = "blue",
"Max Baños" = "green", "Min Baños" = "green",
"Max Habitaciones" = "pink", "Min Habitaciones" = "pink")) +
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.pdf", plot = p, width = 12, height = 10)
El análisis de clustering o agrupamiento se ha realizado para identificar segmentos diferenciados dentro del mercado inmobiliario urbano, empleando el enfoque de K-Means para agrupar propiedades con características similares. Este proceso ha identificado tres clusters principales que distinguen las propiedades según el estrato socioeconómico, el precio y la ubicación, proporcionando una visión clara de las dinámicas del mercado.
El análisis de clustering ha resultado ser una herramienta valiosa para comprender la segmentación del mercado inmobiliario urbano. Los hallazgos de este estudio pueden orientar decisiones estratégicas en diversas áreas, desde el marketing hasta el desarrollo y la inversión inmobiliaria, asegurando que se satisfagan 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 se ha aplicado para obtener una comprensión más profunda de las interacciones entre diversas categorías de propiedades inmobiliarias, enfocándose en la zona, el estrato y el tipo de vivienda. Esta técnica multivariante ofrece una representación visual clara de cómo estas categorías se interrelacionan, desvelando patrones subyacentes en el mercado inmobiliario urbano que anteriormente podían pasar desapercibidos.
El análisis de correspondencia brinda una representación visual valiosa de las relaciones complejas entre las variables categóricas del mercado inmobiliario. Estos hallazgos pueden guiar estrategias comerciales más efectivas, ajustando las ofertas de propiedades a los patrones y preferencias específicas 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