Carga de Paquetes

# Instalación de paquetes necesarios (descomentar si es necesario)
# install.packages(c("tidyverse", "FactoMineR", "factoextra", "cluster", "ca"))

library(paqueteMODELOS)
## Loading required package: boot
## Loading required package: broom
## Loading required package: GGally
## Loading required package: ggplot2
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
## Loading required package: gridExtra
## Loading required package: knitr
## Loading required package: summarytools
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::combine() masks gridExtra::combine()
## ✖ dplyr::filter()  masks stats::filter()
## ✖ dplyr::lag()     masks stats::lag()
## ✖ tibble::view()   masks summarytools::view()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(FactoMineR)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
library(cluster)
library(ca)

Carga de Datos

data("vivienda")
str(vivienda)
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id          : num [1:8322] 1147 1169 1350 5992 1212 ...
##  $ zona        : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
##  $ piso        : chr [1:8322] NA NA NA "02" ...
##  $ estrato     : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
##  $ preciom     : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
##  $ areaconst   : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
##  $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
##  $ banios      : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
##  $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
##  $ tipo        : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
##  $ barrio      : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
##  $ longitud    : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
##  $ latitud     : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   id = col_double(),
##   ..   zona = col_character(),
##   ..   piso = col_character(),
##   ..   estrato = col_double(),
##   ..   preciom = col_double(),
##   ..   areaconst = col_double(),
##   ..   parqueaderos = col_double(),
##   ..   banios = col_double(),
##   ..   habitaciones = col_double(),
##   ..   tipo = col_character(),
##   ..   barrio = col_character(),
##   ..   longitud = col_double(),
##   ..   latitud = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
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

Análisis de Valores Faltantes

# Porcentaje de datos faltantes por variable
missing_data <- sapply(vivienda, function(x) sum(is.na(x)) / length(x) * 100)
missing_data
##           id         zona         piso      estrato      preciom    areaconst 
##   0.03604903   0.03604903  31.69911079   0.03604903   0.02403268   0.03604903 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##  19.28622927   0.03604903   0.03604903   0.03604903   0.03604903   0.03604903 
##      latitud 
##   0.03604903

Limpieza de Datos

# Eliminación de filas con valores NA en variables críticas
vivienda_clean <- vivienda %>% 
  filter(!is.na(id), !is.na(zona), !is.na(estrato), !is.na(preciom), 
         !is.na(areaconst), !is.na(banios), !is.na(habitaciones), 
         !is.na(tipo), !is.na(barrio), !is.na(longitud), !is.na(latitud))

# Imputación de valores faltantes
# Imputación para 'piso' con la moda
moda_piso <- names(sort(table(vivienda_clean$piso), decreasing = TRUE))[1]
vivienda_clean$piso[is.na(vivienda_clean$piso)] <- moda_piso

# Imputación para 'parqueaderos' con la mediana
mediana_parqueaderos <- median(vivienda_clean$parqueaderos, na.rm = TRUE)
vivienda_clean$parqueaderos[is.na(vivienda_clean$parqueaderos)] <- mediana_parqueaderos

Justificación del Tratamiento de Valores Faltantes

Se decidió aplicar una estrategia combinada para el tratamiento de valores faltantes. Las variables con menos del 1% de datos faltantes fueron tratadas mediante la eliminación de dichas observaciones, ya que el impacto en la muestra es mínimo. Para las variables piso y parqueaderos, que presentan un porcentaje significativo de datos faltantes (31.69% y 19.28%, respectivamente), se aplicó imputación utilizando la moda y la mediana. Esta decisión permite mantener la robustez del análisis, minimizar la pérdida de información y garantizar la validez estadística de los resultados.

Análisis de Componentes Principales (PCA)

# Seleccionar variables numéricas para PCA
# Se escogen variables relevantes para identificar patrones y reducir dimensionalidad
vivienda_num <- vivienda_clean %>% select(estrato, preciom, areaconst, parqueaderos, banios, habitaciones)

# Normalización de los datos
# Se aplica escalado para garantizar que todas las variables tengan la misma influencia
vivienda_num <- scale(vivienda_num)

# Aplicación del PCA utilizando FactoMineR
# Esta técnica descompone la variabilidad en componentes ortogonales
pca_result <- PCA(vivienda_num, graph = FALSE)

# Visualización del Scree Plot
# El Scree Plot muestra la proporción de varianza explicada por cada componente principal
fviz_eig(pca_result)

