carga de paquete y datos

library(paqueteMODELOS)
## Loading required package: boot
## Loading required package: broom
## Warning: package 'broom' was built under R version 4.3.3
## Loading required package: GGally
## Warning: package 'GGally' was built under R version 4.3.3
## Loading required package: ggplot2
## Warning: package 'ggplot2' was built under R version 4.3.3
## 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.3
## Loading required package: summarytools
data("vivienda")

Analisis de exploratorio de datos

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")=List of 3
##   ..$ cols   :List of 13
##   .. ..$ id          : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ zona        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ piso        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ estrato     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ preciom     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ areaconst   : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ parqueaderos: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ banios      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ habitaciones: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ tipo        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ barrio      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ longitud    : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ latitud     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   ..$ default: list()
##   .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
##   ..$ delim  : chr ";"
##   ..- attr(*, "class")= chr "col_spec"
##  - 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
head(vivienda)

Validación de datos faltantes

library(mice)
## Warning: package 'mice' was built under R version 4.3.3
## Warning in check_dep_version(): ABI version mismatch: 
## lme4 was built with Matrix ABI version 1
## Current Matrix ABI version is 0
## Please re-install lme4 from source or restore original 'Matrix' package
## 
## Attaching package: 'mice'
## The following object is masked from 'package:stats':
## 
##     filter
## The following objects are masked from 'package:base':
## 
##     cbind, rbind
md.pattern(vivienda) 

##      preciom id zona estrato areaconst banios habitaciones tipo barrio longitud
## 4808       1  1    1       1         1      1            1    1      1        1
## 1909       1  1    1       1         1      1            1    1      1        1
## 876        1  1    1       1         1      1            1    1      1        1
## 726        1  1    1       1         1      1            1    1      1        1
## 1          1  0    0       0         0      0            0    0      0        0
## 2          0  0    0       0         0      0            0    0      0        0
##            2  3    3       3         3      3            3    3      3        3
##      latitud parqueaderos piso     
## 4808       1            1    1    0
## 1909       1            1    0    1
## 876        1            0    1    1
## 726        1            0    0    2
## 1          0            0    0   12
## 2          0            0    0   13
##            3         1605 2638 4275

Eliminación de datos faltantes

De acuerdo con el análisis univariado de la base de datos, siendo los atributos piso y parqueadero con más datos faltantes; piso:2638, parqueadero: 1605

Lo que podría afectar la precisión y fiabilidad del análisis. Por lo tanto, para resolver este problema, se ha decidido eliminar estas variables del conjunto de datos.

Y por ende, se eliminará los atributos barrio y id, dado que su presencia no aporta valor sustancial al análisis ni al tratamiento de los datos.

Nombes de las columnas del conjunto de datos

colnames(vivienda)
##  [1] "id"           "zona"         "piso"         "estrato"      "preciom"     
##  [6] "areaconst"    "parqueaderos" "banios"       "habitaciones" "tipo"        
## [11] "barrio"       "longitud"     "latitud"

Eliminando las columnas ‘id’, ‘piso’, ‘barrio’ y ‘parqueaderos’ usando subset()

vivienda_sin_faltantes <- subset(vivienda, select = -c(id, piso, barrio, parqueaderos))

Eliminando filas con valores faltantes

vivienda_sin_faltantes <- vivienda_sin_faltantes[complete.cases(vivienda_sin_faltantes), ]

Conteo de valores faltantes

sum(is.na(vivienda_sin_faltantes)) 
## [1] 0

visualización data sin faltantes

str(vivienda_sin_faltantes)
## spc_tbl_ [8,319 × 9] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ zona        : chr [1:8319] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
##  $ estrato     : num [1:8319] 3 3 3 4 5 5 4 5 5 5 ...
##  $ preciom     : num [1:8319] 250 320 350 400 260 240 220 310 320 780 ...
##  $ areaconst   : num [1:8319] 70 120 220 280 90 87 52 137 150 380 ...
##  $ banios      : num [1:8319] 3 2 2 5 2 3 2 3 4 3 ...
##  $ habitaciones: num [1:8319] 6 3 4 3 3 3 3 4 6 3 ...
##  $ tipo        : chr [1:8319] "Casa" "Casa" "Casa" "Casa" ...
##  $ longitud    : num [1:8319] -76.5 -76.5 -76.5 -76.5 -76.5 ...
##  $ latitud     : num [1:8319] 3.43 3.43 3.44 3.44 3.46 ...
##  - attr(*, "spec")=List of 3
##   ..$ cols   :List of 13
##   .. ..$ id          : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ zona        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ piso        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ estrato     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ preciom     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ areaconst   : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ parqueaderos: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ banios      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ habitaciones: list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ tipo        : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ barrio      : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
##   .. ..$ longitud    : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   .. ..$ latitud     : list()
##   .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
##   ..$ default: list()
##   .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
##   ..$ delim  : chr ";"
##   ..- attr(*, "class")= chr "col_spec"
##  - attr(*, "problems")=<externalptr>

