Introducción

En este análisis, se examinan los datos de una base inmobiliaria con el objetivo de identificar patrones y relaciones en el mercado de viviendas urbanas. La base de datos incluye información detallada sobre propiedades, como ubicación, precio, área construida, número de habitaciones y otros factores clave.

El propósito del estudio es proporcionar información valiosa que ayude a la toma de decisiones estratégicas en la compra, venta y valoración de inmuebles. A través del análisis exploratorio técnicas multivariadas, se busca comprender mejor las tendencias del mercado y segmentaciones relevantes dentro de la ciudad.

Análisis descriptivo

str(vivienda)
## 'data.frame':    8322 obs. of  13 variables:
##  $ id          : num  1147 1169 1350 5992 1212 ...
##  $ zona        : Factor w/ 5 levels "Zona Centro",..: 4 4 4 5 2 2 2 2 2 2 ...
##  $ piso        : Factor w/ 12 levels "01","02","03",..: NA NA NA 2 1 1 1 1 2 2 ...
##  $ estrato     : num  3 3 3 4 5 5 4 5 5 5 ...
##  $ preciom     : num  250 320 350 400 260 240 220 310 320 780 ...
##  $ areaconst   : num  70 120 220 280 90 87 52 137 150 380 ...
##  $ parqueaderos: num  1 1 2 3 1 1 2 2 2 2 ...
##  $ banios      : num  3 2 2 5 2 3 2 3 4 3 ...
##  $ habitaciones: num  6 3 4 3 3 3 3 4 6 3 ...
##  $ tipo        : Factor w/ 2 levels "Apartamento",..: 2 2 2 2 1 1 1 1 2 2 ...
##  $ barrio      : Factor w/ 436 levels "20 de julio",..: 1 1 1 2 3 3 3 3 3 3 ...
##  $ longitud    : num  -76.5 -76.5 -76.5 -76.5 -76.5 ...
##  $ latitud     : num  3.43 3.43 3.44 3.44 3.46 ...
tabla<-round(as.data.frame(apply(vivienda[,-c(1,2,3,10,11)],2,summary)),2)

kable(tabla, format = "html") %>%
  kable_styling(position = "center")
estrato preciom areaconst parqueaderos banios habitaciones longitud latitud
Min. 3.00 58.00 30.00 1.00 0.00 0.00 -76.59 3.33
1st Qu. 4.00 220.00 80.00 1.00 2.00 3.00 -76.54 3.38
Median 5.00 330.00 123.00 2.00 3.00 3.00 -76.53 3.42
Mean 4.63 433.89 174.93 1.84 3.11 3.61 -76.53 3.42
3rd Qu. 5.00 540.00 229.00 2.00 4.00 4.00 -76.52 3.45
Max. 6.00 1999.00 1745.00 10.00 10.00 10.00 -76.46 3.50
NA’s 3.00 2.00 3.00 1605.00 3.00 3.00 3.00 3.00

Las variables numéricas muestran una gran variabilidad en las características de las propiedades. El precio presenta un rango amplio, indicando la presencia de distintos segmentos de mercado, desde viviendas accesibles hasta propiedades de alto valor. El área construida también varía considerablemente, con algunas viviendas compactas y otras de gran tamaño, lo que sugiere diferentes tipos de oferta inmobiliaria. En cuanto a la distribución de habitaciones y baños, la mayoría de las viviendas tienen entre 2 y 4 habitaciones y 1 a 3 baños, reflejando una tendencia hacia propiedades de tamaño medio. El número de parqueaderos es generalmente bajo, con la mayoría de las propiedades ofreciendo entre 0 y 2 espacios de estacionamiento. Finalmente, los valores de latitud y longitud permiten analizar la ubicación geográfica de los inmuebles, lo que puede ser clave para identificar tendencias de precios según la zona.

