SITUACIÓN

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.

library(devtools)
devtools::install_github("dgonxalex80/paqueteMODELOS", force = TRUE)
## xfun (0.41 -> 0.42) [CRAN]
## package 'xfun' successfully unpacked and MD5 sums checked
## 
## The downloaded binary packages are in
##  C:\Users\Familia GSM\AppData\Local\Temp\RtmpsBaaVu\downloaded_packages
## ── R CMD build ─────────────────────────────────────────────────────────────────
##   
  
  
   checking for file 'C:\Users\Familia GSM\AppData\Local\Temp\RtmpsBaaVu\remotesecc2d69663e\dgonxalex80-paqueteMODELOS-796f588/DESCRIPTION' ...
  
   checking for file 'C:\Users\Familia GSM\AppData\Local\Temp\RtmpsBaaVu\remotesecc2d69663e\dgonxalex80-paqueteMODELOS-796f588/DESCRIPTION' ... 
  
✔  checking for file 'C:\Users\Familia GSM\AppData\Local\Temp\RtmpsBaaVu\remotesecc2d69663e\dgonxalex80-paqueteMODELOS-796f588/DESCRIPTION' (980ms)
## 
  
  
  
─  preparing 'paqueteMODELOS': (494ms)
##    checking DESCRIPTION meta-information ...
  
✔  checking DESCRIPTION meta-information
## 
  
  
  
─  checking for LF line-endings in source and make files and shell scripts
## 
  
  
  
─  checking for empty or unneeded directories
## 
  
  
  
─  building 'paqueteMODELOS_0.1.0.tar.gz'
## 
  
   
## 
library(paqueteMETODOS)
library(dplyr)
data(vivienda)
head(vivienda)

RETO

El reto principal consisten en realizar un análisis integral y multidimensional de la base de datos para obtener una comprensión del mercado inmobiliario urbano. Se requiere aplicar diversas técnicas de análisis de datos, incluyendo:ANÁLISIS DE COMPONENTES PRINCIPALES, ANÁLISIS DE CONGLOMERADOS, ANÁLISIS DE CORRESPONDENCIA.

Reconocimiento y limpieza de los datos:

Procedemos a identificar el tipo de variables, identifcar datos faltantes e imputar en caso necesario.

vivienda <- vivienda[!is.na(vivienda$id),] #Eliminamos los faltantes en Id asumiendo que se trata de errores en los datos, no deberían existir ID faltantes
vivienda = select (vivienda, id:tipo)
vivienda = select (vivienda, -id)
summary(vivienda)
##      zona               piso              estrato         preciom      
##  Length:8319        Length:8319        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  
##                                                                        
##    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   :1602                                      
##      tipo          
##  Length:8319       
##  Class :character  
##  Mode  :character  
##                    
##                    
##                    
## 

Encontramos que la variable ID es solo informativa, por lo tanto, la eliminamos. Las variables zona, piso, tipo, barrio las está comando como de caracter.

Como características de estas viviendas encontramos que pueden ser casas o apartamentos, van del estrato 3 al 6, con áreas construídas desde los 30 metros cuadrados hasta los 1745 metros, en promedio el área construída es de 174 metros cuadrados.En relación con las condiciones de las viviendas, existen algunas sin baños o hasta con 10 baños, las habitaciones van de 0 a 10, siendo 3 el promedio. Pueden tener desde ningún parqueadero hasta 10 parqueaderos. Las características de cada vivienda varían según el tipo, la zona y el estrato. Dado que no es el objetivo del presente estudio, no ahondaremos en estos detalles.

Continuando con la exploración de los datos, en el resultado podemos también ver que hay datos faltantes, la variable que más datos tiene faltantes es piso y parqueadero:

library(naniar)
library(ggplot2)
gg_miss_var(vivienda)

library(mice)
grafico <- md.pattern(vivienda, rotate.names = TRUE)

