Problemática

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.

Para la evaluación de la problemática, se hará en primer lugar un análisis exploratorio, seguidamente de una imputación de datos. Procesos necesarios para limpiar y estructurar la base de datos y continuar con el análisis de componenestes principales, análisis de cluster y análisis de correspondencia.

Importamos la base de datos de vivienda, importando la libreria “paqueteMET”

library(paqueteMET)
data(vivienda)

Aqui podemos visualizar la base de datos descargada desde el paquete.

data_vivienda <- vivienda
summary(data_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

Como se puede visualizar con la opción “Summary”, podemos obtener las medidas de centralidad de cada una de las 13 variables, con sus valores máximos, mínimos, media aritmética, mediana; al igual que las medidas de dispersión como el cuartil 1 que representa el 25% y el tercer cuartil el 75%.

El estudio inmobiliario requerido, no tiene en cuenta la ubicación absoluta de cada una de las ofertas inmboliarias, sino que se realice un análisis de acuerdo al valor de los inmuebles en relación a las zonas de la ciudad de Cali, también como su área construída, características propias de cada construcción, como el número de habitaciones y baños, al igual que su tipo ya sea una casa o un apartamento.

# Eliminar latitud y longitud, no piden ubicación absoluta
data_vivienda <- subset(data_vivienda, select = -c(longitud, latitud))
head(data_vivienda,5)
##     id         zona piso estrato preciom areaconst parqueaderos banios
## 1 1147 Zona Oriente <NA>       3     250        70            1      3
## 2 1169 Zona Oriente <NA>       3     320       120            1      2
## 3 1350 Zona Oriente <NA>       3     350       220            2      2
## 4 5992     Zona Sur   02       4     400       280            3      5
## 5 1212   Zona Norte   01       5     260        90            1      2
##   habitaciones        tipo      barrio
## 1            6        Casa 20 de julio
## 2            3        Casa 20 de julio
## 3            4        Casa 20 de julio
## 4            3        Casa  3 de julio
## 5            3 Apartamento       acopi

El resultado anterior, involucra la nueva base de datos sin los atributos de latitud y longitud.

Preparación de la base de de datos

Para el proceso de preparación de datos, se realiza a través de la imputación con el uso de librerias como mice y naniar para la identificación de los datos faltantes y posterior a esto, se análiza los métodos más adecuadas para tratar estos NaN.

library(mice)
library(naniar)

Es necesario realizar una matriz para Reconocer los datos faltantes del dataframe de vivienda y dar inicio al proceso de imputación de datos

matriz_faltantes <- is.na(data_vivienda)
total_faltantes_por_columna <- colSums(matriz_faltantes)
matriz_presencia_faltantes <- matrix(total_faltantes_por_columna > 0, nrow = 1)
print(matriz_presencia_faltantes)
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
## [1,] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE  TRUE  TRUE

Seguidamente, al evidenciar que todos los atributos tienen datos faltantes se deben ponderar el número de estos usando el siguiente código.

total_faltantes <- colSums(is.na(data_vivienda))
datos_faltantes <- data.frame(Atributo = names(total_faltantes), Faltantes = total_faltantes)
print(datos_faltantes)
##                  Atributo 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

Como se puede observar, la variable de piso tiene un total de 2638 datos faltantes y parqueaderos 1605; los demás atributos tienen datos faltantes mínimos.

Para tener una mejor visualización se construye el siguiente gráfico.

library(naniar)
gg_miss_var(data_vivienda)

Al tener tantos datos datos faltantes, se procede a realizar técnicas de imputación de datos, como reemplazar por la moda o por la media.

Reemplazamos el valor de los datos faltantes para la variable Parqueaderos por cero, ya que si lo reemplazamos por la media o por la moda podemos alterar esta variable porque por ejemplo, hay casas o apartamentos que no poseen parqueadero propio, o que en la venta del inmueble no se incluya el parqueadero para los apartamentos sino que sea vendido independiente de este.

library(mice)
data_vivienda$parqueaderos[is.na(data_vivienda$parqueaderos)] <- 0
grafico <-md.pattern(data_vivienda, rotate.names = TRUE)

Ahora, reemplazamos el valor de moda para los pisos de NA, que sería el dato con mayor frecuencia, esto se debe a que la mayoría de inmuebles en nuestra de base de datos son apartamentos.

library(mice)
library(DescTools)
moda_piso <- as.numeric(names(which.max(table(data_vivienda$piso))))
data_vivienda$piso[is.na(data_vivienda$piso)] <- moda_piso
# Crear gráfico de patrones de datos
grafico <- md.pattern(data_vivienda, rotate.names = TRUE)

Ahora solo nos queda ajustar las otras variables, existen 3 registros de la base de datos que no tienen ninguna información, estos se pueden eliminar para que no generen errores en los modelos.

library(mice)
data_filtrada <- na.omit(data_vivienda)
grafico <-md.pattern(data_filtrada, rotate.names = TRUE)
##  /\     /\
## {  `---'  }
## {  O   O  }
## ==>  V <==  No need for mice. This data set is completely observed.
##  \  \|/  /
##   `-----'

Examinamos los valores de cada registro de la base de datos con su tipo de variable, en la siguiente tabla

library(dplyr)
glimpse(data_filtrada)
## Rows: 8,319
## Columns: 11
## $ id           <dbl> 1147, 1169, 1350, 5992, 1212, 1724, 2326, 4386, 1209, 159…
## $ zona         <chr> "Zona Oriente", "Zona Oriente", "Zona Oriente", "Zona Sur…
## $ piso         <chr> "2", "2", "2", "02", "01", "01", "01", "01", "02", "02", …
## $ estrato      <dbl> 3, 3, 3, 4, 5, 5, 4, 5, 5, 5, 6, 4, 5, 6, 4, 5, 5, 4, 5, …
## $ preciom      <dbl> 250, 320, 350, 400, 260, 240, 220, 310, 320, 780, 750, 62…
## $ areaconst    <dbl> 70, 120, 220, 280, 90, 87, 52, 137, 150, 380, 445, 355, 2…
## $ parqueaderos <dbl> 1, 1, 2, 3, 1, 1, 2, 2, 2, 2, 0, 3, 2, 2, 1, 4, 2, 2, 2, …
## $ banios       <dbl> 3, 2, 2, 5, 2, 3, 2, 3, 4, 3, 7, 5, 6, 2, 4, 4, 4, 3, 2, …
## $ habitaciones <dbl> 6, 3, 4, 3, 3, 3, 3, 4, 6, 3, 6, 5, 6, 2, 5, 5, 4, 3, 3, …
## $ tipo         <chr> "Casa", "Casa", "Casa", "Casa", "Apartamento", "Apartamen…
## $ barrio       <chr> "20 de julio", "20 de julio", "20 de julio", "3 de julio"…

Al tener la base de datos de los inmuebles ajustada, sin registros repetidos, se realizarán gráficos que permitirán ver la relación entre las zonas con los estratos socieconómicos y con el tipo de inmueble (Apartamento y Casa)

DISTRIBUCIÓN POR ZONAS

distribucion <- table(data_filtrada$zona)
distribucion_zona <- as.data.frame(distribucion)
mayores_100 <- sum(distribucion_zona$Freq> 100)
mayores_100 <- as.data.frame(mayores_100)
# Obtener los datos de la columna "Proporciones"
datos <- distribucion_zona$Freq
etiquetas <- round(distribucion_zona$Freq / sum(distribucion_zona$Freq), 3)*100
# Colores para las secciones (opcional)
colores <- c("gray", "purple", "green", "red", "orange")
# Crear el diagrama de sectores con etiquetas en la mitad
pie(datos, labels = etiquetas, col = colores, clockwise = TRUE, radius = 1, init.angle = 90)
leyenda_etiquetas <- distribucion_zona$Var1
legend("topright", legend = leyenda_etiquetas, fill = colores, bty = "n")

El diagrama circular, se visualiza que los registros de los inmuebles de la inmobialiraria en la Zona Sur de la ciudad representan el 56.8%, en la Zona Norte el 23.1%, en la Zona Oeste el 14.4%, 4.2% para la Zona Oriente y con la menor proporción de inmuebles para la Zona Centro con un 1.5%

DISTRIBUCIÓN POR TIPO DE INMUEBLE

distribucion_inmueble <- table(data_filtrada$tipo)
distribucion_inmueble.df <- as.data.frame(distribucion_inmueble)
colnames(distribucion_inmueble.df)[1] <- "Tipo de inmueble"
colnames(distribucion_inmueble.df)[2] <- "Total"
distribucion_inmueble.df
##   Tipo de inmueble Total
## 1      Apartamento  5100
## 2             Casa  3219

En cuánto al tipo de inmueble, se tienen 5100 apartamentos y 3219 casas.

DISTRIBUCIÓN DE ESTRATO

dist_est <- table(data_filtrada$estrato)
dist_estrato <- as.data.frame(dist_est)
mayores_100 <- sum(dist_estrato$Freq> 100)
mayores_100 <- as.data.frame(mayores_100)
# Obtener los datos de la columna "Proporciones"
data <- dist_estrato$Freq
etiquetas <- round(dist_estrato$Freq / sum(dist_estrato$Freq), 4)*100
# Colores para las secciones (opcional)
colores <- c("blue", "purple", "orange", "pink")
# Crear el diagrama de sectores con etiquetas en la mitad
pie(data, labels = etiquetas, col = colores, clockwise = TRUE, radius = 1, init.angle = 90)
leyenda_etiquetas <- dist_estrato$Var1
legend("topright", legend = leyenda_etiquetas, fill = colores, bty = "n")

En la distribución de los estratos socieconómicos de los inmubles de la inmobiliaria, el estrato 5 tiene la mayor representacipión con un 33.6%, el estrato 4 un 25.59%, el estrato 6 un 23.89% y con una menor representación el estrato 3 con un 17.47%.

Con base en lo anterior, se puede realizar un gráfico que muestre la distribución de los inmuebles por zona en relación al precio.

boxplot(data_filtrada$preciom~ data_filtrada$zona, data = data_filtrada, col = c("pink", "cyan", "orange","green","purple" ), ylab = "Precio", xlab = "Zona")

En el diagrama de BoxPlot, se puede inferir que en la Zona Norte, Zona Sur y Zona Oeste se encuentran los inmuebles con mayor costo, para la Zona Oriente y para la Zona Centro ocurre que los precios de las casas y los apartamentos se encuentran en precios menores a mil millones de pesos.

Seguidamente, se puede realizar un gráfico que muestre la distribución de los inmuebles por estrato en relación al precio.

boxplot(data_filtrada$preciom ~ data_filtrada$estrato, data = data_filtrada, col = c("purple", "green", "red", "pink"), ylab = "Precio", xlab = "Estrato")

Finalmente, se puede realizar un gráfico que muestre la distribución de los inmuebles por tipo de inmueble en relación al precio.

boxplot(data_filtrada$preciom ~ data_filtrada$tipo, data = data_filtrada, col = c("orange", "blue"), ylab = "Precio", xlab = "Tipo")

En relación a los apartamentos y a las casas, se puede decir que las casas tienen valores más estables relacionados en la ubicación de las zonas y el estrato, además de que la mayoría de casas se encuentran en los estratos socieconómicos 3 y 4; para el caso apartamentos se encuentran distribuidos por todas las zonas pero los precios más elevados están en la Zona Sur y en los estratos 4, 5 y 6.

Análisis de Componentes Principales (ACP)

En el análisis de componentes principales o ACP, es necesario conocer la correlación de las variables, para este caso de precio, estrato, areaconst, habitaciones, banios, parqueaderos.

library(psych)
library(corrplot)
columnas_seleccionadas <- data_filtrada[, c("preciom","estrato", "areaconst", "habitaciones", "banios","parqueaderos")]
correlacion<-round(cor(columnas_seleccionadas), 1)
corrplot(correlacion, method="number", type="upper")

summary(data_filtrada)
##        id           zona               piso              estrato     
##  Min.   :   1   Length:8319        Length:8319        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  
##     preciom         areaconst       parqueaderos        banios      
##  Min.   :  58.0   Min.   :  30.0   Min.   : 0.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 : 1.000   Median : 3.000  
##  Mean   : 433.9   Mean   : 174.9   Mean   : 1.482   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  
##   habitaciones        tipo              barrio         
##  Min.   : 0.000   Length:8319        Length:8319       
##  1st Qu.: 3.000   Class :character   Class :character  
##  Median : 3.000   Mode  :character   Mode  :character  
##  Mean   : 3.605                                        
##  3rd Qu.: 4.000                                        
##  Max.   :10.000
data_filtrada$piso <- as.numeric(as.character(data_filtrada$piso))

En la relación a la gráfica, se infiere que existe un relación fuerte entre el número de baños, el área construída y el precio del inmueble, sin dejar atrás la correlación entre el parqueadero y el estrato.

Grafico

library(PerformanceAnalytics)
chart.Correlation(columnas_seleccionadas, histogram = TRUE, method = "pearson")

En el análisis de componentes principales se pretende reducir la dimensionalidad del conjunto de datos y visualizar la estructura de las variables en componentes principales para identificar características claves que influyen en la variación de precios y oferta del mercado.

Para hacer este análisis, es necesario que los datos a tratar sean numéricos. Si hay variables categóricas, deben convertirse a números, que se conoce como dummies.

En este caso, convertimos las zonas a variables númericas

library(dplyr)
data_filtrada <- data_filtrada %>% mutate(zona = case_when(
  zona == "Zona Centro" ~ 1,
  zona == "Zona Norte" ~ 2,
  zona == "Zona Oeste" ~ 3,
  zona == "Zona Oriente" ~ 4,
  zona == "Zona Sur" ~ 5,
  TRUE ~ as.numeric(as.character(zona))
))


# Verificar clases
print(class(data_filtrada$zona))
## [1] "numeric"
head(data_filtrada, 3)

La base de datos ahora es completamente numérica para realizar el análisis de componentes principales.

vivienda_pca <- data_filtrada[1:8319,2:9]
head(vivienda_pca,5)

Posteriormente se debe realizar el proceso de estandarización de variables, para tener escaladas las variables y que esten cercanas sus medias aritméticas a 0 y su desviación estándar a 1.

library(tidyverse)
vivienda_estan= vivienda_pca %>%
  scale()
head(vivienda_estan)
##             zona       piso    estrato    preciom  areaconst parqueaderos
## [1,]  0.06192582 -0.5231243 -1.5872276 -0.5595498 -0.7339949   -0.3875522
## [2,]  0.06192582 -0.5231243 -1.5872276 -0.3465670 -0.3842568   -0.3875522
## [3,]  0.06192582 -0.5231243 -1.5872276 -0.2552886  0.3152194    0.4168506
## [4,]  0.81508501 -0.5231243 -0.6156201 -0.1031580  0.7349051    1.2212534
## [5,] -1.44439256 -0.9554580  0.3559875 -0.5291236 -0.5940997   -0.3875522
## [6,] -1.44439256 -0.9554580  0.3559875 -0.5899759 -0.6150839   -0.3875522
##           banios habitaciones
## [1,] -0.07793773    1.6406840
## [2,] -0.77811479   -0.4147626
## [3,] -0.77811479    0.2703863
## [4,]  1.32241640   -0.4147626
## [5,] -0.77811479   -0.4147626
## [6,] -0.07793773   -0.4147626

Teniendo la estandarización de variables, se calculan los componentes principales para cada una.

prcomp(vivienda_estan)
## Standard deviations (1, .., p=8):
## [1] 1.8526416 1.1901285 1.0029102 0.9205086 0.6753980 0.6432638 0.4903103
## [8] 0.4333512
## 
## Rotation (n x k) = (8 x 8):
##                      PC1        PC2          PC3         PC4         PC5
## zona         -0.05768876 -0.1411091  0.957241606  0.18149560  0.00293511
## piso          0.06034123 -0.5011519 -0.242881173  0.81563835 -0.07674273
## estrato      -0.32666552 -0.5182103 -0.006697218 -0.23548995  0.54862483
## preciom      -0.47447488 -0.1610389 -0.124879497 -0.12377096  0.02255815
## areaconst    -0.44174529  0.2254513 -0.077629195  0.01617502 -0.18274965
## parqueaderos -0.40782678 -0.2381562  0.044131102 -0.10836368 -0.73554958
## banios       -0.46603223  0.1314316 -0.003331854  0.19006943  0.31678712
## habitaciones -0.28730916  0.5564518  0.032749891  0.42765402  0.13348841
##                     PC6         PC7         PC8
## zona         -0.1578309 -0.01513575 -0.04857749
## piso         -0.1186177  0.02566582  0.01817125
## estrato       0.1864561  0.45322805  0.16756065
## preciom      -0.3306477 -0.20540136 -0.75232936
## areaconst    -0.6606854  0.27294987  0.45093313
## parqueaderos  0.4619669  0.04873858  0.08029098
## banios        0.2196478 -0.68456276  0.33492806
## habitaciones  0.3446183  0.45387614 -0.28507871

Se ejecuta la matriz de correlaciones para calcular la relación de las componentes estandarizadas.

matriz_correlaciones <- cor(vivienda_estan, use = "pairwise.complete.obs")
matriz_correlaciones
##                      zona        piso     estrato     preciom    areaconst
## zona          1.000000000 -0.01281479  0.11097057  0.01609820  0.007948296
## piso         -0.012814789  1.00000000  0.11408363 -0.02738479 -0.179330039
## estrato       0.110970570  0.11408363  1.00000000  0.60980664  0.274323323
## preciom       0.016098198 -0.02738479  0.60980664  1.00000000  0.687351963
## areaconst     0.007948296 -0.17933004  0.27432332  0.68735196  1.000000000
## parqueaderos  0.122111410  0.00256355  0.51278892  0.63977788  0.482383972
## banios        0.077544475 -0.08259063  0.42032178  0.66914558  0.648416477
## habitaciones  0.021593137 -0.18669342 -0.07137615  0.26409121  0.516912916
##              parqueaderos      banios habitaciones
## zona           0.12211141  0.07754447   0.02159314
## piso           0.00256355 -0.08259063  -0.18669342
## estrato        0.51278892  0.42032178  -0.07137615
## preciom        0.63977788  0.66914558   0.26409121
## areaconst      0.48238397  0.64841648   0.51691292
## parqueaderos   1.00000000  0.52312994   0.19875551
## banios         0.52312994  1.00000000   0.58990641
## habitaciones   0.19875551  0.58990641   1.00000000

Posterior a esto, se cálcula el número de componentes con la libreria factoextra

library(factoextra)
res.pca <- prcomp(vivienda_estan)
fviz_eig(res.pca, addlabels = TRUE)

library(psych)
scree(vivienda_estan,main ="Grafico de Sedimentacion")

De acuerdo con el gráfico de sedimentación, se recomienda que se tomen los componentes que esten por encima de la línea aceptable, en este caso serían 3 componentes que representan el 73.2% de la base de datos.

Con la Matriz de rotación varimax se espera que cada variable sea representativo en solo uno de ellos, con el fin de minimizar al máximo el número de variables dentro de cada factor.

library(stats) 
factanal(vivienda_estan, factors = 3, rotation = "varimax")
## 
## Call:
## factanal(x = vivienda_estan, factors = 3, rotation = "varimax")
## 
## Uniquenesses:
##         zona         piso      estrato      preciom    areaconst parqueaderos 
##        0.958        0.911        0.303        0.135        0.261        0.503 
##       banios habitaciones 
##        0.226        0.218 
## 
## Loadings:
##              Factor1 Factor2 Factor3
## zona                          0.201 
## piso                 -0.238   0.179 
## estrato       0.706  -0.222   0.387 
## preciom       0.914   0.170         
## areaconst     0.658   0.519  -0.194 
## parqueaderos  0.678   0.115   0.156 
## banios        0.625   0.559   0.265 
## habitaciones  0.126   0.871         
## 
##                Factor1 Factor2 Factor3
## SS loadings      2.634   1.489   0.362
## Proportion Var   0.329   0.186   0.045
## Cumulative Var   0.329   0.515   0.561
## 
## Test of the hypothesis that 3 factors are sufficient.
## The chi square statistic is 167.84 on 7 degrees of freedom.
## The p-value is 7.17e-33

Según la matriz, el factor 1 que representa el 42.9% tiene una fuerte correlación con el estrato, el precio, área construída, parqueaderos, baños y habitaciones; en el segundo factor que representa el 17.7% se relacionan el piso y para el tercer factor que representa el 12.6%, se relacionan con zona.

Consecuentemente, se gráficaran las componentes eledidas para este análisis

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

Explicación del gráfico.

Análisis de Conglomerados Clustering

En el análisis de conglomerados o Cluestering, se requiere agrupar las propiedades residenciales en segmentos homogéneos con características similares para entender las dinámicas de las ofertas específicas en diferentes partes de la ciudad y en diferentes estratos socioeconómicos.

Para este análisis, en primer lugar, se seleccionaron las siguientes variables

vivienda_cong <- data_filtrada [1:8319,2:9]
vivienda_cong

Posteriormente, se estandarizan las variables para que la media sea cero y la desviación estándar cercana a 1.

vivienda_cong <- scale(vivienda_cong)
vivienda_cong <- as.data.frame(vivienda_cong)
head(vivienda_cong)

Ahora, se evalua el número del cluster, por diferentes métodos, como se muestra a continuación:

  1. Usando el criterio del Gráfico de Silueta

Este método utiliza el criterio del gráfico que reduce el número de cluster.

set.seed(123)
fviz_nbclust(vivienda_cong, kmeans, method = "silhouette") +
  labs(subtitle = "Silhouette method")

Según este gráfico, deberían hacerse 2 cluster para agrupamiento que involucren las características del las zonas de la ciudad en relación a las ofertas inmobiliarias.

  1. Usando el criterio de Suma de Cuadrados dentro de clusters

Con este método de la suma de cuadrados dentro de cluster

set.seed(123)
wss <- numeric()
for(h in 1:10){
  b<-kmeans(vivienda_cong,h)
  wss[h]<-b$tot.withinss #scintra
}
wss 
##  [1] 66544.00 47701.98 42333.04 37020.62 32608.46 28640.80 27461.07 25417.91
##  [9] 24044.88 23151.57
wss1 <- data.frame(cluster=c(1:10),wss)
wss1

Usamos la libreria ggplot2 para el gráfico de los cluster según la suma de cuadrados dentro de cluster

ggplot(wss1) + aes(cluster,wss) + geom_line(color="blue") + 
  geom_point(color="blue") +
  geom_vline(xintercept = 3, linetype = 2, col="red") +
  labs(title = "Método Elbow") + 
  scale_x_continuous(breaks=1:10) +
  theme_classic()

Según este método deben de tenerse 3 cluster para agrupar las propiedades y similitudes de la oferta inmobiliaria con base a la ubicación de las zonas de la ciudad de Cali.

3.Método de particion: K-means

Para el método de K-means, se realiza la división del conjunto de datos inicial en K clústeres distintos y garantizando que ningún registro se sobreponga sobre otro o solo pertenezca a un solo clúster.

set.seed(123)
km <- kmeans(vivienda_cong, 
             centers=3,      # Número de Cluster
             iter.max = 100, # Número de iteraciones máxima
             nstart = 1,     # Número de puntos iniciales 
             algorithm = "Lloyd")
# Mostrar los clusters que pertenece cada individuo 
sample(km$cluster, 10)
##  [1] 2 2 3 1 1 1 2 1 2 3
clusters1 = km$cluster

# Tamaño de cada cluster
km$size
## [1] 2384 4673 1262

Con este método se obtiene el número de clúster y su tamaño, el cuál coincide con el de la suma de cuadrados; lo que indica que se deben de agrupar el conjunto de datos en 3 clúster con propiedades y caracteristicas similares entre ese grupo pero diferentes entre los otros grupos.

# Visualización de las soluciones usando ACP
library(factoextra)
fviz_cluster(km,data=vivienda_cong,ellipse.type = "convex") + 
  theme_classic()

Con este tipo de gráficos, se sustentan los análisis realizados por medio de los métodos expuestos, en donde aconsejan que se agrupen los datos de las ofertas inmobiliarias en Cali en 3 Clúster, esto con la finalidad de que puedan tener propiedades similares entre cada uno de estos y sea más estructurado el análisis por grupos, de acuerdo a las ofertas distribuidas en las zonas (Norte, Centro, Sur, Oriente, Oeste) en relación a sus estratos socieconómicos.

Para la evaluación de agrupaciones o clúster, es importante contar con los análisis de preprocesamiento de datos que tenían como conclusión que en los estratos 3 y 4 se encontraban en la zona Norte, Centro y Oriente; por otro lado, estaban los estratos 4, 5 y 6 que se ubicaban en las zonas Sur, Oeste y con algunos registros en la Zona Norte.

Análisis de Correspondencia

Examinar la relación entre las variables categóricas (tipo de vivienda, zona y barrio), para identificar patrones de comportamiento de la oferta en mercado inmobiliario.

Para identificar estos patrones, se hará con la variable zona y estrato socieconómico con el propósito de verificar su relación de dependencia.

vivienda_corr <- data_filtrada[, c(2, 4)]
head(vivienda_corr,5)

Ahora cruzaremos los valores para formar una tabla con estas variables

library(FactoMineR) 
tabla <- table(data_filtrada$zona, data_filtrada$estrato)
tabla 
##    
##        3    4    5    6
##   1  105   14    4    1
##   2  572  407  769  172
##   3   54   84  290  770
##   4  340    8    2    1
##   5  382 1616 1685 1043

Posterioremente se realizar una prueba de independencia, identificando si realmente existen asociaciones entre las categorías con respecto a la zona residencial y las categorías del estrato socioeconómico,

Se procede a comprobar esta hipótesis con la prueba de independencia Ji cuadrado, la cuál se ilustra a continuación:

chisq.test(tabla)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla
## X-squared = 3830.4, df = 12, p-value < 2.2e-16
#Estadístico de contraste
qchisq(0.95,4)
## [1] 9.487729

El estadístico de prueba tiene un valor es de 3830.4 resulta ser mayor al estadístico de contraste (9.487), esto quiere decir que existe suficiente evidencia estadística para rechazar la hipótesis nula y aceptar la alterna que indica presencia de asociaciones entre las zonas residencial y el estrato socieconomico, por lo tanto, resulta conveniente hacer uso de la técnica de correspondencia simple.

ACS <- CA(tabla, graph = FALSE)
#% de varianza explicado 
  valores_propios=ACS$eig; valores_propios
##       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
#Gráfica del porcentaje de varianza explicado
fviz_screeplot(ACS, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
  ylab("Porcentaje de varianza explicado") + xlab("Ejes")

Se hará uso de los ejes obtenidos, que para este caso 3 los que representan el 100% de la muestra

fviz_ca_biplot(ACS, repel = TRUE)+ggtitle("")+ylab("Eje 2(27.7%)")+xlab("Eje 1(70)")+ylim(-0.6,1.6)+xlim(-1.2,1.5)

De la representación simultánea se observar que existe una relación entre la Zona residencial Sur (5) y los estratos socieconómicos 4 y 5, por lo que se puede inferir que los inmuebles de esta zona tienen características relacionadas a estos estratos socioeconómicos que influyen directamente en el área construída y en el valor de los apartamentos o casas. Asimismo, ocurre con la Zona residencial Oeste (3), que hay presencia del estrato socieconómico 6, esto se debe a las características constructivas como el número de baños, habitaciones y también en su área constructiva y su precio; estas dos zonas son en las que los inmuebles son más costosos en comparación con las demás zonas residenciales y los estratos socieconómicos por debajo de 4.

Dado lo anterior, se concluye que efectivamente existe una relación de dependencia frente a las zona residencial y el estrato socieconómico, lo que quiere decir que si un estrato socieconómico es alto se encontrara en las zonas residenciales más costosas o donde los inmuebles adquieren un valor más elevado de acuerdo al promedio.

Asi, las decisiones estratégicas que debe asumir la inmobiliaria, se recomienda que estén alineadas a la relación de depende entre el estrato socieconómico y las zonas residenciales; donde también interviene el área construída y el precio de los inmuebles. Esto con la finalidad de optimizar la inversión en las zonas residencial con estratos socieconómicos por encima de 3, que son los que tienen las mejores garantías en ventas, sin dejar de discriminar el potencial que tendrían los estratos socieconómicos 3, localizados en la Zona Norte, los cuáles pueden convertirse en lugares estratégicos para la venta de inmuebles a precios intermedios para estratos medios de la ciudad de Cali.