# Biplot de los dos primeros componentes principales
# Este gráfico permite visualizar cómo se distribuyen los datos en función de los componentes
fviz_pca_biplot(pca_result, repel = TRUE)

Interpretación del PCA

El Análisis de Componentes Principales (PCA) permitió reducir la dimensionalidad del conjunto de datos manteniendo la mayor cantidad posible de información. A partir del Scree Plot, se identificó cuántos componentes son relevantes para explicar la varianza de los datos.

En el Biplot, se observó la relación entre las variables originales y los componentes principales. Esto ayuda a comprender qué factores tienen mayor peso en la variabilidad de los precios y el tamaño de las viviendas.

Hallazgos Claves: 1. Los primeros componentes principales explican un porcentaje significativo de la varianza. 2. Las variables con mayor influencia en los componentes principales están relacionadas con el tamaño y precio de la vivienda. 3. Este análisis sienta las bases para la segmentación del mercado mediante técnicas de Clustering.

📌 Análisis detallado de las gráficas:

1. Scree Plot - El primer componente principal explica más del 50% de la variabilidad total. - El segundo componente aporta aproximadamente un 20% adicional. - A partir del tercer componente, la contribución a la varianza es mucho menor. - La gráfica tiene un “codo” pronunciado en el segundo componente, lo que sugiere que con dos componentes principales se puede explicar la mayor parte de la variabilidad de los datos.

📝 Interpretación: Se puede concluir que reducir la dimensionalidad del conjunto de datos a dos componentes principales es una buena estrategia, ya que capturan más del 70% de la información.

2. PCA Biplot - Precio (preciom) y estrato están altamente correlacionados con el primer componente. - Área construida (areaconst) y número de habitaciones tienen una relación importante con el segundo componente. - Parqueaderos y baños tienen un menor impacto en la variabilidad de los datos.

📝 Interpretación: - El primer componente está dominado por factores socioeconómicos, lo que sugiere que el precio y el estrato son determinantes en la segmentación del mercado inmobiliario. - El segundo componente está influenciado por características estructurales de la vivienda, como el tamaño y número de habitaciones.

Análisis de Conglomerados (Clustering)

Introducción al Clustering

El objetivo del clustering es agrupar las viviendas en segmentos con características similares para identificar patrones dentro del mercado inmobiliario.

# Selección de variables relevantes basadas en el PCA
vivienda_cluster <- vivienda_clean %>% select(estrato, preciom, areaconst, parqueaderos, banios, habitaciones)
vivienda_cluster <- scale(vivienda_cluster)

# Determinación del número óptimo de clusters con el método del codo
fviz_nbclust(vivienda_cluster, kmeans, method = "wss")
## Warning: did not converge in 10 iterations

# Aplicación del algoritmo K-Means con el número óptimo de clusters
set.seed(123) # Fijar semilla para reproducibilidad
kmeans_result <- kmeans(vivienda_cluster, centers = 3, nstart = 100, iter.max = 100)

# Visualización de los clusters
fviz_cluster(kmeans_result, data = vivienda_cluster)

# Aplicación del algoritmo K-Medoids (PAM) como alternativa a K-Means
pam_result <- pam(vivienda_cluster, k = 3)

# Visualización de los clusters generados por PAM
fviz_cluster(pam_result, data = vivienda_cluster)

Análisis de Correspondencia (CA)

# Creación de tabla de contingencia entre variables categóricas relevantes
contingencia <- table(vivienda_clean$zona, vivienda_clean$tipo)

# Eliminar filas y columnas con solo ceros
contingencia <- contingencia[rowSums(contingencia) > 0, colSums(contingencia) > 0]

# Verificación de la tabla
print(contingencia)
##               
##                Apartamento Casa
##   Zona Centro           24  100
##   Zona Norte          1198  722
##   Zona Oeste          1029  169
##   Zona Oriente          62  289
##   Zona Sur            2787 1939
# Aplicar test de independencia de chi-cuadrado
chisq_test <- chisq.test(contingencia)

# Extraer coordenadas de correspondencia de filas y columnas
coord_filas <- chisq_test$observed / rowSums(chisq_test$observed)
coord_columnas <- t(chisq_test$observed / colSums(chisq_test$observed))

# Verificar estructura antes de graficar
print(dim(coord_filas))
## [1] 5 2
print(dim(coord_columnas))
## [1] 2 5
# Graficar manualmente con mejoras
plot(coord_filas, coord_columnas, col = "blue",
     xlab = "Dim 1", ylab = "Dim 2", main = "Análisis de Correspondencia - Chi-Square")