Análisis de componentes

#A continuación, eliminaremos las columnas de ID, longitud, latitud y barrio, ya que no son relevantes para nuestro análisis. Solo mantendremos las columnas desde zona hasta tipo de vivienda.

#Posteriormente, codificaremos las variables zona y tipo para asegurar el correcto funcionamiento en el análisis de componentes principales.
library(psych)
## Warning: package 'psych' was built under R version 4.3.3
## 
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
## 
##     %+%, alpha
## The following object is masked from 'package:boot':
## 
##     logit
pairs.panels(vivienda_sin_faltantes, 
             pch=20,
             stars=T,
             main="Gráfico de Correlación")  

# Se modifican las variables categóricas (zona y tipo) que contiene la data, reclasificándolas asi:
library(dplyr)
## 
## Attaching package: 'dplyr'
## 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
vivienda_sin_faltantes <- vivienda_sin_faltantes %>% mutate(zona = replace(zona, 
                                               zona == "Zona Centro", 1))
vivienda_sin_faltantes <- vivienda_sin_faltantes %>% mutate(zona = replace(zona, 
                                               zona == "Zona Norte", 2))
vivienda_sin_faltantes <- vivienda_sin_faltantes %>% mutate(zona = replace(zona, 
                                               zona == "Zona Oeste", 3))
vivienda_sin_faltantes <- vivienda_sin_faltantes %>% mutate(zona = replace(zona, 
                                               zona == "Zona Oriente",
                                               4))
vivienda_sin_faltantes <- vivienda_sin_faltantes %>% mutate(zona = replace(zona, 
                                               zona == "Zona Sur", 5))
vivienda_sin_faltantes$zona <- as.numeric(vivienda_sin_faltantes$zona)
vivienda_sin_faltantes <- vivienda_sin_faltantes %>% mutate(tipo = replace(tipo, 
                                               tipo == "Casa", 1))
vivienda_sin_faltantes <- vivienda_sin_faltantes %>% mutate(tipo = replace(tipo, 
                                               tipo == "Apartamento", 2))
vivienda_sin_faltantes$tipo <- as.numeric(vivienda_sin_faltantes$tipo)

Mostramos los 10 primeros datos

head(vivienda_sin_faltantes,10)

Correlación

library(psych)
correlacion <- round(cor(vivienda_sin_faltantes), 1)
corPlot(correlacion, number.cex = 0.5)
## Warning in axis(2, at = at2, labels = lab2, las = ylas, ...): "number.cex" is
## not a graphical parameter
## Warning in axis(xaxis, at = at1, labels = lab1, las = xlas, line = line, :
## "number.cex" is not a graphical parameter
## Warning in text.default(rx, ry, rv, cex = 1.5 * cex, ...): "number.cex" is not
## a graphical parameter
## Warning in axis(4, at = at2, labels = labels, las = 2, ...): "number.cex" is
## not a graphical parameter

Análisis de Componentes Principales (ACP) para la vivienda sin faltantes

