Carga de Datos y Paquetes

#install.packages("devtools")
#devtools::install_github("dgonxalex80/paqueteMODELOS")
#install.packages("factoextra")
#install.packages("tidyverse")
# #install.packages("FactoMineR")
library(paqueteMODELOS)
library(ggplot2)
library(dplyr)
library(tidyverse)
library(factoextra)
library(ggplot2)
library(cluster)
library(FactoMineR)
library(dplyr)
library(data.table)
data("vivienda")
head(vivienda)
## # A tibble: 6 × 13
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <chr>   <chr>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1  1147 Zona O… <NA>        3     250        70            1      3            6
## 2  1169 Zona O… <NA>        3     320       120            1      2            3
## 3  1350 Zona O… <NA>        3     350       220            2      2            4
## 4  5992 Zona S… 02          4     400       280            3      5            3
## 5  1212 Zona N… 01          5     260        90            1      2            3
## 6  1724 Zona N… 01          5     240        87            1      3            3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>

Analisis Descriptivo

Diccionario de variables:

dim(vivienda
    )
## [1] 8322   13

El data frame consta de 8322 registros y 13 variables

Tipo de variables

sapply(vivienda, class)
##           id         zona         piso      estrato      preciom    areaconst 
##    "numeric"  "character"  "character"    "numeric"    "numeric"    "numeric" 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##    "numeric"    "numeric"    "numeric"  "character"  "character"    "numeric" 
##      latitud 
##    "numeric"

Nota

  • La variable id solo sirve para identificar los registros por ende no aporta información importante

  • La variable estrato esta clasificada como numérica, sin embargo resulta mas acorde a su naturaleza que sea del tipo ordinal.

  • La variable barrio presenta muchas categorias por ende es mejor no considerarla para el analisis.

analisis de valores faltantes

colSums(is.na(vivienda))%>% as.data.frame()
##                 .
## id              3
## zona            3
## piso         2638
## estrato         3
## preciom         2
## areaconst       3
## parqueaderos 1605
## banios          3
## habitaciones    3
## tipo            3
## barrio          3
## longitud        3
## latitud         3

Nota

  • Las variables piso y parqueaderos presentan gran cantidad de valores faltantes en comparación del total de registros para considerar imputar y no eliminarlos.

Estadisticas descriptivas

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

Nota * Las variables Cuantitativas tienen presencia de valores atipicos, siendo preciom y areaconst las que presentan mayores diferencias en comparación de tercer cuartil.

  • Las variables parqueaderos, banios y habitaciones representan valores discretos de 1 a 10.

Analisis Unidimensional

Variables Discretas y cualitativas

Zona

zona<-as.data.frame(table(vivienda$zona)) 
colnames(zona) <- c("Zona", "Cantidad")
zona
##           Zona Cantidad
## 1  Zona Centro      124
## 2   Zona Norte     1920
## 3   Zona Oeste     1198
## 4 Zona Oriente      351
## 5     Zona Sur     4726

Nota La zona sur tiene mayor presencia de viviendas.

piso

piso<-as.data.frame(table(vivienda$piso))
colnames(piso) <- c("piso", "Cantidad")
piso
##    piso Cantidad
## 1    01      860
## 2    02     1450
## 3    03     1097
## 4    04      607
## 5    05      567
## 6    06      245
## 7    07      204
## 8    08      211
## 9    09      146
## 10   10      130
## 11   11       84
## 12   12       83

Nota La mayoria de pisos estan entre 1 y 4

Estrato

estrato<-as.data.frame(table(vivienda$estrato))
colnames(estrato)<-c("Estrato","Cantidad")
estrato
##   Estrato Cantidad
## 1       3     1453
## 2       4     2129
## 3       5     2750
## 4       6     1987

Nota

  • hay una mayor precensia de estratos 4 y 5

Parqueaderos

parqueaderos<-as.data.frame(table(vivienda$parqueaderos)) 
colnames(parqueaderos) <- c("parqueaderos", "Cantidad")
parqueaderos
##    parqueaderos Cantidad
## 1             1     3155
## 2             2     2475
## 3             3      520
## 4             4      384
## 5             5       68
## 6             6       68
## 7             7       18
## 8             8       17
## 9             9        4
## 10           10        8

Nota La mayoría de viviendas tienen de 1 a 2 parqueaderos

baños