summary(vivienda[,c(2,3,10,11)])
##            zona           piso               tipo                 barrio    
##  Zona Centro : 124   02     :1450   Apartamento:5100   valle del lili:1008  
##  Zona Norte  :1920   03     :1097   Casa       :3219   ciudad jardín : 516  
##  Zona Oeste  :1198   01     : 860   NA's       :   3   pance         : 409  
##  Zona Oriente: 351   04     : 607                      la flora      : 366  
##  Zona Sur    :4726   05     : 567                      santa teresita: 262  
##  NA's        :   3   (Other):1103                      (Other)       :5758  
##                      NA's   :2638                      NA's          :   3

Las propiedades analizadas están distribuidas en diferentes zonas de la ciudad, con una mayor concentración en la Zona Sur (4726 registros) y la Zona Norte (1920 registros), mientras que la Zona Centro (124 registros) tiene una menor presencia en la base de datos. En cuanto al tipo de inmueble, predominan los apartamentos (5100 registros) sobre las casas (3219 registros), lo que indica una tendencia hacia edificaciones verticales. La variable piso muestra una variedad de niveles, con un número considerable de registros en diferentes alturas. Respecto a los barrios, algunos sectores tienen una alta representatividad, como Valle del Lili (1008 registros), Ciudad Jardín (516 registros) y Pance (409 registros), lo que sugiere que estos son sectores con mayor oferta inmobiliaria.

Tratamiento de datos faltantes

md.pattern(vivienda,rotate.names = TRUE)

##      preciom id zona estrato areaconst banios habitaciones tipo barrio longitud
## 4808       1  1    1       1         1      1            1    1      1        1
## 1909       1  1    1       1         1      1            1    1      1        1
## 876        1  1    1       1         1      1            1    1      1        1
## 726        1  1    1       1         1      1            1    1      1        1
## 1          1  0    0       0         0      0            0    0      0        0
## 2          0  0    0       0         0      0            0    0      0        0
##            2  3    3       3         3      3            3    3      3        3
##      latitud parqueaderos piso     
## 4808       1            1    1    0
## 1909       1            1    0    1
## 876        1            0    1    1
## 726        1            0    0    2
## 1          0            0    0   12
## 2          0            0    0   13
##            3         1605 2638 4275

La visualización muestra la presencia de datos faltantes en distintas variables del conjunto de datos. Se observa que las variables piso y parqueaderos contienen una cantidad significativa de valores ausentes, con 2638 y 1605 registros faltantes respectivamente. Hay 3 registros de la base de datos que no cuentan con valores en la mayoria o todas las variables; El tratamiento de faltantes consistirá en eliminar estos registros mencionados e imputar la variable piso con “No aplica” y la variable parqueaderos con el valor de 0, ya que se asume que si es un valor faltante es porque la vivienda no cuenta con parqueadero propio.

vivienda<-vivienda[!apply(vivienda,1,function(x){sum(is.na(x))})>11,]
vivienda$piso <- as.character(vivienda$piso)  
vivienda$piso[is.na(vivienda$piso)] <- "No aplica"
vivienda$piso<-as.factor(vivienda$piso)
vivienda$parqueaderos[is.na(vivienda$parqueaderos)]=0

Resultado despues de imputar:

##  /\     /\
## {  `---'  }
## {  O   O  }
## ==>  V <==  No need for mice. This data set is completely observed.
##  \  \|/  /
##   `-----'

##      id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## 8319  1    1    1       1       1         1            1      1            1
##       0    0    0       0       0         0            0      0            0
##      tipo barrio longitud latitud  
## 8319    1      1        1       1 0
##         0      0        0       0 0

Matriz de correlación

corrplot::corrplot(cor(vivienda[,-c(1,2,3,10,11)]))

Se observa una fuerte correlación positiva entre el precio y variables como estrato, área construida y número de parqueaderos, lo que indica que propiedades de mayor estrato, tamaño y con más parqueaderos tienden a ser más costosas. Además, el número de baños y habitaciones también presenta correlaciones positivas con el precio, aunque en menor medida.

ACP

viviendaZ= scale(vivienda[,-c(1,2,3,10,11,12,13)]) 
res.pca <- prcomp(viviendaZ)
fviz_eig(res.pca, addlabels = TRUE)