prcomp(vivienda_sin_faltantes)
## Standard deviations (1, .., p=9):
## [1] 344.44725498  99.08428693   1.41375600   1.32490169   0.87832831
## [6]   0.64073131   0.35613522   0.02791804   0.01517511
## 
## Rotation (n x k) = (9 x 9):
##                        PC1           PC2           PC3           PC4
## zona         -6.022645e-05  7.754669e-05  0.3876571213 -0.9059829768
## estrato      -1.757918e-03  2.658921e-03 -0.0487681915 -0.1703587710
## preciom      -9.499393e-01  3.124180e-01 -0.0002367425  0.0005675973
## areaconst    -3.124135e-01 -9.499122e-01 -0.0070735895 -0.0032818245
## banios       -2.863573e-03 -2.816005e-03  0.5129290706  0.1224899682
## habitaciones -1.298385e-03 -6.406514e-03  0.7568964755  0.3651311057
## tipo          4.290747e-04  2.381065e-03 -0.1060106996 -0.0364862023
## longitud      1.686893e-05 -2.070794e-05 -0.0004299325  0.0024812937
## latitud       1.381150e-05 -2.097949e-05 -0.0081589623  0.0223545511
##                        PC5           PC6           PC7           PC8
## zona         -0.1646401972  0.0236309127  2.672064e-02 -2.319415e-02
## estrato       0.7008440619 -0.6718953020 -1.609642e-01 -5.515396e-03
## preciom      -0.0031416009  0.0003209413 -1.181915e-05 -2.886728e-06
## areaconst     0.0011932459 -0.0006769549  1.358162e-03  6.076337e-06
## banios        0.6271414336  0.5687174727  7.166443e-02 -1.364894e-03
## habitaciones -0.2825924668 -0.4578862389  6.496287e-02  2.372767e-03
## tipo          0.0922901068 -0.1219990991  9.818219e-01  5.094035e-03
## longitud     -0.0041108106  0.0037949965 -3.618378e-03 -6.972039e-02
## latitud      -0.0008187371  0.0004100336  5.593363e-03 -9.972649e-01
##                        PC9
## zona          1.280900e-04
## estrato       4.877734e-03
## preciom       6.623591e-06
## areaconst     3.522254e-06
## banios        5.017419e-04
## habitaciones  3.967647e-04
## tipo          4.806951e-03
## longitud      9.975411e-01
## latitud      -6.974485e-02

Seleccionar variables y escalar

vivienda_escalar <- scale(vivienda_sin_faltantes[, 2:5])

Visualizar los primeros 6 registros

head(vivienda_escalar)
##         estrato    preciom  areaconst      banios
## [1,] -1.5872276 -0.5595498 -0.7339949 -0.07793773
## [2,] -1.5872276 -0.3465670 -0.3842568 -0.77811479
## [3,] -1.5872276 -0.2552886  0.3152194 -0.77811479
## [4,] -0.6156201 -0.1031580  0.7349051  1.32241640
## [5,]  0.3559875 -0.5291236 -0.5940997 -0.77811479
## [6,]  0.3559875 -0.5899759 -0.6150839 -0.07793773

#install.packages(“factoextra”)

library(factoextra)
## Warning: package 'factoextra' was built under R version 4.3.3
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa

Seleccionar variables y escalar

vivienda_escalar <- scale(vivienda_sin_faltantes[, 2:5])

Realizar PCA y visualizar el gráfico

res.pca <- prcomp(vivienda_escalar)
fviz_eig(res.pca, addlabels = TRUE)

El primer componente principal (CP1) explica el 67% de la variabilidad total de los datos. Los dos primeros componentes principales (CP1 y CP2) explican conjuntamente el 86% de la variabilidad total de los datos. El gráfico de ACP indica que es posible resumir gran parte de la variabilidad de la base de datos con una sola variable (CP1).

Grafico PCA

fviz_pca_var(res.pca,
  col.var = "contrib", 
  gradient.cols = c("#FF7F00", "#034D94"),
  repel = TRUE     
)

Cuando vemos las variables en el plano de los componentes principales, podemos entender mejor qué representan esos componentes. Esto se debe a que los componentes principales están definidos por los vectores propios de la matriz de covarianza. En este caso, el primer componente principal está relacionado principalmente con las variables estrato y precio, y el segundo componente está asociado con la variable área construida.

Análisis de conglomerados

head(vivienda_sin_faltantes)

Seleccionar las variables numéricas para el análisis

variables_conglomerados <- vivienda_sin_faltantes[, c('estrato', 'preciom', 'areaconst', 'banios', 'habitaciones', 'longitud', 'latitud')]

Normalización de datos

datos_normalizados <- scale(variables_conglomerados)

Datos normalizados

