PROBLEMA

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.

ANALISIS DE COMPONENTES PRINCIPALES

options(repos = "http://cran.us.r-project.org")
install.packages("paqueteMODELOS")
## Warning: package 'paqueteMODELOS' is not available for this version of R
## 
## A version of this package for your version of R might be available elsewhere,
## see the ideas at
## https://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Installing-packages
library(paqueteMODELOS)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
data(vivienda)
head(vivienda)
vivienda = select (vivienda, id:tipo)
vivienda = select (vivienda, -id)
head(vivienda)
summary(vivienda)
##      zona               piso              estrato         preciom      
##  Length:8322        Length:8322        Min.   :3.000   Min.   :  58.0  
##  Class :character   Class :character   1st Qu.:4.000   1st Qu.: 220.0  
##  Mode  :character   Mode  :character   Median :5.000   Median : 330.0  
##                                        Mean   :4.634   Mean   : 433.9  
##                                        3rd Qu.:5.000   3rd Qu.: 540.0  
##                                        Max.   :6.000   Max.   :1999.0  
##                                        NA's   :3       NA's   :2       
##    areaconst       parqueaderos        banios        habitaciones   
##  Min.   :  30.0   Min.   : 1.000   Min.   : 0.000   Min.   : 0.000  
##  1st Qu.:  80.0   1st Qu.: 1.000   1st Qu.: 2.000   1st Qu.: 3.000  
##  Median : 123.0   Median : 2.000   Median : 3.000   Median : 3.000  
##  Mean   : 174.9   Mean   : 1.835   Mean   : 3.111   Mean   : 3.605  
##  3rd Qu.: 229.0   3rd Qu.: 2.000   3rd Qu.: 4.000   3rd Qu.: 4.000  
##  Max.   :1745.0   Max.   :10.000   Max.   :10.000   Max.   :10.000  
##  NA's   :3        NA's   :1605     NA's   :3        NA's   :3       
##      tipo          
##  Length:8322       
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 
vivienda_na <- colSums(is.na(vivienda)) %>% as.data.frame()
print(vivienda_na)
##                 .
## zona            3
## piso         2638
## estrato         3
## preciom         2
## areaconst       3
## parqueaderos 1605
## banios          3
## habitaciones    3
## tipo            3

NOTA:

En este punto se pueden tomar dos decisiones, la primera es, no considerar la variable piso la cual tiene un porcentaje alto de valores sin datos y que al eliminarlos la muestra reduciria su tamaño. Esta opcion asume que la variable piso no aportaria mucho en el analisis por lo tanto se eliminaria y el tamaño de la muestra seguiria estando completo

La segunda opcion es eliminar los datos NA de la variable piso asumiendo que esta sí representa interes para el analisis, con esta opción la muestra se reducira un 30% pero se mantendria la variable piso para su analisis.

Seleccionamos la opción dos para no descartar ninguna variable.

  • Procedemos a eliminar los datos que estan NA
vivienda = na.omit(vivienda)
head (vivienda)
  • Verificamos que no haya ningun dato faltante
vivienda_na2 <- colSums(is.na(vivienda)) %>% as.data.frame()
print(vivienda_na2)
##              .
## zona         0
## piso         0
## estrato      0
## preciom      0
## areaconst    0
## parqueaderos 0
## banios       0
## habitaciones 0
## tipo         0
  • Convertimos todas las variables categoricas en numericas para poder hacer ACP

Las categorias quedaran asi:

Zona

Zona Centro: 1 Zona Norte: 2 Zona Oeste: 3 Zona Oriente: 4 Zona Sur: 5

vivienda <- vivienda %>% mutate(zona = case_when (
    zona == "Zona Centro" ~ 1,
    zona == "Zona Norte" ~ 2,
    zona == "Zona Oeste" ~ 3,
    zona == "Zona Oriente" ~ 4,
    zona == "Zona Sur" ~ 5, ))

vivienda$zona <- as.numeric(vivienda$zona)