banios<-as.data.frame(table(vivienda$banios)) 
colnames(banios) <- c("banios", "Cantidad")
banios
##    banios Cantidad
## 1       0       45
## 2       1      496
## 3       2     2946
## 4       3     1993
## 5       4     1456
## 6       5      890
## 7       6      314
## 8       7      107
## 9       8       48
## 10      9       15
## 11     10        9

Nota

La mayoría de viviendas tienen de 2 a 4 baños

Habitaciones

habitaciones<-as.data.frame(table(vivienda$habitaciones))
colnames(habitaciones)<-c("habitaciones", "cantidad")
habitaciones
##    habitaciones cantidad
## 1             0       66
## 2             1       59
## 3             2      926
## 4             3     4097
## 5             4     1729
## 6             5      679
## 7             6      318
## 8             7      173
## 9             8      138
## 10            9       83
## 11           10       51

Nota

La mayoría de las viviendas tienen de 2 a 4 habitaciones

Tipo

tipo<-as.data.frame(table(vivienda$tipo))
colnames(tipo)<-c("Tipo","Cantidad")
tipo
##          Tipo Cantidad
## 1 Apartamento     5100
## 2        Casa     3219

Nota

Hay una mayor presencia de apartamentos en el mercado

Analisis Gráfico

library(gridExtra)
library(grid)
library(patchwork)
## Warning: package 'patchwork' was built under R version 4.4.2
g1<-ggplot(zona, aes(x = Zona, y = Cantidad)) +  
  geom_col(fill = "darkblue") + 
  labs(title = "Frecuencia por zona", x = "Zona", y = "Cantidad") +
  theme_minimal()+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))
g2<-ggplot(piso, aes(x = piso, y = Cantidad)) +  
  geom_col(fill = "darkblue") + 
  labs(title = "Frecuencia por piso", x = "Piso", y = "Cantidad") +
  theme_minimal()
g3<-ggplot(estrato, aes(x = Estrato, y = Cantidad)) +  
  geom_col(fill = "darkblue") + 
  labs(title = "Frecuencia por estrato", x = "Estrato", y = "Cantidad") +
  theme_minimal()
g4<-ggplot(parqueaderos, aes(x = parqueaderos, y = Cantidad)) +  
  geom_col(fill = "darkblue") + 
  labs(title = "Frecuencia de parqueaderos", x = "Parqueaderos", y = "Cantidad") +
  theme_minimal()

(g1 | g2)/(g3 | g4)

g5<-ggplot(banios, aes(x = banios, y = Cantidad)) +  
  geom_col(fill = "darkblue") + 
  labs(title = "Numero de banios", x = "parqueaderos", y = "Cantidad") +
  theme_minimal()
g6<-ggplot(habitaciones, aes(x = habitaciones, y = cantidad)) +  
  geom_col(fill = "darkblue") + 
  labs(title = "Numero de habitaciones", x = "habitaciones", y = "Cantidad") +
  theme_minimal()
g7<-ggplot(tipo, aes(x=Tipo, y= Cantidad))+
  geom_col(fill="darkblue")+labs(title = "Frecuencia por tipo", x= "Tipo",y= "Cantidad")+
  theme_minimal()
(g5 | g6) / (g7)

Variables continuas

Preciom

g8<-ggplot(vivienda, aes(y = preciom)) +
  geom_boxplot(fill = "skyblue", color = "black") +
  labs(title = "Distribucion del Precio por M2", 
       y = "Precio por metro cuadrado") +
  theme_minimal()
g9<- ggplot(vivienda, aes(x = preciom)) +
  geom_histogram(binwidth = 50, fill = "skyblue", color = "black") +
  labs(title = "Distribucion del Precio por M2", 
       x = "Precio por metro cuadrado", 
       y = "Frecuencia") +
  theme_minimal()
(g8 | g9)
## Warning: Removed 2 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Warning: Removed 2 rows containing non-finite outside the scale range
## (`stat_bin()`).

Areaconst

g10<-ggplot(vivienda, aes(y = areaconst)) +
  geom_boxplot(fill = "skyblue", color = "black") +
  labs(title = "Area construida", 
       y = "metros cuadrados construidos") +
  theme_minimal()
g11<-ggplot(vivienda, aes(x = areaconst)) +
  geom_histogram(binwidth = 50, fill = "skyblue", color = "black") +
  labs(title = "Distribucion del Area construida", 
       x = "metros cuadrados construidos", 
       y = "Frecuencia") +
  theme_minimal()
