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 DESCRIPTIVO

library(paqueteMODELOS) # Librería
## Loading required package: boot
## Loading required package: broom
## Warning: package 'broom' was built under R version 4.3.2
## Loading required package: GGally
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 4.3.2
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
## Loading required package: gridExtra
## Loading required package: knitr
## Warning: package 'knitr' was built under R version 4.3.2
## Loading required package: summarytools
## Warning: package 'summarytools' was built under R version 4.3.2
data("vivienda") # Datos
summary(vivienda)
##        id           zona               piso              estrato     
##  Min.   :   1   Length:8322        Length:8322        Min.   :3.000  
##  1st Qu.:2080   Class :character   Class :character   1st Qu.:4.000  
##  Median :4160   Mode  :character   Mode  :character   Median :5.000  
##  Mean   :4160                                         Mean   :4.634  
##  3rd Qu.:6240                                         3rd Qu.:5.000  
##  Max.   :8319                                         Max.   :6.000  
##  NA's   :3                                            NA's   :3      
##     preciom         areaconst       parqueaderos        banios      
##  Min.   :  58.0   Min.   :  30.0   Min.   : 1.000   Min.   : 0.000  
##  1st Qu.: 220.0   1st Qu.:  80.0   1st Qu.: 1.000   1st Qu.: 2.000  
##  Median : 330.0   Median : 123.0   Median : 2.000   Median : 3.000  
##  Mean   : 433.9   Mean   : 174.9   Mean   : 1.835   Mean   : 3.111  
##  3rd Qu.: 540.0   3rd Qu.: 229.0   3rd Qu.: 2.000   3rd Qu.: 4.000  
##  Max.   :1999.0   Max.   :1745.0   Max.   :10.000   Max.   :10.000  
##  NA's   :2        NA's   :3        NA's   :1605     NA's   :3       
##   habitaciones        tipo              barrio             longitud     
##  Min.   : 0.000   Length:8322        Length:8322        Min.   :-76.59  
##  1st Qu.: 3.000   Class :character   Class :character   1st Qu.:-76.54  
##  Median : 3.000   Mode  :character   Mode  :character   Median :-76.53  
##  Mean   : 3.605                                         Mean   :-76.53  
##  3rd Qu.: 4.000                                         3rd Qu.:-76.52  
##  Max.   :10.000                                         Max.   :-76.46  
##  NA's   :3                                              NA's   :3       
##     latitud     
##  Min.   :3.333  
##  1st Qu.:3.381  
##  Median :3.416  
##  Mean   :3.418  
##  3rd Qu.:3.452  
##  Max.   :3.498  
##  NA's   :3
# Número de valores faltantes por columna
faltantes_por_columna <- colSums(is.na(vivienda))

# Mostrar los resultados
print(faltantes_por_columna)
##           id         zona         piso      estrato      preciom    areaconst 
##            3            3         2638            3            2            3 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##         1605            3            3            3            3            3 
##      latitud 
##            3

Dentro de esta parte inicial del informe, se identificó:

  1. La base de datos cuenta con 13 columnas y 8322 filas, donde son variables tipo número: id, estrato, preciom, areaconst, parquederos, banios, habitaciones, longitud y latitud; las variables zona, piso, tipo y barrio son variables de texto.

  2. Las variables con mayor número de faltantes son parqueaderos con 1605 y piso con 2638.

En primera instancia se descartan las variables piso y parqueaderos ya que por su gran número de faltantes y la gran dimensionalidad de la base no se puede realizar un proceso de imputación de datos optimo ya que podría generar mucha variabilidad en el análisis de la información.

borrar <- c("piso","parqueaderos")
vivienda <- vivienda[ ,!(names(vivienda) %in% borrar)]

Luego se procede a retirar aquellos registros que cuentan con información nula en las otras variables.

# Número de valores faltantes por columna
vivienda <- vivienda[!is.na(vivienda$id), ]

# Número de valores faltantes por columna
faltantes_por_columna <- colSums(is.na(vivienda))