summary(datos_normalizados)
##     estrato           preciom          areaconst           banios        
##  Min.   :-1.5872   Min.   :-1.1437   Min.   :-1.0138   Min.   :-2.17847  
##  1st Qu.:-0.6156   1st Qu.:-0.6508   1st Qu.:-0.6640   1st Qu.:-0.77812  
##  Median : 0.3560   Median :-0.3161   Median :-0.3633   Median :-0.07794  
##  Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.00000  
##  3rd Qu.: 0.3560   3rd Qu.: 0.3228   3rd Qu.: 0.3782   3rd Qu.: 0.62224  
##  Max.   : 1.3276   Max.   : 4.7620   Max.   :10.9822   Max.   : 4.82330  
##   habitaciones        longitud           latitud        
##  Min.   :-2.4702   Min.   :-3.47989   Min.   :-1.98516  
##  1st Qu.:-0.4148   1st Qu.:-0.74572   1st Qu.:-0.86422  
##  Median :-0.4148   Median :-0.08013   Median :-0.03856  
##  Mean   : 0.0000   Mean   : 0.00000   Mean   : 0.00000  
##  3rd Qu.: 0.2704   3rd Qu.: 0.55844   3rd Qu.: 0.80575  
##  Max.   : 4.3813   Max.   : 3.77083   Max.   : 1.87755

Determinar el número de clusters

X <-datos_normalizados

sse <- numeric(10)  

for (k in 1:10) {
  km <- kmeans(X, centers = k)
  sse[k] <- km$tot.withinss  
}

plot(1:10, sse, type = "b", pch = 19, frame = FALSE, 
     xlab = "Número de clusters (k)", ylab = "SSE",
     main = "Método del codo")

abline(v = 4, col = "red", lty = 2)

Aplicación del Algoritmo K-means

KM=kmeans(datos_normalizados, 4)

head(aggregate(datos_normalizados, by=list(cluster= km$cluster), mean))

Grafica

fviz_cluster(KM, data=datos_normalizados)

Analisis de correspondencia

explorar y visualizar las relaciones entre dos o más variables categóricas.

carga de libreria

library(FactoMineR)
## Warning: package 'FactoMineR' was built under R version 4.3.3
tabla <- table(vivienda_sin_faltantes$zona, vivienda_sin_faltantes$estrato)
tabla
##    
##        3    4    5    6
##   1  105   14    4    1
##   2  572  407  769  172
##   3   54   84  290  770
##   4  340    8    2    1
##   5  382 1616 1685 1043

Se realiza la prueba de chi cuadrado con el fin de encontrar el grado de relación que tienen las dos variables.

chisq.test(tabla)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla
## X-squared = 3830.4, df = 12, p-value < 2.2e-16

El p-valor menor a 0.05 muestra que las variables no son independientes, rechazando la hipótesis nula.

analisisc <- CA(tabla)

# En la zona oeste, el estrato 6 está ubicado en el cuadrante 2. El cuadrante 3, que corresponde a la zona centro, está asociado con el estrato 3. La zona norte, que no tiene estratos definidos, está cerca de los estratos 4 y 5, los cuales están relacionados con la zona sur.

Grafico de varianza

fviz_screeplot(analisisc, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")

Conclusiones

Analisis de componentes principales

El Análisis de Componentes Principales (ACP) se realiza para identificar las variables principales que influyen en la variabilidad del precio de la vivienda. Se ha descubierto que el primer componente principal (CP1) explica el 67% de la variabilidad total, y que al combinar los dos primeros componentes principales se alcanza una explicación del 86%. El gráfico del ACP revela que el CP1 está principalmente relacionado con variables como el estrato, el precio y el área construida.

Analisis de conglomerados

En el Análisis de Conglomerados, se lleva a cabo un análisis de k-means para agrupar las viviendas en categorías basadas en variables relevantes. Se observa una relación positiva entre el estrato socioeconómico, el precio de la propiedad y el número de conglomerados. El conglomerado 1 se distingue por la mayoría de apartamentos, mientras que el conglomerado 3 se caracteriza por una mayor presencia de casas. En contraste, el conglomerado 2 muestra una distribución más equilibrada entre apartamentos y casas.

Analisis de correspondencia

se utiliza para explorar la relación entre variables categóricas y numéricas. Se detecta una asociación muy significativa entre las variables zona y estrato. Además, se observa que el estrato 6 se encuentra principalmente en la Zona Oeste, mientras que los estratos 4 y 5 son más comunes en las Zonas Sur y Norte.