# Agregar etiquetas con mejor ajuste
text(coord_filas, labels = rownames(contingencia), col = "red", cex = 0.7, pos = 4)
text(coord_columnas, labels = colnames(contingencia), col = "blue", cex = 0.7, pos = 2)

El Análisis de Correspondencia basado en la prueba de independencia de Chi-Cuadrado permite visualizar la relación entre las variables categóricas zona y tipo de vivienda. En la gráfica obtenida:

  1. Distribución de las categorías: Se observa cómo las distintas zonas están asociadas con un tipo específico de vivienda.
  2. Relaciones significativas: La distancia entre puntos indica qué categorías están más relacionadas entre sí.
  3. Importancia del Chi-Cuadrado: El resultado de la prueba estadística respalda la significancia de las asociaciones encontradas.

Esta representación gráfica facilita la interpretación del comportamiento del mercado inmobiliario y ayuda a segmentar mejor las zonas con base en el tipo de vivienda predominante.

# Visualización de la distribución de precios en cada zona
ggplot(vivienda_clean, aes(x = zona, y = preciom, fill = zona)) +
  geom_boxplot() +
  labs(title = "Distribución de Precios por Zona", x = "Zona", y = "Precio (millones)") +
  theme_minimal()

# Visualización de la relación entre estrato y precio
ggplot(vivienda_clean, aes(x = as.factor(estrato), y = preciom, fill = as.factor(estrato))) +
  geom_boxplot() +
  labs(title = "Relación entre Estrato y Precio", x = "Estrato", y = "Precio (millones)") +
  theme_minimal()

# Gráfico de dispersión entre área construida y precio
ggplot(vivienda_clean, aes(x = areaconst, y = preciom)) +
  geom_point(alpha = 0.5, color = "blue") +
  labs(title = "Relación entre Área Construida y Precio", x = "Área Construida (m2)", y = "Precio (millones)") +
  theme_minimal()

Conclusiones del Análisis Inmobiliario

Distribución de Precios por Zona

  1. Se observa que los precios varían significativamente dependiendo de la zona.
  2. Las zonas Oeste y Sur presentan precios más elevados en comparación con otras zonas, lo que sugiere que podrían ser sectores con mayor demanda o con características inmobiliarias premium.
  3. Las zonas Centro y Oriente tienen una menor dispersión de precios, lo que indica mayor homogeneidad en el mercado inmobiliario de estas áreas.
  4. La presencia de valores atípicos (outliers) en la mayoría de las zonas sugiere que hay propiedades con precios excepcionalmente altos en todas las ubicaciones.

Relación entre Estrato y Precio

Se confirma una correlación positiva entre el estrato socioeconómico y el precio de las viviendas. Los estratos más bajos (3 y 4) muestran precios más homogéneos y concentrados en un rango medio-bajo. En estratos más altos (5 y 6), la dispersión de precios es significativamente mayor, reflejando la diversidad de propiedades dentro de estos segmentos. Los valores extremos en el estrato 6 sugieren que existen propiedades de lujo que pueden influir en la percepción de los precios en este sector. Relación entre Área Construida y Precio

Existe una relación clara entre el tamaño de la vivienda y el precio. Se evidencia un patrón de crecimiento exponencial, donde las viviendas más grandes presentan un incremento pronunciado en el precio. Aunque la mayoría de los datos siguen esta tendencia, algunos puntos dispersos en la parte superior derecha del gráfico indican la presencia de viviendas con áreas extremadamente grandes y precios muy elevados. El comportamiento de los datos sugiere que el precio por metro cuadrado varía según la ubicación y el estrato, lo que podría requerir un análisis más detallado en futuros estudios. Implicaciones para el Mercado Inmobiliario Segmentación del Mercado: La diferenciación de precios por zona y estrato permite a los inversionistas y compradores tomar decisiones estratégicas sobre en qué áreas invertir. Impacto del Tamaño en el Precio: Los desarrolladores inmobiliarios pueden usar estos hallazgos para diseñar propiedades en función de la demanda en cada sector. Oportunidades de Negocio: Se identifican áreas con precios más homogéneos que pueden representar oportunidades de inversión segura, mientras que las zonas con alta dispersión de precios pueden ser más riesgosas pero con potencial de alta rentabilidad. Estrategias de Venta: Los agentes inmobiliarios pueden adaptar sus estrategias según la zona y el estrato, destacando características clave como área construida y ubicación.