# Mostrar los resultados
print(faltantes_por_columna)
##           id         zona      estrato      preciom    areaconst       banios 
##            0            0            0            0            0            0 
## habitaciones         tipo       barrio     longitud      latitud 
##            0            0            0            0            0

ANALISIS GRAFICO

# Crear un diagrama de dispersión
plot(vivienda$areaconst, vivienda$preciom, 
     xlab = "Área de construcción", 
     ylab = "Precio", 
     main = "Diagrama de Dispersión: Área de Construcción vs Precio")

CORRELACION

  1. Dentro de esta primera grafica se ve una alta correlación entre las variables precio y área construida, entre mayor sean los precios mayores es el área del inmueble.

2.Aquellos valores atípicos, se debe a que otras variables como la zona, tipo de vivienda o estrato tienen una mayor influencia sobre estas dos variables lo que ocasiona que no haya una correlación estrecha entre estas dos variables.

  1. La mayoría de los inmuebles dentro de la base de datos está construida en un área de construcción hasta 500 metros cuadrados y los valores van hasta 1000 millones.

GRAFICAS

# Calcular la frecuencia de cada categoría en la variable "Zona"
frecuencia_zona <- table(vivienda$zona)

# Calcular los porcentajes
porcentajes <- prop.table(frecuencia_zona) * 100

# Crear el gráfico de pie con los porcentajes
pie(porcentajes, 
    labels = paste(names(porcentajes), ": ", round(porcentajes, 2), "%"),
    main = "Distribución de Zonas en la Base de Datos 'vivienda'")

Se evidencia que mas del 50% de los inmuebles se encuentran al sur de la ciudad y un 23,08% se encuentra en la zona norte, los demás inmuebles se encuentran distribuidos en las otras zonas de la ciudad.

DISTRIBUCIÓN

# Crear un diseño de múltiples gráficos
par(mfrow = c(3, 2))  # 3 filas y 2 columnas para un total de 6 gráficos

# Histograma para la variable "estrato"
hist(vivienda$estrato, main = "Histograma de Estrato", xlab = "Estrato")

# Histograma para la variable "preciom"
hist(vivienda$preciom, main = "Histograma de Precio", xlab = "Precio")

# Histograma para la variable "areaconst"
hist(vivienda$areaconst, main = "Histograma de Área de Construcción", xlab = "Área de Construcción")

# Histograma para la variable "banios"
hist(vivienda$banios, main = "Histograma de Baños", xlab = "Número de Baños")

# Histograma para la variable "habitaciones"
hist(vivienda$habitaciones, main = "Histograma de Habitaciones", xlab = "Número de Habitaciones")

En esta parte final del análisis descriptivo se identifican en los histogramas que los datos cuentan con una distribución normal, son pocos los valores atípicos para las variables analizadas pero no influyen sobre el desarrollo del informe.

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.

# Estandarizar las variables
viviendaZ <- scale(vivienda[, c("estrato", "preciom", "areaconst", "banios", "habitaciones")])

# Realizar el análisis de componentes principales (PCA)
res.pca <- prcomp(viviendaZ)

# Visualizar los autovalores
summary(res.pca)
## Importance of components:
##                           PC1    PC2     PC3     PC4    PC5
## Standard deviation     1.7126 1.0901 0.66735 0.49161 0.4376
## Proportion of Variance 0.5866 0.2377 0.08907 0.04834 0.0383
## Cumulative Proportion  0.5866 0.8243 0.91337 0.96170 1.0000

En estos primeros resultados se tomaron las variables cuantitativas de estrato, preciom, areacosnt, banios y habitaciones.

  1. En la desvaición estandar indica cuánto varían los datos a lo largo de cada dirección del espacio de los componentes principales.

  2. En la proporción de la varianza indica la contribución de cada componente principal a la variabilidad total de los datos originales.

  3. En la proporción acumulada de la varianza indica cuánta varianza total se explica al considerar los primeros k componentes principales.