# Estandarizamos el nombre de las variables "tipo"antes de transformarlas a numéricas para el PCA:
vivienda$tipo <- toupper(vivienda$tipo)
vivienda$zona <- toupper(vivienda$zona)
vivienda$tipo<- ifelse(vivienda$tipo=='CASA','CASA','APARTAMENTO')
# Nos está reconociendo la variable piso como caracter y no número, por lo que debemos convertirla en numérica
vivienda$piso <- as.numeric(as.character(vivienda$piso))
str(vivienda$piso)
##  num [1:8319] NA NA NA 2 1 1 1 1 2 2 ...
summary(vivienda$piso)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   1.000   2.000   3.000   3.771   5.000  12.000    2635

Teniendo la variable en forma numérica, realizaremos la imputación por la mediana dado que la variable no se distribuye de manera normal -lo sabemos por el conocimiento previo de los datos en el ejercicio del semestre anterior.

vivienda$piso[is.na(vivienda$piso)]<-3
summary(vivienda$piso)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   1.000   2.000   3.000   3.527   4.000  12.000

En relación con la variable parqueadero, el mínimo de parqueadero es 1, el máximo es 10, la media y mediana serían 2 (si aproximamos la media) y el rango es 9. Hay 1603 NA, podríamos suponer que esos NA corresponden al valor 0, pues es probable que varias viviendas no cuenten con parqueadero, ya sabemos que la distriución de NA es similar entre casa y apartamento. Para efecto práctico, podríamos suponer que al no tener una opción de respuesta en 0, podríamos imputar los datos faltantes por 0.

vivienda$parqueaderos[is.na(vivienda$parqueaderos)]<-0
summary(vivienda$parqueaderos)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   1.000   1.000   1.482   2.000  10.000

Y verificamos si aún nos quedan datos faltantes:

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

Convertir variables categóricas a numéricas:

Ahora estamos seguros que no hay datos faltantes. Procedemos entonces a convertir las variables categóricas - Zona y Tipo - a numéricas para realizar luego el ACP:

table(vivienda$zona)
## 
##  ZONA CENTRO   ZONA NORTE   ZONA OESTE ZONA ORIENTE     ZONA SUR 
##          124         1920         1198          351         4726
vivienda <- vivienda %>% mutate(zonaN = case_when (
    zona == "ZONA CENTRO" ~ 1,
    zona == "ZONA NORTE" ~ 2,
    zona == "ZONA OESTE" ~ 3,
    zona == "ZONA ORIENTE" ~ 4,
    zona == "ZONA SUR" ~ 5, ))
vivienda$zonaN <- as.numeric(vivienda$zonaN)
head(vivienda)
table(vivienda$tipo)
## 
## APARTAMENTO        CASA 
##        5100        3219
vivienda <- vivienda %>% mutate(tipoN = case_when (
    tipo == "APARTAMENTO" ~ 1,
    tipo == "CASA" ~ 2 ))
vivienda$tipoN <- as.numeric(vivienda$tipoN)
head(vivienda)
#Dejamos solo variables numéricas:
vivienda2 <- vivienda %>% select(-zona, -tipo)
head (vivienda2)

Identificar correlación entre variables:

Correlacionamos las variables para comprender las relaciones entre ellas y evaluar la fuerza y dirección de esas relaciones:

# Hacemos una matriz de correlación:

library(corrplot)
matrizcor <- cor(vivienda2)
corrplot (matrizcor, method = "number", number.cex = 0.5)

Las correlaciones más fuertes son:

Positivas: preciom y estrato: 0.61 preciom y áreaconst: 0.69 preciom y parqueaderos:0.64 preciom y banios: 0.67 areaconst y banios: 0.65

Negativas:

Las correlaciones negativas se observan débiles, siendo la más fuerte entre -0.38 entre tipo y piso, lo cual no tendría mucha aplicación práctica.

Estandarizar variables numéricas:

Estandarizamos las variables para que tengan media 0 y desviación estándar 1 esto nos ayuda a estandarizar las distancias entre observaciones. Al estandarizar lo que se hace es restar la media y dividir por la desviación estándar de cada variable.

Esto nos permite comparar directamente las magnitudes de las variables, ya que todas están en la misma escala. Esto es útil cuando las variables tienen unidades diferentes o escalas muy distintas.Nos puede ayudar a garantizar que todas las variables tengan un impacto similar en el modelo que se está realizando.