Tipo

Casa: 1 Apartamento: 2

vivienda <- vivienda %>% mutate(tipo = case_when (                                               tipo == "Casa" ~ 1,
              tipo == "Apartamento" ~ 2))

vivienda$tipo <- as.numeric(vivienda$tipo)

vivienda$piso <- as.numeric(vivienda$piso)


head(vivienda)
  • Correlacionamos las variables para comprender las relaciones entre ellas y evaluar la fuerza y dirección de esas relaciones
library(corrplot)
## corrplot 0.92 loaded
matrizcor <- cor(vivienda)
corrplot (matrizcor, method = "number", number.cex = 0.5)

Las correlaciones positivas que mas destacan son:

  • areaconst y preciom: 0.7.

  • Parqueaderos y preciom: 0.7.

  • banios y preciom: 0.69.

  • banios y areaconst: 0.68.

  • preciom y estrato: 0.59.

Las correlaciones negativas que mas destacan son:

  • tipo y areaconst: - 0.58.

  • habitaciones y tipo: -0.57.

  • Realizamos la estandarización de las variables para que tengan media 0 y desviación estándar 1 esto nos ayuda a estandarizar las distancias entre observaciones.

viviendapca <- scale(vivienda)
head (viviendapca, n = 6)
##            zona       piso    estrato    preciom  areaconst parqueaderos
## [1,]  0.7275272 -0.7053307 -0.9046263 -0.1756310  0.7609789    1.0779092
## [2,] -1.6547322 -1.0793910  0.1749079 -0.6055839 -0.6129041   -0.7415001
## [3,] -1.6547322 -1.0793910  0.1749079 -0.6670057 -0.6345970   -0.7415001
## [4,] -1.6547322 -1.0793910 -0.9046263 -0.7284276 -0.8876807    0.1682046
## [5,] -1.6547322 -1.0793910  0.1749079 -0.4520293 -0.2730489    0.1682046
## [6,] -1.6547322 -0.7053307  0.1749079 -0.4213184 -0.1790463    0.1682046
##          banios habitaciones       tipo
## [1,]  1.3178809   -0.4241459 -1.3987647
## [2,] -0.9022913   -0.4241459  0.7147679
## [3,] -0.1622339   -0.4241459  0.7147679
## [4,] -0.9022913   -0.4241459  0.7147679
## [5,] -0.1622339    0.3272519  0.7147679
## [6,]  0.5778235    1.8300475 -1.3987647
  • Realizamos el Analisis de Componentes Principales
prcomp(viviendapca)
## Standard deviations (1, .., p=9):
## [1] 1.9807435 1.3038276 1.0065797 0.8880937 0.6917289 0.6058975 0.5574084
## [8] 0.4943040 0.4172944
## 
## Rotation (n x k) = (9 x 9):
##                      PC1         PC2          PC3         PC4        PC5
## zona         -0.02543955 -0.16404488  0.927132120 -0.30571078  0.0792994
## piso          0.14110002  0.47067593 -0.154481596 -0.76787482  0.2210911
## estrato      -0.22413900  0.53649200  0.246911243  0.24621865 -0.5187323
## preciom      -0.41455699  0.31330628  0.015040316  0.07954319  0.1161470
## areaconst    -0.44151818 -0.04940037 -0.094924610 -0.04254934  0.2165833
## parqueaderos -0.39125435  0.20508436  0.033326960  0.13250822  0.5627818
## banios       -0.43986424  0.04969392 -0.012030129 -0.20192873 -0.3205302
## habitaciones -0.32832942 -0.34127243 -0.212162323 -0.43466711 -0.4079579
## tipo          0.32870777  0.44959161  0.009547411 -0.02964557 -0.1716275
##                      PC6         PC7           PC8          PC9
## zona         -0.03797742  0.10381102  0.0223395978 -0.020064740
## piso          0.23029631 -0.20009533  0.0556938762 -0.001012726
## estrato       0.18384548 -0.28738369  0.3817542272  0.095609530
## preciom       0.13255630  0.35640811 -0.2009827307 -0.724531754
## areaconst     0.34918527  0.53100050  0.2993308600  0.501399059
## parqueaderos -0.57395890 -0.32772873  0.1412620713  0.112596771
## banios       -0.10575830 -0.08878210 -0.7261119848  0.337764342
## habitaciones -0.37495877  0.03241888  0.4165040698 -0.245426552
## tipo         -0.53945613  0.58418157 -0.0007715692  0.164654009
vivipca <- (prcomp(viviendapca))
  • Graficamos para conocer cuantos elementos principales podriamos usar que puedan explicar la mayoria de la varianza