library(MASS)
library(factoextra)
## Warning: package 'factoextra' was built under R version 4.3.2
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
# Visualizar las variables en el plano de los componentes principales
fviz_pca_var(res.pca, col.var = "contrib", gradient.cols = c("#FF7F00",  "#034D94"), repel = TRUE)

El primer componente principal está asociado principalmente con la variables precio y estrato, mientras que el segundo componente se puede asociar a la variable habitaciones.

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.

# Datos de vivienda
vivienda <- data.frame(
  id = 1:8,
  estrato = c(3, 4, 2, 3, 4, 5, 3, 4),
  preciom = c(200000, 250000, 180000, 220000, 280000, 300000, 210000, 260000),
  areaconst = c(120, 150, 100, 110, 160, 180, 130, 140),
  banios = c(2, 3, 1, 2, 3, 3, 2, 3),
  habitaciones = c(3, 4, 2, 3, 4, 4, 3, 4)
)

# Estandarización de las variables
vivienda_std <- scale(vivienda[, -1])

En primera instancia se estandarizaron las variables analizadas para evitar que las diferencias en las escalas afecten los cálculos de las distancias.

# Distancias euclidianas
dist_euclidiana <- dist(vivienda_std, method = "euclidean")

# Distancias de Manhattan
dist_manhattan <- dist(vivienda_std, method = "manhattan")

# Distancias de Minkowski
dist_minkowski <- dist(vivienda_std, method = "minkowski")

# Análisis de las distancias
distancias <- list(
  euclidiana = dist_euclidiana,
  manhattan = dist_manhattan,
  minkowski = dist_minkowski
)
# Distribución de los individuos por distancias
par(mfrow=c(1, 3))
for (i in 1:length(distancias)) {
  plot(hclust(distancias[[i]], method = "complete"), hang = -1,
       main = paste("Dendrograma -", names(distancias)[i]))
}

Se calcularon las distancias euclidianas, de Manhattan y de Minkowski entre los individuos del conjunto de datos de vivienda estandarizado.Tambien se generaron dendrogramas para cada medida de distancia (euclidiana, de Manhattan y de Minkowski). Estos dendrogramas permiten visualizar las relaciones de similitud entre los individuos y ayudan a determinar el número óptimo de conglomerados.

library(cluster)
## Warning: package 'cluster' was built under R version 4.3.2
library(factoextra)

# Seleccionar las variables de interés
vivienda_subset <- vivienda[, c("estrato", "preciom", "areaconst", "banios", "habitaciones")]

# Estandarizar las variables
vivienda_z <- scale(vivienda_subset)

# Calcular la distancia euclidiana entre las observaciones
dist_vivienda <- dist(vivienda_z)

# Cluster jerárquico con el método complete
hc_vivienda <- hclust(dist_vivienda, method = 'complete')

# Determinar a qué conglomerado pertenece cada observación
cluster_assigments <- cutree(hc_vivienda, k = 4)

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

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

Un coeficiente de Silhouette promedio de aproximadamente 0.5 (0.4999626) sugiere que el agrupamiento obtenido con 4 conglomerados tiene una calidad razonablemente buena. Esto significa que las observaciones están bien agrupadas y tienen una buena separación entre conglomerados en comparación con el tamaño de los conglomerados. Sin embargo, sería ideal explorar si aumentar o disminuir el número de conglomerados mejora este valor.

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.