viviendapACP <- scale(vivienda2)
head(viviendapACP)
##            piso    estrato    preciom  areaconst parqueaderos      banios
## [1,] -0.2404274 -1.5872276 -0.5595498 -0.7339949   -0.3875522 -0.07793773
## [2,] -0.2404274 -1.5872276 -0.3465670 -0.3842568   -0.3875522 -0.77811479
## [3,] -0.2404274 -1.5872276 -0.2552886  0.3152194    0.4168506 -0.77811479
## [4,] -0.6968663 -0.6156201 -0.1031580  0.7349051    1.2212534  1.32241640
## [5,] -1.1533052  0.3559875 -0.5291236 -0.5940997   -0.3875522 -0.77811479
## [6,] -1.1533052  0.3559875 -0.5899759 -0.6150839   -0.3875522 -0.07793773
##      habitaciones       zonaN      tipoN
## [1,]    1.6406840  0.06192582  1.2586312
## [2,]   -0.4147626  0.06192582  1.2586312
## [3,]    0.2703863  0.06192582  1.2586312
## [4,]   -0.4147626  0.81508501  1.2586312
## [5,]   -0.4147626 -1.44439256 -0.7944184
## [6,]   -0.4147626 -1.44439256 -0.7944184

ANÁLISIS DE COMPONENTES PRINCIPALES

Reducir la dimensionalidad del conjunto de datos y visualizar la estructura de las variables en componentes principales para identificar características clave que influyen en la variación de precios y oferta del mercado:

viviACP <- prcomp(viviendapACP)
viviACP
## Standard deviations (1, .., p=9):
## [1] 1.9185623 1.3325574 1.0129156 0.9157328 0.6940268 0.6607266 0.5798833
## [8] 0.4899315 0.4293186
## 
## Rotation (n x k) = (9 x 9):
##                      PC1          PC2         PC3           PC4         PC5
## piso          0.10167301  0.418094277 -0.27721900  0.7877193977  0.28479191
## estrato      -0.26269473  0.528003715  0.07660283 -0.2195491505 -0.37071351
## preciom      -0.43544109  0.254933024 -0.10000087 -0.1268264516  0.09316786
## areaconst    -0.44347033 -0.104890890 -0.11433597  0.0054019243  0.31047640
## parqueaderos -0.36916330  0.283660392  0.08356206 -0.1185759178  0.37840591
## banios       -0.45235228  0.001375948 -0.05067375  0.1891747641 -0.39091479
## habitaciones -0.31699964 -0.395081852 -0.09360763  0.4176150241 -0.45033454
## zonaN        -0.05481869  0.058549539  0.93428073  0.3015499679  0.03803197
## tipoN        -0.29996868 -0.480034871  0.05491284 -0.0004003058  0.41968581
##                       PC6         PC7         PC8          PC9
## piso          0.110045218 -0.15080943 -0.03864123 -0.007384819
## estrato       0.262339350 -0.39469106 -0.47097464  0.119520505
## preciom       0.239073698  0.26288786  0.22571418 -0.730357230
## areaconst     0.325483720  0.51511861 -0.26090063  0.493435407
## parqueaderos -0.777230003 -0.07829913 -0.05267398  0.077650245
## banios       -0.005158907 -0.15269511  0.67836774  0.347391752
## habitaciones -0.293455729  0.10503144 -0.43899624 -0.259980951
## zonaN         0.102586714  0.12660003  0.01927249 -0.037209263
## tipoN         0.234986893 -0.65613455 -0.04033918 -0.114345596

Para saber cuántos componenter principales podemos utilizar que puedan explicar la mayoría de la varianza, podemos verlo gráficamente. Este gráfico muestra barras para cada componente principal, indicando la proporción de varianza explicada por cada uno. También muestra la acumulación de varianza explicada en función del número de componentes principales:

library(ggplot2)
library(ggsignif)
library(factoextra) #Para visualizar valores propios del ACP - es útil para entender la proporción de varianza explicada por cada componente principal.


PlotPCA <- fviz_eig(viviACP, addlabels = TRUE, ylim = c(0, 55))
PlotPCA + ggtitle("Gráfico de Valores Propios en Análisis de Componentes Principales")

La gráfica nos muestra 9 componentes, los cuatro primeros componentes explican el 81,3% de la varianza y los 6 primeros explican el 91,6%.

