Una empresa inmobiliaria líder en una gran ciudad está buscando comprender en profundidad el mercado de viviendas urbanas para tomar decisiones estratégicas más informadas. La empresa posee una base de datos extensa que contiene información detallada sobre diversas propiedades residenciales disponibles en el mercado. Se requiere realizar un análisis holístico de estos datos para identificar patrones, relaciones y segmentaciones relevantes que permitan mejorar la toma de decisiones en cuanto a la compra, venta y valoración de propiedades.
data(vivienda)
summary(vivienda)
## id zona piso estrato
## Min. : 1 Length:8322 Length:8322 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## NA's :3 NA's :3
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## NA's :2 NA's :3 NA's :1605 NA's :3
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8322 Length:8322 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## NA's :3 NA's :3
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
## NA's :3
Verificamos los tipos de variable
clase <- sapply(vivienda, class)
clase
## id zona piso estrato preciom areaconst
## "numeric" "character" "character" "numeric" "numeric" "numeric"
## parqueaderos banios habitaciones tipo barrio longitud
## "numeric" "numeric" "numeric" "character" "character" "numeric"
## latitud
## "numeric"
Se observa que el atributo Piso está como texto, lo mejor seria convertir a numérico para facilitar posteriores calculos y analisis.
num_faltantes_por_variable <- colSums(is.na(analisis))
# Crear un marco de datos con los resultados
resultados_faltantes <- data.frame(variable = names(num_faltantes_por_variable), faltantes = num_faltantes_por_variable)
# Imprimir los resultados
print(resultados_faltantes)
## variable faltantes
## id id 3
## zona zona 3
## piso piso 2638
## estrato estrato 3
## preciom preciom 2
## areaconst areaconst 3
## parqueaderos parqueaderos 1605
## banios banios 3
## habitaciones habitaciones 3
## tipo tipo 3
## barrio barrio 3
## longitud longitud 3
## latitud latitud 3
Podemoas identificar que el dataframe cuenta con 8322 flas y 13 varibles, se identifica la presencia de registros con datos faltantes o NA,las columnas con mayore presenca son Piso con 2638 registros y parqueaderos en 1605 registros.
En el contexto del análisis realizado, opte por utilizar la Imputación Múltiple por Ecuaciones Encadenadas (mice) debido a la complejidad de los datos y la presencia de múltiples variables interrelacionadas. Dado que el conjunto de datos incluye diversas características de las viviendas, como el precio, la ubicación, el número de habitaciones y baños, entre otros, la imputación por permite capturar de manera más precisa las relaciones entre estas variables. Además, la imputación por mice es especialmente útil cuando hay valores faltantes en varias variables y se quiere evitar sesgos en el análisis.
Se procesde a elimar las filas que cumplan la condicion de id=NA
#elimar finalas que cumplan la condicion de id=NA
# Filtrar las filas que cumplen con la condición
analisis_filtrado <- analisis[!is.na(analisis$id), ]
# Verificar la cantidad de filas eliminadas
filas_eliminadas <- nrow(analisis) - nrow(analisis_filtrado)
cat("Se han eliminado", filas_eliminadas, "filas del dataset.")
## Se han eliminado 3 filas del dataset.
# Actualizar el dataframe original
analisis <- analisis_filtrado
Verifcamos que ya no queden datos faltantes.
num_faltantes_por_variable <- colSums(is.na(analisis))
# Crear un marco de datos con los resultados
resultados_faltantes <- data.frame(variable = names(num_faltantes_por_variable), faltantes = num_faltantes_por_variable)
# Imprimir los resultados
print(resultados_faltantes)
## variable faltantes
## id id 0
## zona zona 0
## piso piso 0
## estrato estrato 0
## preciom preciom 0
## areaconst areaconst 0
## parqueaderos parqueaderos 0
## banios banios 0
## habitaciones habitaciones 0
## tipo tipo 0
## barrio barrio 0
## longitud longitud 0
## latitud latitud 0
una vez terminamos con el analisis expliratorio de los datos y limpiza procedemos con el objetivo de la presente actividad.
el propósito de este análisis es reducir la dimensionalidad del conjunto de datos para simplificar su estructura y facilitar la identificación de las características clave que influyen en la variación de precios y la oferta en el mercado inmobiliario. A través de técnicas de análisis de componentes principales (PCA, por sus siglas en inglés), se busca transformar las variables originales en un conjunto reducido de componentes que capturen la mayor parte de la variabilidad presente en los datos. Esto permitirá visualizar de manera más clara las relaciones entre las variables y comprender cuáles son las características más relevantes que afectan los precios y la oferta en el mercado
Para garantizar que el análisis de componentes principales (PCA) proporcione resultados significativos, es crucial normalizar las variables antes de proceder con el cálculo. Dado que el PCA se basa en la varianza y covarianza de los datos, y estas medidas son sensibles a las magnitudes de los valores, variables con diferentes escalas podrían influir de manera desproporcionada en los componentes principales.
# Seleccionar variables numéricas
vivienda_num <- vivienda_limpia %>% select(piso,estrato,preciom,areaconst,parqueaderos,banios, habitaciones)
# Estandarizar datos
vivienda_scaled <- scale(vivienda_num)
# Realizar PCA
pca_result <- PCA(vivienda_scaled, graph = FALSE)
pca_result <- PCA(vivienda_scaled, ncp = 7, graph = FALSE)
# Obtener la matriz de cargas
matriz_cargas <- pca_result$var$coord
# Imprimir la matriz de cargas
print(matriz_cargas)
## Dim.1 Dim.2 Dim.3 Dim.4 Dim.5
## piso -0.1374186 0.6800223 0.699390149 0.16794334 -0.02771857
## estrato 0.5654438 0.6518987 -0.195366707 -0.40408901 0.02843489
## preciom 0.8791285 0.2608802 -0.096064087 0.06538226 -0.15798062
## areaconst 0.8409095 -0.2137518 0.006633517 0.21374303 -0.39472039
## parqueaderos 0.7995928 0.1355075 -0.172754246 0.40156006 0.38126990
## banios 0.8611295 -0.1035645 0.206475597 -0.25635684 0.08085066
## habitaciones 0.5524564 -0.6225542 0.444892030 -0.15562832 0.13836110
## Dim.6 Dim.7
## piso 0.01166578 0.02073426
## estrato 0.21848374 0.07281198
## preciom -0.09568384 -0.33385362
## areaconst 0.10830148 0.18416801
## parqueaderos 0.04538211 0.06138679
## banios -0.33978623 0.13186335
## habitaciones 0.23064659 -0.11281627
fviz_screeplot(pca_result,
addlabels = TRUE, # Añadir etiquetas de porcentaje de varianza
ylim = c(0, 75), # Definir el límite del eje y
barfill = "skyblue", # Color de las barras
barcolor = "black", # Color del borde de las barras
title = "Scree Plot", # Título del gráfico
xlab = "Componentes Principales", # Etiqueta del eje x
ylab = "Porcentaje de Varianza Explicada", # Etiqueta del eje y
ggtheme = theme_minimal() # Tema visual para el gráfico
)
El primer componente principal (PC1) explica el 50.1% de la varianza total en los datos, lo cual es significativo. El segundo componente principal (PC2) explica un 20.3% adicional de la varianza. Los primeros dos componentes juntos explican alrededor del 70.4% de la varianza total, lo cual indica que gran parte de la información de los datos originales puede ser capturada por solo dos componentes. Los componentes principales posteriores (del tercero en adelante) explican cada vez menos varianza, siendo estos valores 11.5%, 7%, 5%, 3.4%, y 2.6%, respectivamente. Esto sugiere que la mayoría de la información relevante está contenida en los primeros pocos componentes.
# Visualizar variables en el plano de los dos primeros componentes principales
fviz_pca_var(pca_result, col.var = "contrib", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), repel = TRUE)
#### Componentes principales:
El primer componente (Dim1) está fuertemente asociado con las variables precio, estrato, parqueaderos, baños, areaconst, y habitaciones. Estas variables tienen vectores largos en la dirección de Dim1, lo que indica que tienen una alta contribución en la varianza explicada por este componente.
El segundo componente (Dim2) está fuertemente influenciado por la variable piso, que se encuentra en una dirección casi perpendicular a las otras variables, indicando que piso contribuye a una dimensión distinta.
Las variables que están agrupadas y apuntan en la misma dirección (precio, estrato, parqueaderos, baños, areaconst, habitaciones) están altamente correlacionadas entre sí. Esto sugiere que cuando una de estas variables aumenta, las otras también tienden a aumentar.
La variable piso, al estar casi perpendicular a las demás, tiene poca o ninguna correlación con estas.
La escala de colores indica la contribución de cada variable a los componentes principales. Las variables con colores más cálidos (precio y estrato) tienen una mayor contribución, especialmente al primer componente.
# Graficar la contribución de las variables al primer componente
fviz_contrib(pca_result, choice = "var", axes = 1)
Las variables preciom (probablemente el precio), baños, areaconst (área
construida), y parqueaderos son las que más contribuyen al primer
componente principal (Dim-1), con una contribución superior al 15%. Esto
sugiere que estas variables son las más importantes para explicar la
varianza en la dirección del primer componente.
preciom tiene la mayor contribución, con más del 20%, seguida de cerca por baños y areaconst.
Las variables estrato, habitaciones, y piso tienen una contribución mucho menor al primer componente. Especialmente piso, cuya contribución es casi nula. Esto confirma que piso no está bien representado en Dim-1 y podría estar más relacionado con otros componentes (como Dim-2, según el gráfico anterior).
# Graficar la contribución de las variables al segndo componente
fviz_contrib(pca_result, choice = "var", axes = 2)
Las variables “piso”, “estrato”, y “habitaciones” son las que más contribuyen a la Dim-2, con contribuciones superiores al 20%. Esto sugiere que estas variables tienen una gran influencia en la formación de esta dimensión.
Variables de Menor Contribución: Las variables “preciom”, “areaconst”, “parqueaderos”, y “baños” tienen una contribución significativamente menor a Dim-2, todas por debajo del 10%. Esto indica que su influencia en esta dimensión es limitada.
Para agrupar las propiedades residenciales en segmentos homogéneos con características similares y comprender las dinámicas de las ofertas en distintas partes de la ciudad y estratos socioeconómicos, se emplea el análisis de conglomerados. Este método ayuda a descubrir estructuras subyacentes en los datos al agrupar objetos de manera lógica y útil, considerando la similitud y distancia entre los individuos de los grupos.
# Seleccionar variables numéricas
vivienda_num <- vivienda_limpia %>% select(piso,estrato,preciom,areaconst,parqueaderos,banios,habitaciones)
# Estandarizar datos
vivienda_scaled <- scale(vivienda_num)
# Determinar el número óptimo de clusters con el método del codo
codo <- fviz_nbclust(vivienda_scaled, kmeans, method = "wss")+
geom_vline(xintercept = 3, linetype = 2)
## Warning: did not converge in 10 iterations
## Warning: did not converge in 10 iterations
print(codo)
Punto de Inflexión (Codo): El gráfico muestra un claro punto de inflexión en k = 3. Esto significa que a partir de 3 clusters, la disminución en la suma de cuadrados dentro de los grupos se vuelve menos pronunciada. Este punto sugiere que 3 es el número óptimo de clusters, ya que es donde se logra un buen equilibrio entre minimizar la variabilidad dentro de los grupos y no sobrecargar el modelo con demasiados clusters.
silhouette <- fviz_nbclust(vivienda_scaled, kmeans, method = "silhouette")
print(silhouette)
Pico en k=2 El gráfico muestra un pico máximo en el valor promedio
cuando k=2, lo que sugiere queel número óptimo de clusters sería 2. Esto
indica que los datos se agrupan mejor en dos clusters, con una buena
separación entre ellos y cohesión interna.
# Aplicar K-means con el número óptimo de clusters
set.seed(123)
kmeans_result <- kmeans(vivienda_scaled, centers = 2, nstart = 25)
# Añadir los clusters a los datos originales
# Asegurarse de que las filas eliminadas en vivienda_scaled también se eliminen en vivienda original
vivienda_limpia <- vivienda_limpia[complete.cases(vivienda_num), ]
vivienda_limpia$cluster <- as.factor(kmeans_result$cluster)
# Visualizar los clusters
fviz_cluster(kmeans_result, data = vivienda_scaled, ellipse.type = "convex", geom = "point", stand = FALSE)
# Aplicar K-means con el número óptimo de clusters
set.seed(123)
kmeans_result <- kmeans(vivienda_scaled, centers = 3, nstart = 25)
## Warning: Quick-TRANSfer stage steps exceeded maximum (= 415950)
# Añadir los clusters a los datos originales
# Asegurarse de que las filas eliminadas en vivienda_scaled también se eliminen en vivienda original
vivienda_limpia <- vivienda_limpia[complete.cases(vivienda_num), ]
vivienda_limpia$cluster <- as.factor(kmeans_result$cluster)
# Visualizar los clusters
fviz_cluster(kmeans_result, data = vivienda_scaled, ellipse.type = "convex", geom = "point", stand = FALSE)
Finalmente, se procede a realizar el análisis de correspondencia, que consiste en estimar las coordenadas para cada uno de los niveles de las variables categóricas y representarlas en un plano cartesiano. El objetivo principal del análisis de correspondencia es descubrir patrones y relaciones entre las categorías de las variables mediante una representación gráfica en un espacio de baja dimensión.
tabla <- table(vivienda_limpia$zona, vivienda_limpia$estrato)
tabla
##
## 3 4 5 6
## Zona Centro 105 14 4 1
## Zona Norte 572 407 769 172
## Zona Oeste 54 84 290 770
## Zona Oriente 340 8 2 1
## Zona Sur 382 1616 1685 1043
chisq.test(tabla)
##
## Pearson's Chi-squared test
##
## data: tabla
## X-squared = 3830.4, df = 12, p-value < 2.2e-16
El valor p es extremadamente pequeño, menor que 0.00000000000000022. Un valor p tan bajo indica que hay evidencia muy fuerte para rechazar la hipótesis nula.
resultados_ac <- CA(tabla)
Se puede eidentiicar de acueros a cada :
El estrato 6 se ubica en la zona Oeste El estrato 4 y 5 En la zonal sur El estrato 3 se ubica en la zona centro y Oriente
valores_prop <-resultados_ac$eig ; valores_prop
## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.32215213 69.965515 69.96551
## dim 2 0.12745096 27.680002 97.64552
## dim 3 0.01084108 2.354483 100.00000
fviz_screeplot(resultados_ac, addlabels = TRUE, ylim = c(0, 90))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")
El primer componente explica el 70% de la varianza total, mientras que el segundo componente aporta el 27.7%. Por lo tanto, juntos, los dos primeros componentes explican el 97.7% de la varianza total de los datos.
dimension_descriptions <- dimdesc(resultados_ac)
# Imprimir la descripción de las variables para cada dimensión
print(dimension_descriptions)
## $`Dim 1`
## $`Dim 1`$row
## coord
## Zona Oeste -0.5690714
## Zona Sur -0.2090141
## Zona Norte 0.3898305
## Zona Centro 1.7245923
## Zona Oriente 2.0148839
##
## $`Dim 1`$col
## coord
## 6 -0.5190649
## 4 -0.1544575
## 5 -0.1323066
## 3 1.1865554
##
##
## $`Dim 2`
## $`Dim 2`$row
## coord
## Zona Sur -0.1880737
## Zona Norte -0.1471227
## Zona Centro 0.3637090
## Zona Oriente 0.5374546
## Zona Oeste 0.7826088
##
## $`Dim 2`$col
## coord
## 4 -0.3798066
## 5 -0.2042818
## 3 0.2066347
## 6 0.5385722
Los dos primeros componentes principales capturan una gran parte de la variabilidad en los datos (70.4% en total). Por lo tanto, podríamos utilizar estos dos componentes para reducir la dimensionalidad del conjunto de datos sin perder mucha información.
Las variables como precio, estrato, y parqueaderos están estrechamente relacionadas y podrían estar representando una dimensión similar en los datos.
La variable piso parece estar capturando una información diferente en comparación con las otras variables, lo que podría ser relevante para un análisis adicional o para interpretaciones específicas.
A medida que se incrementa el número de clusters de 1 a 3, la suma de cuadrados dentro de los grupos disminuye rápidamente, indicando que agregar más clusters en esta región mejora significativamente la calidad de la clasificación. Sin embargo, después de 3 clusters, las mejoras se vuelven marginales.
Para mejorar su posicionamiento en el mercado y maximizar los beneficios, se recomienda a la empresa:
Implementar campañas de marketing segmentadas: Dirigir las campañas de mercadeo y publicidad según las preferencias de las viviendas (casas o apartamentos) y el estrato socioeconómico y ubicación. Esto permitirá clasificar a los potenciales clientes de acuerdo con su nivel de ingresos promedio.
Explorar oportunidades en zonas de bajo precio: Considerar inversiones a largo plazo en las Zonas Centro y Oriente, que tienen menos viviendas y precios de venta promedio más bajos. Evaluar la adquisición de viviendas económicas para su valorización o la compra de lotes para desarrollar nuevos proyectos, buscando aumentar la cantidad de viviendas disponibles y, por ende, maximizar los beneficios.