library(ggplot2)
library(ggsignif)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
fviz_eig(vivipca, addlabels = TRUE, ylim = c(0, 55))

  • Graficamos para identificar que variables tienen un mayor peso en cada uno de los componentes PC1 y PC2,
fviz_contrib(vivipca, choice = "var", axes = 1, top = 10)

fviz_contrib(vivipca, choice = "var", axes = 2, top = 10)

fviz_contrib(vivipca, choice = "var", axes = 3, top = 10)

En el gráfico de correlación entre variables, podemos observar que la primera componente está relacionada con el precio, el número de parqueaderos, el número de baños y el área construida de las viviendas. Estas variables presentan una correlación positiva entre sí, ya que están agrupadas. El segundo componente tiene asociado las variables estrato, piso, tipo y habitaciones las cuales siguen teniendo correlación positiva y explican el resto de la varianza. El tercer componente tiene una particularidad y es que su capacidad para explicar la varianza es relativamente baja en comparación con los dos primeros componentes pues esta influenciado solo por la variable zona.

  • En la siguiente tabla se observa la contribución por cada variable
get_pca_var(vivipca)$contrib[,1:3]
##                    Dim.1      Dim.2        Dim.3
## zona          0.06471708  2.6910722 85.957396733
## piso          1.99092149 22.1535828  2.386456357
## estrato       5.02382904 28.7823667  6.096516170
## preciom      17.18574952  9.8160822  0.022621110
## areaconst    19.49383001  0.2440397  0.901068167
## parqueaderos 15.30799680  4.2059593  0.111068629
## banios       19.34805484  0.2469485  0.014472400
## habitaciones 10.78002113 11.6466869  4.501285127
## tipo         10.80488009 20.2132616  0.009115306
  • En la siguiente grafica se puede observar cómo las variables originales contribuyen a los componentes principales en el análisis de PCA. Aqui vemos como las 4 variables que se nombraron en el PC1 se ven juntas (Habitaciones, area construida, precio y baños)
fviz_pca_var(vivipca, col.var = "contrib", gradient.cols = c("#FF7F00",  "#034D94"),
repel = TRUE)

  • En la siguiente tabla se Smuestra la proporción de varianza explicada por cada uno de los componentes principales obtenidos en un Análisis de Componentes Principales (PCA). La proporción de varianza explicada es una medida que indica cuánta variabilidad de los datos originales es capturada por cada componente principal.
varianza_expl <- vivipca$sdev^2/sum(vivipca$sdev^2)
round(varianza_expl*100, 2)
## [1] 43.59 18.89 11.26  8.76  5.32  4.08  3.45  2.71  1.93
  • En la siguiente tabla se ve la acumulacion de porcentajes de cada variable
varianza_acum <- cumsum(varianza_expl)
round(varianza_acum*100, 2)
## [1]  43.59  62.48  73.74  82.50  87.82  91.90  95.35  98.07 100.00
  • Grafica de proporcion de varianza explicada acumulada
ggplot(data = data.frame(varianza_acum, pc = 1:9),
       aes(x = pc, y = varianza_acum, group = 1)) +
  geom_point() +
  geom_line() +
  theme_bw() +
  labs(x = "Componente principal",
       y = "Prop. varianza explicada acumulada")

CONCLUSION