El gráfico de sedimentación del Análisis de Componentes Principales (ACP) indica que la primera componente principal explica 56.9% de la varianza total, mientras que la segunda componente captura 20%, sumando entre ambas 77.9% de la variabilidad en los datos. Esto sugiere que estas dos primeras componentes contienen la mayor parte de la información relevante del conjunto de datos y podrían ser utilizadas para reducir la dimensionalidad sin perder demasiada información.

fviz_pca_var(res.pca,
             col.var = "contrib", # Color by contributions to the PC
             gradient.cols = c("#FF7F00",  "#034D94"),
             repel = TRUE     # Avoid text overlapping
)

Interpretación:

Variables como precio, área construida, cantidad de baños y parqueaderos tienen una fuerte contribución positiva en esta dimensión. También se observa que estrato está altamente correlacionado en la misma dirección. Esto sugiere que la primera componente principal está asociada a variables relacionadas con el tamaño, valor y características de las propiedades.

v1=which.min( res.pca$x[,1])
v2=which.max( res.pca$x[,1])
v3=which.min( res.pca$x[,2])
v4=which.max( res.pca$x[,2])

datos<- rbind(vivienda[v1,-c(1,2,3,10,11)], # ok
              vivienda[v2,-c(1,2,3,10,11)],
              vivienda[v3,-c(1,2,3,10,11)],
              vivienda[v4,-c(1,2,3,10,11)])

datos <- as.data.frame(datos)
rownames(datos) = c(paste("vivienda ",v1),paste("vivienda ",v2),paste("vivienda ",v3),paste("vivienda ",v4))

kable(datos, format = "html") %>%
  kable_styling(position = "center")
estrato preciom areaconst parqueaderos banios habitaciones longitud latitud
vivienda 4480 3 148 87 0 0 0 -76.55000 3.37500
vivienda 1762 6 1800 1586 10 4 5 -76.53798 3.35961
vivienda 2926 5 950 280 10 0 0 -76.53932 3.39698
vivienda 8073 3 370 1440 1 4 10 -76.49815 3.46343
casos1 <- rbind(res.pca$x[v1,1:2],res.pca$x[v2,1:2]) # CP1
rownames(casos1) = c(v1,v2)
casos1 <- as.data.frame(casos1)

casos2 <- rbind(res.pca$x[v3,1:2], res.pca$x[v4,1:2]) # CP2
rownames(casos2) = c(v3,v4)
casos2 <- as.data.frame(casos2)