Proporción de varianza explicada:

Medida que indica cuánta variabilidad de los datos originales es capturada por cada componente principal.

# Proporción de varianza explicada por cada uno de los componentes:

varianza_expl <- viviACP$sdev^2/sum(viviACP$sdev^2)
round(varianza_expl*100, 2)
## [1] 40.90 19.73 11.40  9.32  5.35  4.85  3.74  2.67  2.05

Nos genera el mismo resultado que podemos observar en el gráfico anterior en las líneas. El primer componente principal explica aproximadamente el 40.90% de la varianza en los datos.El segundo componente principal explica aproximadamente el 19.73% de la varianza adicional. Así sucesivamente, hasta el noveno componente principal.

También podemos observar gráficamente qué variables tienen un mayor peso en cada uno de los componentes PC1 y PC2…

#Revisando las variables con mayores contribuciones del primer componente principal:

fviz_contrib(viviACP, choice = "var", axes = 1, top = 10)

Podemos observar en el gráfico anterior que la variable que más influye en el primer componente es la de baños, con un poco más del 20% de contribución, en segundo lugar área construída, en tercer lugar el precio y en cuarto lugar los parqueaderos. Estas variables presentan una correlación positiva entre sí, ya que están agrupadas.

Detallando el segundo componente cuyas variables siguen teniendo correlación positiva y explican el resto de la varianza.:

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

En este segundo componente, las 4 variables que más influyen son el estrato, el tipo de vivienda, pisos y habitaciones.

Y podemos detallar también las variables que influyen en el tercer componente:

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

En este tercer componente, la explicación de la varianza es menor comparado con los dos primeros, la variable con influencia mayoritaria es la zona.

Podemos identifcar en la siguinte tabla la contribución de cada variable en estos tres primeros componentes:

get_pca_var(viviACP)$contrib[,1:3]
##                   Dim.1        Dim.2      Dim.3
## piso          1.0337402 1.748028e+01  7.6850375
## estrato       6.9008521 2.787879e+01  0.5867993
## preciom      18.9608945 6.499085e+00  1.0000175
## areaconst    19.6665934 1.100210e+00  1.3072714
## parqueaderos 13.6281543 8.046322e+00  0.6982618
## banios       20.4622586 1.893232e-04  0.2567829
## habitaciones 10.0488772 1.560897e+01  0.8762388
## zonaN         0.3005088 3.428049e-01 87.2880489
## tipoN         8.9981210 2.304335e+01  0.3015420

En la siguiente gráfica observaremos cómo las variables originales contribuyen a los componentes principales en el análisis de PCA. Aqui vemos como las variables que se nombraron en el los componentes como las más representativas, se muestran con mayor contribución.

fviz_pca_var(viviACP, col.var = "contrib", gradient.cols = c("#ff69b4",  "#5DC1B9"),
repel = TRUE)

Al visualizar las variables en el plano de los componentes principales permite identificar el sentido y la caracterización de los componentes. En este ejercicio el primer componente principal está asociado principalmente con la variables precio y estrato, mientras que el segundo componente se puede asociar a la variable área construída.También vemos que son importantes las variables habitaciones y tipo de vivienda. La zona y el piso tienen menor peso.

Así se puede observar el porcentaje acumulado de cada componente:

varianza_acum <- cumsum(varianza_expl)
round(varianza_acum*100, 2)
## [1]  40.90  60.63  72.03  81.35  86.70  91.55  95.29  97.95 100.00

Tal como lo explicamos anteriormente, los primeros 6 componentes explican el 91% de la varianza y los 7 primeros el 95,3%.

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 = "Proporción de varianza acumulada")

En el gráfico anterior vemos cómo se va a cumulando la varianza a medida que aumentan los componentes.

ANÁLISIS DE CONGLOMERADOS

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.

Los análisis de clusters o conglomerados es una técnica en estadística y aprendizaje no supervisado que tiene como objetivo dividir un conjunto de datos en grupos o “clusters” de manera que las observaciones dentro de un mismo grupo sean más similares entre sí que con las observaciones de otros grupos.