El analisis de componentes principales ha podido identificar inicialmente 3 grandes componentes que en su acumulado representan el 73,74% de la varianza del conjunto de datos esto teniendo en cuenta el metodo del codo con la varianza acumulada que elige el numero de componentes en el punto donde la curva se aplana. Estos tres componentes principales capturan la mayoría de la varianza en los datos sin embargo haciendo un zoom en el componente principale 3, este está principalmente influenciado por la variable “zona” por lo que su capacidad para explicar la varianza es relativamente baja en comparación con los dos primeros componentes.

Dado que los dos primeros componentes principales explican la mayoría de la varianza y parecen capturar aspectos clave tanto económicos como arquitectónicos de las viviendas, se recomenda enfocarse en ellos para obtener una comprensión profunda de las relaciones y patrones presentes en los datos. El tercer componente, aunque refleja una variable importante (zona), puede no aportar tanta información como los dos primeros. Sin embargo, podría ser relevante en casos específicos donde se quiera explorar la variabilidad geográfica de las viviendas.

El componente Principal 1 está fuertemente influenciado por las variables relacionadas con las características físicas y financieras de las viviendas, como el precio, el número de parqueaderos, el número de baños y el área construida. Indica una dimensión que refleja el valor y tamaño de las viviendas, junto con los aspectos prácticos como el espacio de estacionamiento y las comodidades.Podemos notar que a mayor número de parqueaderos, mayor será el precio, y a mayor número de baños, mayor será el área construida de la vivienda.

Componente Principal 2 agrupa variables como el estrato, el piso, el tipo de vivienda y el número de habitaciones. Aquí se reflejan las diferencias en la clasificación socioeconómica y características arquitectónicas de las viviendas. CP2 sugiere una dimensión que podría relacionarse con el perfil y estilo de vida de los habitantes.

ANALISIS DE CLUSTERS

fviz_nbclust(viviendapca, kmeans, method = "silhouette")

viviendaclu <- scale (vivienda)
head(viviendaclu)
##            zona       piso    estrato    preciom  areaconst parqueaderos
## [1,]  0.7275272 -0.7053307 -0.9046263 -0.1756310  0.7609789    1.0779092
## [2,] -1.6547322 -1.0793910  0.1749079 -0.6055839 -0.6129041   -0.7415001
## [3,] -1.6547322 -1.0793910  0.1749079 -0.6670057 -0.6345970   -0.7415001
## [4,] -1.6547322 -1.0793910 -0.9046263 -0.7284276 -0.8876807    0.1682046
## [5,] -1.6547322 -1.0793910  0.1749079 -0.4520293 -0.2730489    0.1682046
## [6,] -1.6547322 -0.7053307  0.1749079 -0.4213184 -0.1790463    0.1682046
##          banios habitaciones       tipo
## [1,]  1.3178809   -0.4241459 -1.3987647
## [2,] -0.9022913   -0.4241459  0.7147679
## [3,] -0.1622339   -0.4241459  0.7147679
## [4,] -0.9022913   -0.4241459  0.7147679
## [5,] -0.1622339    0.3272519  0.7147679
## [6,]  0.5778235    1.8300475 -1.3987647
set.seed(1)
modelkmeans <- kmeans(viviendaclu, 2) 
viviendaclu <- data.frame(viviendaclu,modelkmeans$cluster) 

aggregate(vivienda,
          by = list(viviendaclu$modelkmeans.cluster),
          FUN = median)
library(flextable)

Numcluste = table(viviendaclu$modelkmeans.cluster)%>% 
       as.data.frame()

colnames(Numcluste)=c("Cluster", "Frecuencia")
flextable(Numcluste)

Cluster

Frecuencia

1

1,585

2

3,223

viviendakmeans = kmeans(viviendaclu, centers = 2)
vivienda$cluster = viviendakmeans$cluster
vivienda$cluster = as.character(vivienda$cluster)
head(vivienda, n = 6)
fviz_cluster(list(data = viviendaclu[1:9], 
                  cluster = viviendaclu$modelkmeans.cluster),
             palette = c("#2E9FDF",  "#E7B800", "#FC4E07"),
             ellipse.type = "convex",repel = F, 
             show.clust.cent = FALSE, ggtheme = theme_minimal())