fviz_pca_ind(res.pca, col.ind = "#DEDEDE", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")) +
  geom_point(data = casos1, aes(x = PC1, y = PC2), color = "red", size = 3) +
  geom_point(data = casos2, aes(x = PC1, y = PC2), color = "blue", size = 3)

Análisis de las viviendas seleccionadas:

Interpretación: Dim1 diferencia viviendas de bajo costo y pocos servicios versus viviendas de alto costo, mayor tamaño y más comodidades.

Interpretación: Dim2 parece diferenciar viviendas con más habitaciones pero menos parqueaderos versus viviendas con más parqueaderos y menos habitaciones.

fviz_pca_biplot(res.pca, 
                
                habillage = vivienda$tipo,
                col.var = "#034A94", # Variables color
                col.ind = c("#DEDEDE", "#034A94")  # Individuals color
)

Los apartamentos (rojo) tienden a agruparse en la parte inferior izquierda, indicando menor precio, área y parqueaderos, mientras que las casas (azul) se dispersan más, mostrando mayor variabilidad en características. Se identifican viviendas extremas: la 1762 con alto precio y más parqueaderos, la 8073 con muchas habitaciones y la 2926 con pocos baños y parqueaderos. En general, Dim1 representa la jerarquía socioeconómica y Dim2 refleja diferencias en el número de habitaciones, diferenciando claramente casas y apartamentos.

Análisis de conglomerados

viviendaZ<-as.data.frame(viviendaZ)
dist_emp <- dist(viviendaZ, method = "euclidean")
hc_emp <- hclust(dist_emp, method = 'complete')
dendograma <- hclust(dist_emp, method = "average")
par(mfrow=c(1,2))
barplot(head(sort(dendograma$height, decreasing = TRUE),10), horiz = TRUE, 
        main = "Agregaciones (distancias euclidianas)",
        col = "lightblue", ylab = "Nodo", xlab = "Peso",
        ylim = c(0,12))
silu<-c(0)
for (i in 2:10){
  cluster_assigments <- cutree(hc_emp, k = i)
  
  sil <- silhouette(cluster_assigments, dist(viviendaZ))
  silu[i] <- mean(sil[,3])
}

plot(1:10,silu,type = "b",pch=19,col="blue",xlab="cluster",ylab="Silhouette", main="Cant. cluster método Silhouette")
abline(v=which.max(silu),lty=2,col="red")

El análisis de conglomerados muestra a la izquierda un gráfico de agregaciones basado en distancias euclidianas, indicando cómo se fusionan los nodos en el proceso de agrupamiento jerárquico. A la derecha, el método del coeficiente de Silhouette sugiere que la mejor cantidad de clusters es 2, ya que maximiza el valor del coeficiente (~0.65), lo que indica una mejor separación entre grupos. La drástica caída de Silhouette para más de 2 clusters sugiere que una mayor segmentación reduce la calidad de la agrupación.

dist_emp <- dist(viviendaZ, method = 'euclidean')

hc_emp <- hclust(dist_emp, method = 'complete')

cluster_assigments <- cutree(hc_emp, k = 2)

assigned_cluster <- viviendaZ %>% mutate(cluster = as.factor(cluster_assigments))


# gráfico de puntos
ggplot(assigned_cluster, aes(x = preciom  , y = areaconst , color = cluster)) +
  geom_point(size = 4) +
  geom_text(aes(label = cluster), vjust = -.8) + # Agregar etiquetas del clúster
  theme_classic()

El gráfico de dispersión muestra la relación entre precio y área construida }, con los datos segmentados en dos clusters. El cluster 1 (rojo) agrupa la mayoría de los puntos con menor precio y menor área construida, mientras que el cluster 2 (azul) representa propiedades con mayor área construida y precio, sugiriendo una diferenciación clara entre propiedades más accesibles y aquellas de mayor tamaño y costo.

Analisis de correspondencia

vivienda_c<-vivienda[,c("zona","estrato")]
vivienda_c$estrato<-as.factor(vivienda_c$estrato)
tabla <- table( vivienda_c$estrato,vivienda_c$zona)

kable(tabla, format = "html") %>%
  kable_styling(position = "center")
Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
3 105 572 54 340 382
4 14 407 84 8 1616
5 4 769 290 2 1685
6 1 172 770 1 1043
chisq.test(tabla)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla
## X-squared = 3830.4, df = 12, p-value < 2.2e-16

El análisis de correspondencia muestra la relación entre las variables Zona y Estrato, representadas en una tabla de contingencia con diferentes valores para cada categoría. La prueba de chi-cuadrado de Pearson indica una asociación altamente significativa entre Zona y Estrato, lo que sugiere que la distribución de los estratos no es aleatoria en las distintas zonas geográficas analizadas.

resultados_ac <- CA(tabla)

fviz_screeplot(resultados_ac)+ggtitle("")+
  ylab("Porcentaje de varianza explicado") + xlab("Ejes")

El gráfico muestra que el primer eje explica más del 69.97% de la varianza, seguido del segundo eje con aproximadamente 27.68%, mientras que el tercer eje tiene una contribución marginal, lo que indica que la mayor parte de la información relevante en las asociaciones entre zona y estrato está contenida en los dos primeros ejes.

Conclusiones

En conjunto, estos métodos ofrecen una visión integral de la estructura de los datos, permitiendo identificar relaciones, agrupaciones y patrones que pueden ser fundamentales para la toma de decisiones y estrategias de planificación.