Es una técnica exploratoria que busca revelar estructuras subyacentes o patrones en los datos sin tener información previa sobre las etiquetas de clase. Dentro de cada grupo los objetos son más similares entre sí que con los de otros grupos.

Los algoritmos de agrupamiento utilizados pueden ser jerárquicos o no jerárquicos, dependiendo de si los grupos se construyen de forma iterativa a partir de subgrupos más pequeños.

Estandarización de variables:

Para realizar este análisis, se requiere la estandarización de las variables, lo cual ya realizamos en el dataset viviendaspACP, sin embargo lo haremos de nuevo para este análisis.

viviendaCL <- scale (vivienda2)
head(viviendaCL)
##            piso    estrato    preciom  areaconst parqueaderos      banios
## [1,] -0.2404274 -1.5872276 -0.5595498 -0.7339949   -0.3875522 -0.07793773
## [2,] -0.2404274 -1.5872276 -0.3465670 -0.3842568   -0.3875522 -0.77811479
## [3,] -0.2404274 -1.5872276 -0.2552886  0.3152194    0.4168506 -0.77811479
## [4,] -0.6968663 -0.6156201 -0.1031580  0.7349051    1.2212534  1.32241640
## [5,] -1.1533052  0.3559875 -0.5291236 -0.5940997   -0.3875522 -0.77811479
## [6,] -1.1533052  0.3559875 -0.5899759 -0.6150839   -0.3875522 -0.07793773
##      habitaciones       zonaN      tipoN
## [1,]    1.6406840  0.06192582  1.2586312
## [2,]   -0.4147626  0.06192582  1.2586312
## [3,]    0.2703863  0.06192582  1.2586312
## [4,]   -0.4147626  0.81508501  1.2586312
## [5,]   -0.4147626 -1.44439256 -0.7944184
## [6,]   -0.4147626 -1.44439256 -0.7944184

Selección del número de clusters:

Para determinar el número de clusters existen diferentes métodos, en esta ocasión aplicaré el método “Del codo”, se busca el “codo” en el gráfico, que es el punto donde la disminución en el WCSS se hace menos pronunciada. Este es un indicador del número óptimo de clusters:

set.seed(123)
wcss <- numeric(length = 10)

for (i in 1:10) {
  kmeans_model <- kmeans(viviendaCL, centers = i)
  wcss[i] <- kmeans_model$tot.withinss
}

plot(1:10, wcss, type = "b", pch = 19, frame = FALSE, 
     xlab = "Número de Clusters (k)", ylab = "WCSS", main = "Método del Codo")

La elección podría tener un componente subjetivo, sin embargo, Según la gráfica, podríamos decir que después de 2 clusters, la disminución se hace menos pronunciada. Por esto me quedaré con 2 clusters.

Ahora, generamos un nuevo dataset clasificando 2 clusters:

set.seed(123)

modelkmeans <- kmeans(viviendaCL, 2)
viviendaCL <- data.frame(viviendaCL, cluster = modelkmeans$cluster)

# Calcular medianas de todas las variables numéricas en 'vivienda'
resultados_agregados <- aggregate(. ~ cluster, data = viviendaCL[, -1], FUN = median)

# Mostrar los resultados
print(resultados_agregados)
##   cluster    estrato    preciom  areaconst parqueaderos     banios habitaciones
## 1       1  0.3559875  0.5966426  0.6894391    0.4168506  0.6222393    0.2703863
## 2       2 -0.6156201 -0.5595498 -0.5940997   -0.3875522 -0.7781148   -0.4147626
##      zonaN      tipoN
## 1 0.815085  1.2586312
## 2 0.815085 -0.7944184

i

# Para saber cuántos registros quedaron en cada cluster:

NCL = table(viviendaCL$cluster)
print(NCL)
## 
##    1    2 
## 2934 5385

Como se puede ver en la tabla, el cluster 2 quedó con mayor número de registros con 5385 y el cluster 1 con los 2934 restantes.

Análisis de clusters:

#Incluimos la variable cluster al dataset para posteriormente graficar:
viviendakmeans = kmeans(viviendaCL, centers = 2)
vivienda$cluster = viviendakmeans$cluster
vivienda$cluster = as.character(vivienda$cluster)
head(vivienda2)

