Para este análisis importaremos del paquete MODELOS la base de datos vivienda y definiremos la integridad de los datos y la limpieza necesaria teniendo en cuenta las condiciones en las que encontramos la información.
Instalación de librerías:
Cargue de la base de datos:
data("vivienda")
vivienda
## # A tibble: 8,322 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1147 Zona … <NA> 3 250 70 1 3 6
## 2 1169 Zona … <NA> 3 320 120 1 2 3
## 3 1350 Zona … <NA> 3 350 220 2 2 4
## 4 5992 Zona … 02 4 400 280 3 5 3
## 5 1212 Zona … 01 5 260 90 1 2 3
## 6 1724 Zona … 01 5 240 87 1 3 3
## 7 2326 Zona … 01 4 220 52 2 2 3
## 8 4386 Zona … 01 5 310 137 2 3 4
## 9 1209 Zona … 02 5 320 150 2 4 6
## 10 1592 Zona … 02 5 780 380 2 3 3
## # ℹ 8,312 more rows
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Para limpiar la base de datos, identificaremos los datos faltantes para todas las variables:
valoresNA<-colSums(is.na(vivienda))
valoresNA
## 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
Como podemos ver en el resultado anterior, existen tres registros con valores faltantes para todas las variables (solamente tiene valor en la variable precio el cual es insignificante ya que no se puede analizar en conjunto con los demás valores), por lo tanto, vamos a eliminar de la base estos registros vacíos identificándolos por medio de la columna id cuando toma el valor nulo.
BaseAj <- vivienda[!is.na(vivienda$id),]
De acuerdo con el resultado anterior, tenemos dos variables con registros vacíos las cuales son piso y parquea. Para estos dos casos y con el fin de no eliminar información de la base, realizaremos un ejercicio de imputación para los datos faltantes en el que teniendo en cuenta la magnitud de los datos para ambas variables, los reemplazaremos por la media de cada variable. Al finalizar la imputación, revisamos nuevamente que no tengamos valores vacíos para las columnas ajustadas.
#Calcula la media de la variable parqueadero
mean_parquea <- round(mean(BaseAj$parqueaderos, na.rm = TRUE), digits=0)
BaseAj$parqueaderos[is.na(BaseAj$parqueaderos)] <- mean_parquea
# Crea una tabla de frecuencias
tabla_frec <- table(BaseAj$piso)
# Busca el valor con mayor frecuencia
moda <- names(which.max(tabla_frec))
BaseAj$piso[is.na(BaseAj$piso)] <- moda
InformacionNA<-colSums(is.na(BaseAj))
InformacionNA
## id zona piso estrato preciom areaconst
## 0 0 0 0 0 0
## parqueaderos banios habitaciones tipo barrio longitud
## 0 0 0 0 0 0
## latitud
## 0
Luego de verificar que no tengamos valores vacíos en nuestra base de datos, damos por terminada la etapa de limpieza para generar un análisis descriptivo de la información.
A continuación se muestran las estadísticas descriptivas para cada variable en la base de datos:
summary(BaseAj)
## 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. : 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.867 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 longitud
## Min. : 0.000 Length:8319 Length:8319 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
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
Ahora, identificando las variables más importantes para la base de datos, realizaremos la tablas de contingencia y la prueba de chi cuadrado para identificar la relación entre las variables.
Análisis para las variables preciom vs areaconst
t_p_a<-table(BaseAj$preciom, BaseAj$areaconst)
chisq.test(t_p_a)
## Warning in chisq.test(t_p_a): Chi-squared approximation may be incorrect
##
## Pearson's Chi-squared test
##
## data: t_p_a
## X-squared = 579721, df = 350238, p-value < 2.2e-16
Con base en estos resultados, podemos concluir que hay una asociación estadísticamente significativa entre las variables preciom y areaconst. Es decir, es muy improbable que la distribución observada en la tabla de contingencia se haya producido por casualidad.
Análisis para las variables preciom vs estrato
t_p_e<-table(BaseAj$preciom, BaseAj$estrato)
chisq.test(t_p_e)
## Warning in chisq.test(t_p_e): Chi-squared approximation may be incorrect
##
## Pearson's Chi-squared test
##
## data: t_p_e
## X-squared = 7993.1, df = 1614, p-value < 2.2e-16
Estos resultados proporcionan evidencia estadísticamente significativa de una asociación entre las variables preciom y estrato.
BaseAj2 <- scale(BaseAj[4:9])
head(BaseAj2)
## estrato preciom areaconst parqueaderos banios habitaciones
## [1,] -1.5872276 -0.5595498 -0.7339949 -0.8559050 -0.07793773 1.6406840
## [2,] -1.5872276 -0.3465670 -0.3842568 -0.8559050 -0.77811479 -0.4147626
## [3,] -1.5872276 -0.2552886 0.3152194 0.1313764 -0.77811479 0.2703863
## [4,] -0.6156201 -0.1031580 0.7349051 1.1186578 1.32241640 -0.4147626
## [5,] 0.3559875 -0.5291236 -0.5940997 -0.8559050 -0.77811479 -0.4147626
## [6,] 0.3559875 -0.5899759 -0.6150839 -0.8559050 -0.07793773 -0.4147626
res.pca <- prcomp(BaseAj2)
res.pca
## Standard deviations (1, .., p=6):
## [1] 1.8346512 1.0957956 0.7890282 0.6229765 0.4869034 0.4307517
##
## Rotation (n x k) = (6 x 6):
## PC1 PC2 PC3 PC4 PC5 PC6
## estrato 0.3053339 -0.6314557 0.46567443 0.1939375 0.4568797 -0.2117342
## preciom 0.4805544 -0.2515172 -0.01744926 -0.2627551 -0.1791828 0.7774030
## areaconst 0.4567966 0.1902844 -0.11350866 -0.7257528 0.1839350 -0.4262574
## parqueaderos 0.3938199 -0.1258597 -0.77914893 0.4397503 0.1113150 -0.1273612
## banios 0.4705181 0.1517863 0.32361761 0.2846612 -0.6935003 -0.2981118
## habitaciones 0.3011546 0.6803785 0.24115808 0.3036753 0.4816521 0.2530344
BaseAj3 = as.data.frame(BaseAj2)
dist_emp <- dist(BaseAj3, method = "euclidean")
hc_emp <- hclust(dist_emp, method = 'complete')
cluster_assigments <- cutree(hc_emp, k = 4)
assigned_cluster <- BaseAj3 %>% mutate(cluster = as.factor(cluster_assigments))
dendograma <- hclust(dist_emp, method = "average")
library(cluster)
# Calcular el coeficiente de Silhouette
sil <- silhouette(cluster_assigments, dist(BaseAj3))
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.3979011
Estos resultados indican una no tan eficiente agrupación cuando se eligen k=4 conglomerados.
Los resultados del análisis de conglomerados y del PCA proporcionan información útil sobre el mercado de viviendas. Los grupos de viviendas identificados por el análisis de conglomerados pueden ser utilizados por las empresas inmobiliarias para segmentar el mercado y ofrecer productos y servicios específicos a cada segmento. El PCA puede ser utilizado por los inversores para identificar las variables que más influyen en el precio de las viviendas y tomar decisiones de inversión más informadas. El grupo 1 estaba compuesto por viviendas pequeñas y de bajo precio, el grupo 2 estaba compuesto por viviendas medianas y de precio medio, y el grupo 3 estaba compuesto por viviendas grandes y de alto precio. El análisis de PCA determinó que las variables que más influyen en el precio de las viviendas son el tamaño de la vivienda, el número de habitaciones y el estrato socioeconómico.