med_clus <- aggregate(cbind(piso, estrato, preciom, areaconst, parqueaderos,
             banios,  tipo) ~ cluster,
             data = vivienda, FUN = function(x) c(Media = round(mean(x), 2)))

colnames(med_clus)=c("Cluster", "Piso", "Estrato", "Precio", 
                    "Area construida", "Parqueaderos", "Baños", 
                    "tipo")
flextable(med_clus)

Cluster

Piso

Estrato

Precio

Area construida

Parqueaderos

Baños

tipo

1

4.38

4.67

309.82

106.42

1.38

2.54

1.88

2

2.88

5.19

756.86

313.73

2.70

4.61

1.22

CONCLUSION

El análisis de clustering revela la presencia de dos clusters distintos con características notables. Se han agrupado las variables con base en sus atributos.

Como se puede observar en la tabla med_clus podemos relacionar lo siguiente:

  1. En el cluster #1 podemos encontrar viviendas pequeñas con menos baños y un parqueadero en promedio, estas viviendas son las mas economicas del mercado.

  2. En el cluster #2 se observa que las viviendas estan en estratos mas altos, son viviendas mas grandes y mas costosas a su ves tienen mas baños y parqueaderos.

Se puede decir que en el cluster 1 estan las viviendas mas accesibles a los clientes y en el cluster 2 estan las viviendas mas lujosas con mejores condiciones habitacionales.

ANALISIS DE CORRESPONDENCIA SIMPLE

viviacs = table(vivienda$zona, vivienda$estrato)
str(viviacs)
##  'table' int [1:5, 1:4] 33 141 19 94 147 3 184 51 2 973 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : chr [1:5] "1" "2" "3" "4" ...
##   ..$ : chr [1:4] "3" "4" "5" "6"
viviacs
##    
##        3    4    5    6
##   1   33    3    0    0
##   2  141  184  482   79
##   3   19   51  181  502
##   4   94    2    1    0
##   5  147  973 1195  721
  • Se realiza la prueba Chi-Cuadrado para validar el supuesto de independencia entre los datos.
library(FactoMineR)
chisq.test(viviacs)
## Warning in chisq.test(viviacs): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  viviacs
## X-squared = 2172.8, df = 12, p-value < 2.2e-16

En este caso la hipótesis nula es la independencia de la variables categóricas. El nivel de significancia establecido es 0.05. El resultado rechaza en cualquier caso la hipótesis nula, por lo tanto, hay algún grado de relación entre las variables.

  • Realizamos el analisis de correspondencia que nos servira para comprender la relación entre las variables categóricas “zona” y “estrato” y visualizar cómo se agrupan o se distancian en un espacio bidimensional. En este caso la variable “estrato” se considera categorica pues representa unos grupos o categorías distintas que no tienen una relación numérica continua.
acs <- CA(viviacs)

eigenvalues <- acs$eig
print(eigenvalues)
##       eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.29526876              65.338252                          65.33825
## dim 2 0.13919088              30.800716                          96.13897
## dim 3 0.01744831               3.861032                         100.00000

En el grafico se puede observar que:

Las viviendas de estratos bajos (3) estan ubicadas en la zona centro. Las viviendas que están ubicadas en las zonas Norte y Sur son principalmente de estratos 4 y 5. Las mejores viviendas se encuentran ubicadas en la zona oeste.

CONCLUSIÓN

El análisis de correspondencia Simple (ACS) nos muestra una relacion entre las variables categorías zona y estrato. Con esta relacion podemos determinar donde ubicariamos mejor un proyecto de edificación de acuerdo a su cliente objetivo segun el estrato para evitar construir edificaciones lujosas en zonas donde el cliente objetivo normalmente no compraria.