Ya se visualiza la variable cluster como caracter.

Ahora generamos la gráfica:

fviz_cluster(list(data = viviendaCL[1:9], 
                  cluster = viviendaCL$cluster),  
             palette = c("#ff69b4", "#5DC1B9"),
             ellipse.type = "convex",
             repel = FALSE,  
             show.clust.cent = FALSE,
             ggtheme = theme_minimal())

En la gráfica se puede observar la mayor área de incluencia del cluster 1. Cada punto de datos es una observación en el conjunto de datos, elegí no marcar los centroides de los cluster, Al contar solo con 2 clusters, se observan claramente los agrupamientos. Esta gráfica bidimensional se utiliza de forma exploratoria.

Luego, Calculamos las medias de las variables para cada cluster:

mediaCL <- aggregate(cbind(piso, estrato, preciom, areaconst, parqueaderos,
             banios,  tipoN) ~ cluster,
             data = vivienda, FUN = mean)

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

Cluster

Piso

Estrato

Precio

Area construida

Parqueaderos

Baños

tipo

1

3.849954

4.387001

275.8908

102.8449

1.032312

2.334076

1.184773

2

2.933538

5.086230

723.9192

307.2474

2.306748

4.537832

1.758010

El análisis de cluster agrupa variables según sus atributos. En el cluster 2 agrupó viviendas más grandes, se observa la diferencia respecto al cluster 1, en el cual el área construída es menor y tiene menor precio, al ser más pequeñas, cuentan con menos baños y menos parqueaderos, también se observa menor estrato. En el cluster 1 están las viviendas más accesibles a la población general, mientras que en el cluster 2, las viviendas más grandes y costosas.

Por último, se mide el indice de Silhouette promedio con el fin de valorar la mejor alternativa para la elección del número de conglomerados:

library(tidyverse)
library(cluster)
# distancia euclidiana
dist_emp <- dist(viviendaCL, method = 'euclidean')

# Cluster jerarquico con el método complete
hc_emp <- hclust(dist_emp, method = 'complete')

# Determinamos a dónde pertenece cada observación
cluster_assigments <- cutree(hc_emp, k = 2)

# Calcular el coeficiente de Silhouette
sil <- silhouette(cluster_assigments, dist(viviendaCL))
sil_avg <- mean(sil[,3])

# Imprimir el coeficiente de Silhouette promedio
cat("Coeficiente de Silhouette promedio k=2 : ", sil_avg)
## Coeficiente de Silhouette promedio k=2 :  0.6120583

La interpretación del coeficiente de Silhouette promedio es que valores cercanos a 1 indican que las observaciones están bien clasificadas en sus clusters, mientras que valores cercanos a -1 indican que podrían estar mejor en clusters vecinos. Un valor cerca de 0 sugiere superposición entre clusters. En general, un coeficiente de Silhouette promedio más alto es deseable. En este caso, Un coeficiente de Silhouette promedio de 0.61 para k=2 indica que, en promedio, las observaciones están bien clasificadas en sus clusters. Las observaciones tienen una buena separación y no están demasiado cerca de los límites de los clusters vecinos.

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.

El Análisis de Correspondencia es un método estadístico utilizado para representar posibles asociaciones entre variables categóricas, es decir la asociación entre sus categorías, con el fin establecer si existe, patrones o estructuras en los datos

Este método estadístico es de tipo exploratorio y complementario de otros tipos de análisis como los modelos de regresión logístico.

Se convierte la variable estrato en tipo factor:

vivienda$estrato <- as.factor(vivienda$estrato)

Selecciono las variables requeridas:

vivicor <- table(vivienda$estrato, vivienda$zona)
vivicor
##    
##     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

Confirmamos que ho hay datos faltantes:

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

##   ZONA CENTRO ZONA NORTE ZONA OESTE ZONA ORIENTE ZONA SUR  
## 4           1          1          1            1        1 0
##             0          0          0            0        0 0

seguidamente realizamos una prueba de chi2 para validar el supuesto de independencia de los datos:

chisq.test(vivicor)
## 
##  Pearson's Chi-squared test
## 
## data:  vivicor
## X-squared = 3830.4, df = 12, p-value < 2.2e-16