(g10 | g11)
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_bin()`).

Nota

En cuanto al precio y al area construida se observa una gran precensia de valores atipicos.

Resultado del análisis unidimensional

  • Los precios de las viviendas y los metros cuadrados construidos presentan gran cantidad de valores atipicos.

  • se cuenta con mas apartamentos que casas en las viviendas.

  • la mayoría de viviendas tienen de 2 a 5 baños y habitaciones.

  • La mayoría de viviendas se registran en la zona sur de cali

Analisis Bidimensional

###Precio-Tipo

ggplot(data=vivienda,aes(x= tipo,y=preciom))+geom_boxplot(fill="darkblue",color="red")+
  labs(title = "precio por tipo de vivienda", 
       y = "precio por metro cuadrado") +
  theme_minimal()
## Warning: Removed 2 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Nota * LAs casas tienen un precio superior en comparación de ls apartamentos,ademas de una mayor variabilidad. cabe resaltar que se presentan hay un rango de valores atípicos desde los 1250 hasta los 1750 entre apartamentos y casas con los mismos precios.

###Tipo-areaconst

ggplot(data=vivienda,aes(x= tipo,y=areaconst))+geom_boxplot(fill="darkblue",color="red")+
  labs(title = "m2 construidos por tipo de vivienda", 
       y = "metros cuadrados construidos") +
  theme_minimal()
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Nota De acuerdo al contexto del problema se esperaba que las casas tuvieran una mayor area construida que los apartamentos.

Zona-Estrato

table(vivienda$zona,vivienda$estrato)
##               
##                   3    4    5    6
##   Zona Centro   105   14    4    1
##   Zona Norte    572  407  769  172
##   Zona Oeste     54   84  290  770
##   Zona Oriente  340    8    2    1
##   Zona Sur      382 1616 1685 1043

Nota

  • hay una mayor precencia de viviendas en la zona sur en los estratos 4 y 5

zona-areaconst

ggplot(data=vivienda,aes(x= zona,y=areaconst))+geom_boxplot(fill="darkblue",color="red")+
  labs(title = "Area construida", 
       y = "metros cuadrados construidos") +
  theme_minimal()
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Nota

  • En la zona sur se presenta una mayor variabilidad en cuanto al area construida.

Zona y precio

ggplot(data=vivienda,aes(x= zona,y=preciom))+geom_boxplot(fill="darkblue",color="red")+
  labs(title = "precio por metro cuadrado", 
       y = "precio") +
  theme_minimal()
## Warning: Removed 2 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Nota

  • La zona oeste presenta precios mas altos y a la vez mas variables en cuanto a viviendas.

Estrato-areaconst

library(data.table)
df <- copy(vivienda)
df$estrato<-as.factor(df$estrato)
ggplot(data=df,aes(x=estrato,y=areaconst))+geom_boxplot(fill="darkblue",color="red")+
  labs(title = "Area Construida por Estrato", 
       y = "Area construida") +
  theme_minimal()
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Nota

  • hay cierta correspondencia con la realidad colombiana en que el estrato 6 que es el mas alto presente que sus viviendas sean mas grandes, debido a su poder adquisitivo.
cor(vivienda$estrato, vivienda$areaconst, method = "spearman", use = "complete.obs")
## [1] 0.3945008
cor.test(vivienda$estrato, vivienda$areaconst, method = "spearman",use="complete.obs")
## Warning in cor.test.default(vivienda$estrato, vivienda$areaconst, method =
## "spearman", : Cannot compute exact p-value with ties
## 
##  Spearman's rank correlation rho
## 
## data:  vivienda$estrato and vivienda$areaconst
## S = 5.81e+10, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.3945008

Nota

  • Hay correlación entre el estrato y el area construida.

Precio-estrato

ggplot(data=df,aes(x=estrato,y=preciom))+geom_boxplot(fill="darkblue",color="red")+
  labs(title = "Precio por Estrato", 
       y = "precio por metro cuadrado") +
  theme_minimal()
## Warning: Removed 2 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Nota

  • es un resultado esperado dentro del contexto colombiano, que los estratos mas altos en particular el 6 presente unos precios mas altos.
cor(vivienda$estrato, vivienda$preciom, method = "spearman", use = "complete.obs")
## [1] 0.7100707
cor.test(vivienda$estrato, vivienda$preciom, method = "spearman",use="complete.obs")
## Warning in cor.test.default(vivienda$estrato, vivienda$preciom, method =
## "spearman", : Cannot compute exact p-value with ties
## 
##  Spearman's rank correlation rho
## 
## data:  vivienda$estrato and vivienda$preciom
## S = 2.782e+10, p-value < 2.2e-16
## alternative hypothesis: true rho is not equal to 0
## sample estimates:
##       rho 
## 0.7100707

Nota El coeficiente de correlacion de Spearman evidencia una correlación entre las variables estrato y precio.

Correlacion entre areaconst y precio

cor(vivienda$areaconst, vivienda$preciom, method = "pearson", use = "complete.obs")
## [1] 0.687352
cor.test(vivienda$estrato, vivienda$preciom, method = "pearson",use="complete.obs")
## 
##  Pearson's product-moment correlation
## 
## data:  vivienda$estrato and vivienda$preciom
## t = 70.17, df = 8317, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.5961292 0.6231303
## sample estimates:
##       cor 
## 0.6098066

precio-areaconst por tipo

ggplot(data = vivienda, aes(x = areaconst, y = preciom, color = tipo)) +
  geom_point(size = 2, alpha = 0.7) + # Ajuste de tamaño y transparencia
  labs(title = "Diagrama de Dispersión: Precio vs Área Construida",
       x = "Área Construida (m²)", 
       y = "Precio (millones)",
       color = "Tipo") +  # Etiqueta de la leyenda
  theme_minimal()
## Warning: Removed 3 rows containing missing values or values outside the scale range
## (`geom_point()`).

precio-areaconst por zonas

ggplot(data = vivienda, aes(x = areaconst, y = preciom, color = zona)) +
  geom_point(size = 2, alpha = 0.7) + # Ajuste de tamaño y transparencia
  labs(title = "Diagrama de Dispersión: Precio vs Área Construida",
       x = "Área Construida (m²)", 
       y = "Precio (millones)",
       color = "Zona") +  # Etiqueta de la leyenda
  theme_minimal()
## Warning: Removed 3 rows containing missing values or values outside the scale range
## (`geom_point()`).

precio-areaconst por estrato

library(ggplot2)

ggplot(data = df, aes(x = areaconst, y = preciom, color = estrato)) +
  geom_point(size = 2, alpha = 0.7) + # Ajuste de tamaño y transparencia
  labs(title = "Diagrama de Dispersión: Precio vs Área Construida",
       x = "Área Construida (m²)", 
       y = "Precio (millones)",
       color = "estrato") +  # Etiqueta de la leyenda
  theme_minimal()
## Warning: Removed 3 rows containing missing values or values outside the scale range
## (`geom_point()`).

Precio por ubicacion

ggplot(vivienda, aes(x = longitud, y = latitud, color = preciom)) +
  geom_point(alpha = 0.7) +
  scale_color_gradient(low = "blue", high = "red") +
  labs(title = "Mapa de precios de viviendas",
       x = "Longitud", y = "Latitud", color = "Precio por m²")
## Warning: Removed 3 rows containing missing values or values outside the scale range
## (`geom_point()`).

Nota

  • En la parte inferior con longitud aproximada entre -76.52 y -76.55 y latitud entre 3.33 y 3.70 se observa una franja de viviendas con precios ligeramente mas altos que los demas debido a su coloración rojiza.

parqueadero-estrato

table(vivienda$estrato,vivienda$parqueaderos)
##    
##        1    2    3    4    5    6    7    8    9   10
##   3  557   93   19   10    1    3    0    0    0    1
##   4 1238  317   50   23    4    4    2    0    1    2
##   5 1206 1030  136  100   27   13    5    3    1    1
##   6  154 1035  315  251   36   48   11   14    2    4

parqueadero-tipo

table(vivienda$tipo,vivienda$parqueaderos)
##              
##                  1    2    3    4    5    6    7    8    9   10
##   Apartamento 2298 1584  252   88    4    2    1    0    0    2
##   Casa         857  891  268  296   64   66   17   17    4    6

Resultados Analisis bidimencional

  • La zona oeste presenta un precio mas elevado en sus viviendas.

  • Las viviendas con longitud aproximada entre -76.52 y -76.55 y latitud entre 3.33 y 3.70 se observa una franja de viviendas con precios ligeramente mas alto.

  • La zona sur presenta una mayor cantidad de viviendas siendo en su gram mayoria en estratos 4 y 5.

Tratamiento de los datos

Valores faltantes e imputacion

Al mirar las variables piso y parqueadero, podemos observar que tienen gran cantidad de datos faltantes en comparación a la cantidad total, por esta razón preferimos imputar a eliminar, para ello imputaremos haciendo uso de la moda en el caso de piso y para parqueaderos lo haremos mediante la mediana, teniendo en cuenta el estrato y tipo del inmueble, los demás se eliminaran ya que presentan una proporción pequeña de los datos.

# imputar con la moda en piso
moda_piso <- names(sort(table(vivienda$piso), decreasing = TRUE))[1]
vivienda$piso[is.na(vivienda$piso)] <- moda_piso
# imputar parqueaderos considerando el estrato y el tipo
vivienda <- vivienda %>%
  group_by(estrato, tipo) %>%
  mutate(parqueaderos = ifelse(is.na(parqueaderos), median(parqueaderos, na.rm = TRUE), parqueaderos)) %>%
  ungroup()
# verificacion
colSums(is.na(vivienda))%>% as.data.frame()
##              .
## id           3
## zona         3
## piso         0
## estrato      3
## preciom      2
## areaconst    3
## parqueaderos 3
## banios       3
## habitaciones 3
## tipo         3
## barrio       3
## longitud     3
## latitud      3

eliminar el resto de datos faltantes.

vivienda_limpia <- vivienda %>% drop_na()
dim(vivienda_limpia)
## [1] 8319   13

Eliminacion de datos atipicos

De acuerdo a el análisis exploratorio de datos vamos considerar tres casos en los que vamos a eliminar valores atípicos de manera que se pueda observar el comportamiento de los modelos y las variaciones de estos. caso base: se trabajara con los datos obtenidos despues del proceso de impuación y eliminacion de valores faltantes caso 1: eliminar todos los datos atípicos de las variables numéricas, tomando como referencia los valores a 1.5 veces el rango intercuartil. caso 2: eliminar solo los valores atípicos de las variables de tipo continuas es decir del area construida y el precio, usando el método del rango intercuartil ya que estas dos variables no siguen una distribución casi normal.

caso 1

# defino una función que me permita eliminar outliers
eliminar_outliers_mult <- function(df, columnas) {
  for (col in columnas) {
    Q1 <- quantile(df[[col]], 0.25, na.rm = TRUE)
    Q3 <- quantile(df[[col]], 0.75, na.rm = TRUE)
    IQR <- Q3 - Q1
    limite_inferior <- Q1 - 1.5 * IQR
    limite_superior <- Q3 + 1.5 * IQR
# selecciona los valores dentro de 1.5 RIC
    df <- df[df[[col]] >= limite_inferior & df[[col]] <= limite_superior, ]
  }
  return(df)
}
variables_filtradas <- c("preciom", "areaconst", "parqueaderos", "banios", "habitaciones")
vivienda_sin_outliers <- eliminar_outliers_mult(vivienda_limpia, variables_filtradas)
dim(vivienda_sin_outliers)
## [1] 6565   13

al realizar el proceso de eliminación se obtuvieron 6565 registros representando el 79% de los datos obtenidos después del proceso de imputación.

caso 2

variables_filtradas1 <- c("preciom", "areaconst")
vivienda_sin_outliers1<- eliminar_outliers_mult(vivienda_limpia, variables_filtradas1)
dim(vivienda_sin_outliers1)
## [1] 7365   13

al realizar el proceso de eliminación se obtuvieron 7368 registros representando el 88.5% de los datos obtenidos después del proceso de imputación.

Vamos a estandarizar los datos para ingresarlos al PCA,caso base, caso 1 y caso 2

pca <- scale(vivienda_sin_outliers[, c("preciom", "areaconst", "parqueaderos", "banios", "habitaciones")])
pca1<- scale(vivienda_sin_outliers1[, c("preciom", "areaconst", "parqueaderos", "banios", "habitaciones")])

Analisis de componentes principales

se realizaran 3 análisis de componentes principales, teniendo en cuenta los 3 casos mencionados anteriormente.

pca_base <- scale(vivienda_limpia[, c("preciom", "areaconst", "parqueaderos", "banios", "habitaciones")])
dim(pca_base)
## [1] 8319    5

caso base

pca_resultado_base<-prcomp(pca_base)
pca_resultado_base
## Standard deviations (1, .., p=5):
## [1] 1.7908096 0.9471010 0.6092291 0.5770444 0.4380183
## 
## Rotation (n x k) = (5 x 5):
##                    PC1         PC2        PC3        PC4        PC5
## preciom      0.4748950  0.38383446  0.2446701 -0.3096262  0.6865960
## areaconst    0.4814940 -0.05348847  0.6847715  0.4039500 -0.3649861
## parqueaderos 0.4315302  0.46143342 -0.6093001  0.4607795 -0.1315164
## banios       0.4861697 -0.17690710 -0.2044608 -0.6834356 -0.4727097
## habitaciones 0.3464954 -0.77819867 -0.2411921  0.2481009  0.3932176
fviz_eig(pca_resultado_base, addlabels = TRUE)

fviz_pca_var(pca_resultado_base,
col.var = "contrib", # Color by contributions to the PC
gradient.cols = c("#FF7F00",  "#034D94"),
repel = TRUE     # Avoid text overlapping
)

caso 1

pca_resultado_1<-prcomp(pca)
pca_resultado_1
## Standard deviations (1, .., p=5):
## [1] 1.8001855 0.9095985 0.6278664 0.5857852 0.4411373
## 
## Rotation (n x k) = (5 x 5):
##                    PC1         PC2        PC3         PC4        PC5
## preciom      0.4826392 -0.34417245 -0.3209808 -0.04679068  0.7371476
## areaconst    0.4765933  0.19491653 -0.3771729 -0.64121225 -0.4259740
## parqueaderos 0.4216387 -0.50167750  0.7160878 -0.12326897 -0.2063092
## banios       0.4822087  0.01623593 -0.2488523  0.75459715 -0.3686013
## habitaciones 0.3600192  0.76916120  0.4242673  0.04522582  0.3110131
fviz_eig(pca_resultado_1, addlabels = TRUE)

fviz_pca_var(pca_resultado_1,
col.var = "contrib", # Color by contributions to the PC
gradient.cols = c("#FF7F00",  "#034D94"),
repel = TRUE     # Avoid text overlapping
)

caso 2

pca_resultado_2<-prcomp(pca1)
pca_resultado_2
## Standard deviations (1, .., p=5):
## [1] 1.7605360 0.9740786 0.6419605 0.5898516 0.4377737
## 
## Rotation (n x k) = (5 x 5):
##                    PC1        PC2        PC3         PC4        PC5
## preciom      0.4785252  0.3728634  0.4095836  0.03949097  0.6801972
## areaconst    0.4926828 -0.1369852  0.2061553  0.71070638 -0.4369155
## parqueaderos 0.4080483  0.5177048 -0.7406953 -0.04343075 -0.1223217
## banios       0.4909095 -0.1274992  0.2900280 -0.70071724 -0.4094276
## habitaciones 0.3475366 -0.7469495 -0.3962266 -0.02111912  0.4047754
fviz_eig(pca_resultado_2, addlabels = TRUE)

fviz_pca_var(pca_resultado_2,
col.var = "contrib", # Color by contributions to the PC
gradient.cols = c("#FF7F00",  "#034D94"),
repel = TRUE     # Avoid text overlapping
)

Nota Debido a la gran cantidad de registros no es muy útil la visualización mediante el biplot.

Resultados PCA

En el experimento realizado, se puede observar que los tres modelos evidencian comportamientos similares como la selección de dos componentes principales, ademas de las relaciones entre las variables precio y parqueadero, banios y areaconst, siendo estas variables las que mas aportan a la primer componente, y habitaciones con un mayor aporte hacia la segunda componente.

Analisis Cluster

El análisis cluster se hará mediante el uso de las dos componentes principales halladas en el paso anterior y se usaran los mismos tres casos anteriormente mencionados en el pca

caso base

# Seleccionar las dos primeras componentes principales
pca_comps <- pca_resultado_base$x[, 1:2]  # Solo las dos primeras componentes
set.seed(123)
kmeans_base <- kmeans(pca_comps, centers = 3, nstart = 25)

# Agregar los resultados del clustering al DataFrame original (si es necesario)
vivienda_limpia$cluster <- as.factor(kmeans_base$cluster)
# Método del codo 
fviz_nbclust(pca_comps, kmeans, method = "wss")

Nota

fviz_cluster(kmeans_base, data = pca_comps, geom = "point") +
  labs(title = "Clustering usando las Dos Primeras Componentes Principales") +
  theme_minimal()

# Asegurarte de que 'estrato' esté en el DataFrame y sea un factor
vivienda_limpia$estrato <- as.factor(vivienda_limpia$estrato)

# Visualizar los clusters coloreados por 'estrato'
fviz_cluster(kmeans_base, data = pca_comps, geom = "point") +
  geom_point(aes(color = vivienda_limpia$estrato)) +  # Colorea por estrato
  labs(title = "Clustering de Viviendas por Estrato usando las Dos Primeras Componentes Principales", color = "Estrato") +
  theme_minimal()

# Asegurarte de que 'zona' esté en el DataFrame y sea un factor
vivienda_limpia$zona <- as.factor(vivienda_limpia$zona)

# Visualizar los clusters coloreados por 'zona'
fviz_cluster(kmeans_base, data = pca_comps, geom = "point") +
  geom_point(aes(color = vivienda_limpia$zona)) +  # Colorea por zona
  labs(title = "Clustering de Viviendas por Zona usando las Dos Primeras Componentes Principales", color = "Zona") +
  theme_minimal()

# Calcular el índice de silueta para los resultados del k-means
silhouette_score <- silhouette(kmeans_base$cluster, dist(pca_comps))

# Graficar el índice de silueta
plot(silhouette_score, main = "Índice de Silueta para los Clusters")

Caso 1

# Seleccionar las dos primeras componentes principales
pca_comps_1 <- pca_resultado_1$x[, 1:2]  # Solo las dos primeras componentes
set.seed(123)
kmeans_1<- kmeans(pca_comps_1, centers = 3, nstart = 25)

# Agregar los resultados del clustering al DataFrame original (si es necesario)
vivienda_sin_outliers$cluster <- as.factor(kmeans_1$cluster)
# Método del codo 
fviz_nbclust(pca_comps_1, kmeans, method = "wss")

Nota

fviz_cluster(kmeans_1, data = pca_comps_1, geom = "point") +
  labs(title = "Clustering usando las Dos Primeras Componentes Principales") +
  theme_minimal()

# Asegurarte de que 'estrato' esté en el DataFrame y sea un factor
vivienda_sin_outliers$estrato <- as.factor(vivienda_sin_outliers$estrato)

# Visualizar los clusters coloreados por 'estrato'
fviz_cluster(kmeans_1, data = pca_comps_1, geom = "point") +
  geom_point(aes(color = vivienda_sin_outliers$estrato)) +  # Colorea por estrato
  labs(title = "Clustering de Viviendas por Estrato usando las Dos Primeras Componentes Principales", color = "Estrato") +
  theme_minimal()

# Asegurarte de que 'zona' esté en el DataFrame y sea un factor
vivienda_sin_outliers$zona <- as.factor(vivienda_sin_outliers$zona)

# Visualizar los clusters coloreados por 'zona'
fviz_cluster(kmeans_1, data = pca_comps_1, geom = "point") +
  geom_point(aes(color = vivienda_sin_outliers$zona)) +  # Colorea por zona
  labs(title = "Clustering de Viviendas por Zona usando las Dos Primeras Componentes Principales", color = "Zona") +
  theme_minimal()

# Calcular el índice de silueta para los resultados del k-means
silhouette_score_1<- silhouette(kmeans_1$cluster, dist(pca_comps_1))

# Graficar el índice de silueta
plot(silhouette_score_1, main = "Índice de Silueta para los Clusters")

caso 2

# Seleccionar las dos primeras componentes principales
pca_comps_2<- pca_resultado_2$x[, 1:2]  # Solo las dos primeras componentes
set.seed(123)
kmeans_2<- kmeans(pca_comps_2, centers = 3, nstart = 25)

# Agregar los resultados del clustering al DataFrame original (si es necesario)
vivienda_sin_outliers1$cluster <- as.factor(kmeans_2$cluster)

# Método del codo 
fviz_nbclust(pca_comps_2, kmeans, method = "wss")

Nota

fviz_cluster(kmeans_2, data = pca_comps_2, geom = "point") +
  labs(title = "Clustering usando las Dos Primeras Componentes Principales") +
  theme_minimal()

# Asegurarte de que 'estrato' esté en el DataFrame y sea un factor
vivienda_sin_outliers1$estrato <- as.factor(vivienda_sin_outliers1$estrato)

# Visualizar los clusters coloreados por 'estrato'
fviz_cluster(kmeans_2, data = pca_comps_2, geom = "point") +
  geom_point(aes(color = vivienda_sin_outliers1$estrato)) +  # Colorea por estrato
  labs(title = "Clustering de Viviendas por Estrato usando las Dos Primeras Componentes Principales", color = "Estrato") +
  theme_minimal()

# Asegurarte de que 'zona' esté en el DataFrame y sea un factor
vivienda_sin_outliers1$zona <- as.factor(vivienda_sin_outliers1$zona)

# Visualizar los clusters coloreados por 'zona'
fviz_cluster(kmeans_2, data = pca_comps_2, geom = "point") +
  geom_point(aes(color = vivienda_sin_outliers1$zona)) +  # Colorea por zona
  labs(title = "Clustering de Viviendas por Zona usando las Dos Primeras Componentes Principales", color = "Zona") +
  theme_minimal()

# Calcular el índice de silueta para los resultados del k-means
silhouette_score_2<- silhouette(kmeans_2$cluster, dist(pca_comps_2))

# Graficar el índice de silueta
plot(silhouette_score_2, main = "Índice de Silueta para los Clusters")

Resultados Analisis Cluster

Se observa en los tres casos usados en este análisis que mediante el método del “codo” 3 cluster parecen ser un buen número , sin embargo se observa que los cluster entre si están muy juntos lo cual gráficamente puede ser un indicio de que los cluster no separan bien los grupos y esto se comprueba mediante el indice silhouette el cual muestra en los 1 casos que el mejor clasificado de los 3 cluster es el tercero, ademas el valor del average silhouette es bajo lo cual indica que los grupos no están bien agrupados.

Analisis de Correspondencias

Realizaremos un análisis de correspondencias para observar asociaciones entre las variables cualitativas zona, estrato, tipo. no consideramos piso ya que al haber casas y apartamentos podría este análisis no ser tan preciso de encontrar relaciones, al igual que barrio debido a la cantidad de categorías que presenta esta variable.

Pruebas Chi_cuadrado

Zona y estrato

viviendas_ac<-vivienda_limpia%>%select(zona,estrato,tipo)
ch1<-chisq.test(viviendas_ac$zona,viviendas_ac$estrato)
ch1
## 
##  Pearson's Chi-squared test
## 
## data:  viviendas_ac$zona and viviendas_ac$estrato
## X-squared = 3830.4, df = 12, p-value < 2.2e-16

Zona y Tipo

ch2<-chisq.test(viviendas_ac$zona,viviendas_ac$tipo)
ch2
## 
##  Pearson's Chi-squared test
## 
## data:  viviendas_ac$zona and viviendas_ac$tipo
## X-squared = 690.93, df = 4, p-value < 2.2e-16

tipo y estrato

ch3<-chisq.test(viviendas_ac$tipo,viviendas_ac$estrato)
ch3
## 
##  Pearson's Chi-squared test
## 
## data:  viviendas_ac$tipo and viviendas_ac$estrato
## X-squared = 224.33, df = 3, p-value < 2.2e-16

Observación Las tres variables estadisticamente están relacionadas.

Analisis de correspondencias

Zona y Estrato

tabla_ac_Zona_estrato<-table(viviendas_ac$zona,viviendas_ac$estrato)
ac1<-CA(tabla_ac_Zona_estrato,graph= FALSE)
fviz_ca_biplot(ac1,repel = TRUE)

Observación

  • hay una fuerte relación entre la zona sur y el estrato 4 y 5

  • hay una relación entre la zona oeste y el estrato 6.

Zona y Tipo

tabla_ac_Zona_tipo<-table(viviendas_ac$zona,viviendas_ac$tipo)
ac2<-CA(tabla_ac_Zona_tipo,graph= FALSE)
ac2$eig
##       eigenvalue percentage of variance cumulative percentage of variance
## dim 1 0.08305442                    100                               100

Observación ya que solo se tiene una sola dimensión no es posible realizar el biplot en el análisis de correspondencias.

Estrato y Tipo

tabla_ac_est_tipo<-table(viviendas_ac$estrato,viviendas_ac$tipo)
ac3<-CA(tabla_ac_est_tipo,graph= FALSE)
ac3$eig
##       eigenvalue percentage of variance cumulative percentage of variance
## dim 1  0.0269661                    100                               100

Observación ya que solo se tiene una sola dimensión no es posible realizar el biplot en el análisis de correspondencias.

Nota Lo anterior puede deberse a las pocas categorías de la variable tipo.

Resultados Analisis de Correspondencias

  • se observa una relación fuerte entre la zona sur y el estrato 4 y 5.
  • se observa una relación entre la zona oeste y el estrato 6.

Conclusiones y Recomendaciones.