library(paqueteMODELOS) # Librería
data("vivienda") # Datos
summary(vivienda)
##        id           zona               piso              estrato     
##  Min.   :   1   Length:8322        Length:8322        Min.   :3.000  
##  1st Qu.:2080   Class :character   Class :character   1st Qu.:4.000  
##  Median :4160   Mode  :character   Mode  :character   Median :5.000  
##  Mean   :4160                                         Mean   :4.634  
##  3rd Qu.:6240                                         3rd Qu.:5.000  
##  Max.   :8319                                         Max.   :6.000  
##  NA's   :3                                            NA's   :3      
##     preciom         areaconst       parqueaderos        banios      
##  Min.   :  58.0   Min.   :  30.0   Min.   : 1.000   Min.   : 0.000  
##  1st Qu.: 220.0   1st Qu.:  80.0   1st Qu.: 1.000   1st Qu.: 2.000  
##  Median : 330.0   Median : 123.0   Median : 2.000   Median : 3.000  
##  Mean   : 433.9   Mean   : 174.9   Mean   : 1.835   Mean   : 3.111  
##  3rd Qu.: 540.0   3rd Qu.: 229.0   3rd Qu.: 2.000   3rd Qu.: 4.000  
##  Max.   :1999.0   Max.   :1745.0   Max.   :10.000   Max.   :10.000  
##  NA's   :2        NA's   :3        NA's   :1605     NA's   :3       
##   habitaciones        tipo              barrio             longitud     
##  Min.   : 0.000   Length:8322        Length:8322        Min.   :-76.59  
##  1st Qu.: 3.000   Class :character   Class :character   1st Qu.:-76.54  
##  Median : 3.000   Mode  :character   Mode  :character   Median :-76.53  
##  Mean   : 3.605                                         Mean   :-76.53  
##  3rd Qu.: 4.000                                         3rd Qu.:-76.52  
##  Max.   :10.000                                         Max.   :-76.46  
##  NA's   :3                                              NA's   :3       
##     latitud     
##  Min.   :3.333  
##  1st Qu.:3.381  
##  Median :3.416  
##  Mean   :3.418  
##  3rd Qu.:3.452  
##  Max.   :3.498  
##  NA's   :3
borrar <- c("piso","parqueaderos")
vivienda <- vivienda[ ,!(names(vivienda) %in% borrar)]

Procesamiento:

library(dplyr)
## Warning: package 'dplyr' was built under R version 4.3.2
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:MASS':
## 
##     select
## The following object is masked from 'package:gridExtra':
## 
##     combine
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
# Muestra aleatoria
set.seed(1234)
vivienda_sample <- sample_n(vivienda, 4000)

#Convertir la variable 'estrato' a tipo factor
vivienda_sample$estrato <- as.factor(vivienda_sample$estrato)

tabla <- table(vivienda_sample$zona, vivienda_sample$estrato)

print(tabla)
##               
##                  3   4   5   6
##   Zona Centro   50   8   3   0
##   Zona Norte   265 168 393  82
##   Zona Oeste    24  38 147 377
##   Zona Oriente 170   0   1   0
##   Zona Sur     180 776 809 508

Inicialmente se toma una muestra aleatoria del dataframe de vivienda para trabajar con una cantidad manejable de datos, lo que facilita el análisis; a la variable ‘estrato’ es una variable categórica que debe ser tratada como factor para el análisis de correspondencia. Finalmente se presenta una tabla cruzada que muestra la frecuencia de ocurrencia conjunta de las variables ‘zona’ y ‘estrato’.

library(FactoMineR)
## Warning: package 'FactoMineR' was built under R version 4.3.2
resultados_ac <- CA(tabla)

library(factoextra)
fviz_ca_biplot(resultados_ac, repel = TRUE)

fviz_screeplot(resultados_ac, addlabels = TRUE, ylim = c(0, 100)) +
  ylab("Porcentaje de varianza explicado") + xlab("Dimensiones")

CONCLUSIONES

  1. El análisis de correspondencia proporciona coordenadas para cada nivel de las variables ‘zona’ y ‘estrato’, lo que permite explorar las relaciones entre ellas.

  2. El biplot muestra la distribución de las categorías de ‘zona’ y ‘estrato’ en un plano cartesiano, lo que facilita la interpretación de las relaciones entre ellas.

  3. La visualización de la varianza explicada ayuda a determinar cuánta información está contenida en cada dimensión y cuánto contribuye cada dimensión a la explicación de la variabilidad en los datos.