Los resultados del chi cuadrado nos indican una evidencia contra de la hipótesis nula de independencia entre las variables. Osea que las variables están relacionadas de alguna manera y no son independientes.

Ahora estimamos las coordenadas para cada uno de los niveles de ambas variables y representarlas en un plano cartesiano:

library(FactoMineR)
library(factoextra)
library(gridExtra)
resultados_ac <- CA(vivicor)

El análisis de correspondencia nos permite entender la relación entre las variables Zona y Estrato y visualizar su agrupamiento en el espacio bidimensional. El gráfico nos permite establecer relaciones y validarlas así:

  • En las zonas oriente y centro se encuentran viviendas de estrato 3,
  • En las zonas sur y Norte se encuentran viviendas de estratos 4 y 5
  • En la zona Oeste se encuentran viviendas del estrato 6

Para medir el grado de representatividad del proceso calculamos los valores de la varianza acumulada, utilizando para ellos los valores propios de la matriz de discrepancias:

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

Los resultados de valores propios obtenidos son útiles para comprender cuánto de la varianza está siendo capturada por cada dimensión, lo que puede ayudar en la reducción de dimensionalidad y en la interpretación de la estructura de los datos. La primera dimensión primera dimensión explica aproximadamente el 69.97% de la varianza total, la segunda dimensión el 27,68% y la tercera explica solo el 2,35% restante. Las dos primeras dimensiones explican el 97,64% de la varianza total de los datos.

Esto lo podemos ver representado en la siguiente gráfica:

fviz_screeplot(resultados_ac, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")

VISUALIZACIÓN DE RESULTADOS

Presentar gráficos, mapas y otros recursos visuales para comunicar los hallazgos de manera clara y efectiva a la dirección de la empresa.

Este apartado ya se trabajó en cada uno de los ítems presentados explicando las gráficas generadas.

CONCLUSIONES

Recomendaciones específicas para guiar las decisiones estratégicas de la empresa inmobiliaria. Se espera que este análisis de datos proporcione ventajas competitivas en el mercado, optimizando la inversión y maximizando los beneficios en un entorno altamente competitivo y en constante cambio.

Informe para Inmobiliaria:

Estimados miembros de la inmobiliaria A&C,

Se revisaron los datos de ofertas de vivienda publicadas en el portal de Fincaraiz relacionados con oferta de viviendas en la ciudad de Cali:

En el periodo revisado, para la ciudad de Cali, se ofertaron 8.319 viviendas ubicados etre los estratos 3 y 6 principalmente en la zona Sur, con áreas construídas que varían entre 30 y 1.745 metros cuadrados, la mediana del área construida es de 123 metros cuadrados.

Los precios de las viviendas varían desde 58 hasta 1999 millones. A mayor área construída, mayor es el precio, también está directamente relacionado con el estrato.

El análisis de componentes principales nos muestra una reducción de la dimensionalidad donde el primer componente que nos explica la mayor variabilidad representa el 40.9% y se relaciona predominantemente con los atributos de precio y las características de las viviendas según el área construída, como el número de baños o parqueaderos. El segundo componente agrupa otros atributos como las diferencias en la clasificación socioeconómica y explica un 19.7% se tienen en cuenta aquí con mayor representatividad el estrato y el tipo de vivienda.

Al realizar una agrupación de variables para hacer un análisis por conglomerados, podemos ver dos grandes grupos, un grupo con viviendas más accesibles a la población, pero con menor oferta en el mercado, al rededor del estrato 4, con precios medios de 275 millones y áreas construídas promedio de 102 metros cuadrados. Por otro lado se agruparon viviendas de estratos superiores, con mayor disponibilidad de oferta y mayores precios, su precio medio está en 723 millones, área cosntruída promedio de 307 metros cuadrados, por lo tanto mayores comodidades reflejadas en mayor número de parqueaderos y baños. Lo anterior nos da una idea que la mayor venta de vivienda se encuentra en estratos inferiores con precios más accesibles.

Finalmente, en el análisis de correspondencia podemos observar la relación que hay entre los estratos y las zonas donde están ubicadas las viviendas. Con esta relación sería útil establecer la construcción de proyectos con características específicas según los clientes objetivo.