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(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ó:
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.
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
# 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")
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.
# 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.
# 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.
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.
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.
En la proporción de la varianza indica la contribución de cada componente principal a la variabilidad total de los datos originales.
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.
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.
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")
El análisis de correspondencia proporciona coordenadas para cada nivel de las variables ‘zona’ y ‘estrato’, lo que permite explorar las relaciones entre ellas.
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.
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.