1. Introducción

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.

2. Objetivo

3. Métodos

Los datos son obtenidos de la librería paqueteMETODOS de R y, analizados a través de la misma herramienta haciendo uso de diferentes paquetes que permiten realizar un análisis estadístico de acuerdo a la siguiente metodología.

3.1. Cargue de datos

library(paqueteMODELOS)
data("vivenda")
str(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>

3.2. Identificación de datos faltantes por variable

faltantes <- colSums(is.na(vivienda)) %>% as.data.frame() 
faltantes
##                 .
## 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
library(naniar)
gg_miss_var(vivienda)

VIM::aggr(vivienda, cex.axis =1, cex.lab=1)

3.3. Imputación y estandarización de datos

  • Imputar por cero. Los datos faltantes de la variable “parqueaderos” sugiere que esos inmuebles no tienen parqueaderos.
vivienda$parqueaderos[is.na(vivienda$parqueaderos)] <- 0
  • Imputar por la moda. La variable “piso” es cualitativa de escala ordinal, por lo que los datos faltantes se reemplazan por la moda.
moda_piso <- Mode(vivienda$piso, na.rm = TRUE)
vivienda$piso[is.na(vivienda$piso)] <- moda_piso
  • Eliminar registros con datos faltantes.
vivienda <- na.omit(vivienda)
  • Estandarizar variable “tipo” ya que realmente consta de dos opciones.
vivienda$tipo <- ifelse(vivienda$tipo=="Casa","CASA",ifelse(vivienda$tipo=="casa","CASA",vivienda$tipo))
vivienda$tipo <- ifelse(vivienda$tipo=="apto","APARTAMENTO",ifelse(vivienda$tipo=="Apartamento","APARTAMENTO",vivienda$tipo))
table(vivienda$tipo)
## 
## APARTAMENTO        CASA 
##        5100        3219
  • Ajustar las variables “longitud” y “latitud” de acuerdo a las coordenadas válidas.
vivienda$longitud <- ifelse(vivienda$longitud<=-90,vivienda$longitud/1000,vivienda$longitud)
vivienda$latitud <- ifelse(vivienda$latitud>=270,vivienda$latitud/1000,vivienda$latitud)
  • Crear variable “preciom2” equivalente al precio de venta por metro cuadrado.
vivienda$preciom2 <- vivienda$preciom/vivienda$areaconst
  • Verificar que después de la imputación no se cuenta con datos faltantes.
faltantes <- colSums(is.na(vivienda)) %>% as.data.frame() 
faltantes
##              .
## id           0
## zona         0
## piso         0
## estrato      0
## preciom      0
## areaconst    0
## parqueaderos 0
## banios       0
## habitaciones 0
## tipo         0
## barrio       0
## longitud     0
## latitud      0
## preciom2     0

4. Análisis

4.1. Análisis de componentes principales

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.

  • Definir las varibles “piso”, “estrato”, “parqueaderos”, “banios” y, “habitaciones” como cualitativas de númericas.
vivienda$piso <- as.numeric(vivienda$piso)
vivienda$estrato <- as.numeric(vivienda$estrato)
vivienda$parqueaderos <- as.numeric(vivienda$parqueaderos)
vivienda$banios <- as.numeric(vivienda$banios)
vivienda$habitaciones <- as.numeric(vivienda$habitaciones)
  • Estandarizar las variables antes de estimar los componentes principales, esto con el propósito de evitar que las variables con escalas de valores grandes afecten las estimaciones. Se decide no considerar el “piso” ya que es una variable que originalmente tenía faltantes, lo que puede generar un sesgo.
viviendaC = vivienda[,c(4:9)]
viviendaZ = scale(viviendaC)
head(viviendaZ)
##         estrato    preciom  areaconst parqueaderos      banios habitaciones
## [1,] -1.5872276 -0.5595498 -0.7339949   -0.3875522 -0.07793773    1.6406840
## [2,] -1.5872276 -0.3465670 -0.3842568   -0.3875522 -0.77811479   -0.4147626
## [3,] -1.5872276 -0.2552886  0.3152194    0.4168506 -0.77811479    0.2703863
## [4,] -0.6156201 -0.1031580  0.7349051    1.2212534  1.32241640   -0.4147626
## [5,]  0.3559875 -0.5291236 -0.5940997   -0.3875522 -0.77811479   -0.4147626
## [6,]  0.3559875 -0.5899759 -0.6150839   -0.3875522 -0.07793773   -0.4147626
  • Realizar el cálculo de los componentes principales con las variables estandarizadas.
prcomp(viviendaZ)
## Standard deviations (1, .., p=6):
## [1] 1.8480703 1.1222455 0.6779600 0.6592367 0.4909833 0.4357909
## 
## Rotation (n x k) = (6 x 6):
##                    PC1        PC2        PC3         PC4         PC5        PC6
## estrato      0.3306904 -0.5816950  0.5551021  0.07749341  0.46143880 -0.1587620
## preciom      0.4781754 -0.1883533 -0.0359721 -0.36062553 -0.21967777  0.7458339
## areaconst    0.4417250  0.2388377 -0.2878930 -0.61783592  0.27859384 -0.4534506
## parqueaderos 0.4096354 -0.2607395 -0.6565763  0.57091588  0.04760414 -0.0700729
## banios       0.4668745  0.1921461  0.3633148  0.18500105 -0.67876421 -0.3437503
## habitaciones 0.2847775  0.6813261  0.2111757  0.34936005  0.44521273  0.2997240

Se evidencia que el primer componente principal explica el 56.9% de la variabilidad contenida en la base de datos y entre los dos primeros el 77.9%, lo cual indicaría que con solo una variable (CP1) que se obtiene mediante una combinación lineal de las variables se puede resumir gran parte de la variabilidad que contiene la base de datos.

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

Al analizar el círculo de correlaciones se evidencia que las variables “preciom” está considerablemente correlacionada con “parqueaderos”, lo que indica que a mayor número de parqueaderos mayor es el precio de la vivienda. Lo mismo se evidencia entre las variables “areaconst” y “banios”, lo que sugiere que las viviendas con mayor área construida tiene mayor cantidad de baños.

Por el contrario, se observa que las variables “habitaciones” y “estrato” tienen una baja correlación, dado que son perpendiculares. Sin embargo, ambas variables muestran altos niveles de contribución, es decir que, son importantes para explicar la variabilidad en los datos, siendo las variables son mayor relación con PC2.

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

  • Para explicar el sentido de los ejes, se escogen dos casos extremos conformados por las siguientes viviendas.
casos1 <- rbind(res.pca$x[5717,1:2],res.pca$x[1762,1:2]) # CP1
rownames(casos1) = c("5717","1762")
casos1 <- as.data.frame(casos1)

casos2 <- rbind(res.pca$x[2926,1:2], res.pca$x[8073,1:2]) # CP2
rownames(casos2) = c("2926","8073")
casos2 <- as.data.frame(casos2)

# Genera el gráfico
fviz_pca_ind(res.pca, col.ind = "#DEDEDE", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07")) +
geom_point(data = casos1, aes(x = PC1, y = PC2), color = "red", size = 3) +
geom_text(data = casos1, aes(x = PC1, y = PC2, label = rownames(casos1)), color = "red", vjust = -1) +
geom_point(data = casos2, aes(x = PC1, y = PC2), color = "blue", size = 3) +
geom_text(data = casos2, aes(x = PC1, y = PC2, label = rownames(casos2)), color = "blue", vjust = -1)

datos <- rbind(viviendaC[5717,],
viviendaC[1762,],
viviendaC[2926,],
viviendaC[8073,])

datos <- as.data.frame(datos)
rownames(datos) = c("Vivienda 5717","Vivienda 1762","Vivienda 2926","Vivienda 8073")
datos
##               estrato preciom areaconst parqueaderos banios habitaciones
## Vivienda 5717       4     160        84            1      0            0
## Vivienda 1762       6    1800      1586           10      4            5
## Vivienda 2926       5     950       280           10      0            0
## Vivienda 8073       3     370      1440            1      4           10

La vivienda 5717 presenta un precio bajo $160M, mientras que la vivienda 1762 presenta un precio alto de $1800, evidenciando el sentido en que aumentan los valores de PC1. También se observa cómo el precio se relaciona con el número de parqueadero, así como el área construida con el número de baños.

Por otro lado, la vivienda 2926 es de estrato 5 y la vivienda 8073 de estrato 3, se evidencia que tienen un número de habitaciones de 0 y 10, respectivamente.

fviz_pca_biplot(res.pca, 
repel = TRUE,
habillage = viviendaC$estrato,
col.var = "#034A94", # Variables color
col.ind = c("#DEDEDE", "#034A94")  # Individuals color
)

La representación gráfica de los dos primeros componentes principales nos permite observar la relación existente entre las variables “areaconst” y “banios”, y “preciom” y “parqueaderos” formando un grupo que presenta un mayor efecto sobre PC1, mientras que las variables “habitaciones” y “estrato” presentan mayor efecto sobre PC2.

Los colores en dicha gráfica indican que a mayor estrato, mayor es el precio de la vivienda y el tamaño de la misma.

4.2. Análisis de conglomerados

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.

# Correlación
cor(viviendaC)
##                  estrato   preciom areaconst parqueaderos    banios
## estrato       1.00000000 0.6098066 0.2743233    0.5127889 0.4203218
## preciom       0.60980664 1.0000000 0.6873520    0.6397779 0.6691456
## areaconst     0.27432332 0.6873520 1.0000000    0.4823840 0.6484165
## parqueaderos  0.51278892 0.6397779 0.4823840    1.0000000 0.5231299
## banios        0.42032178 0.6691456 0.6484165    0.5231299 1.0000000
## habitaciones -0.07137615 0.2640912 0.5169129    0.1987555 0.5899064
##              habitaciones
## estrato       -0.07137615
## preciom        0.26409121
## areaconst      0.51691292
## parqueaderos   0.19875551
## banios         0.58990641
## habitaciones   1.00000000
corrplot(cor(viviendaC))

La matriz de correlación muestra que la variable que tiene menor correlación con el precio de la vivienda es el número de habitaciones, esto puede deberse a errores en la recolección de los datos o puede ser un comportamiento correcto, y no ser un factor determinante.

  • Construir los clústers.
# PCA
res.pca <- PCA(viviendaC, graph = FALSE, scale.unit = TRUE )

# Distancia euclidiana
distancia <- dist(res.pca$ind$coord, method = "euclidean")

# Cluster
res.HCPC <-  HCPC(res.pca, nb.clust=4) 

  • Determinar si k=4 es un número de clústers óptimo utilizando el siguiente gráfico (método del codo).
wss <- sapply(1:10, function(k){kmeans(res.pca$ind$coord, k)$tot.withinss})
plot(1:10, wss, type="b", pch = 19, frame = FALSE, 
     xlab="Número de clusters K", ylab="Total within-clusters sum of squares")

  • Índice de Calinski-Harabasz.
# Clustering jerárquico
res.hclust <- hclust(distancia, method = "ward.D2")

# Calculamos el índice de Calinski-Harabasz para diferentes números de clusters
ch <- c()
for (k in 2:10) {
  cluster_assignments <- cutree(res.hclust, k)
  ch[k] <- cluster.stats(distancia, cluster_assignments)$ch
}

# Graficamos el índice de Calinski-Harabasz
plot(2:10, ch[2:10], type = "b", xlab = "Número de clusters", ylab = "Índice de Calinski-Harabasz")

De acuerdo con ambos métodos (método del codo e índice de Calinski-Harabasz) se puede deducir que k=4, es un óptimo número de Clúster.

  • Conocer las características de cada clúster.
res.HCPC$desc.var
## 
## Link between the cluster variable and the quantitative variables
## ================================================================
##                   Eta2 P-value
## estrato      0.5638495       0
## preciom      0.6979368       0
## areaconst    0.5452858       0
## parqueaderos 0.5248949       0
## banios       0.5928349       0
## habitaciones 0.5778037       0
## 
## Description of each cluster by quantitative variables
## =====================================================
## $`1`
##                 v.test Mean in category Overall mean sd in category Overall sd
## habitaciones -39.02301        2.8792762     3.605361      0.7522374   1.459449
## areaconst    -46.64650       89.9194939   174.934938     49.0584275 142.955533
## parqueaderos -46.90204        0.7384789     1.481789      0.5654987   1.243084
## preciom      -53.22682      210.8886062   433.904436     84.3116821 328.645270
## estrato      -54.25919        3.9216850     4.633610      0.7300851   1.029160
## banios       -60.40017        2.0115917     3.111311      0.6160892   1.428124
##              p.value
## habitaciones       0
## areaconst          0
## parqueaderos       0
## preciom            0
## estrato            0
## banios             0
## 
## $`2`
##                  v.test Mean in category Overall mean sd in category Overall sd
## estrato       46.084940         5.348264     4.633610      0.5944452   1.029160
## parqueaderos  13.818823         1.740625     1.481789      0.7103518   1.243084
## banios        10.688655         3.341319     3.111311      0.8837819   1.428124
## preciom        6.950902       468.325347   433.904436    176.0051906 328.645270
## areaconst     -6.755470       160.383351   174.934938     71.9104638 142.955533
## habitaciones -11.801610         3.345833     3.605361      0.7590999   1.459449
##                   p.value
## estrato      0.000000e+00
## parqueaderos 1.962512e-43
## banios       1.150264e-26
## preciom      3.629584e-12
## areaconst    1.423729e-11
## habitaciones 3.829154e-32
## 
## $`3`
##                  v.test Mean in category Overall mean sd in category Overall sd
## habitaciones  63.575009         6.550169     3.605361       1.571131   1.459449
## banios        30.749706         4.505073     3.111311       1.456520   1.428124
## areaconst     27.837912       301.239549   174.934938     131.002770 142.955533
## parqueaderos  -7.410968         1.189402     1.481789       1.065065   1.243084
## estrato      -22.573423         3.896280     4.633610       0.858972   1.029160
##                    p.value
## habitaciones  0.000000e+00
## banios       1.233900e-207
## areaconst    1.508815e-170
## parqueaderos  1.253805e-13
## estrato      7.907997e-113
## 
## $`4`
##                v.test Mean in category Overall mean sd in category Overall sd
## preciom      68.69075      1097.897537   433.904436    349.1186332 328.645270
## parqueaderos 57.74505         3.593103     1.481789      1.5747239   1.243084
## areaconst    54.02679       402.103419   174.934938    195.2082515 142.955533
## banios       46.69877         5.072906     3.111311      1.1888666   1.428124
## estrato      36.25382         5.731034     4.633610      0.5304264   1.029160
## habitaciones 16.14757         4.298522     3.605361      1.2674585   1.459449
##                    p.value
## preciom       0.000000e+00
## parqueaderos  0.000000e+00
## areaconst     0.000000e+00
## banios        0.000000e+00
## estrato      8.650420e-288
## habitaciones  1.181206e-58

La construcción de estos clústeres y su análisis permite conocer las características comunes bajo las cuales se pueden agrupar las viviendas, a fin de facilitar el proceso de venta de estas. Los clústeres obtenidos se analizan de acuerdo al valor v.test.

En el clúster 1 se tienen las Viviendas con valores bajos en las variables estudiadas, es decir, aquellas viviendas de menor precio y área construida, estrato más bajo, y menor número de baños, habitaciones y parqueaderos.

En el clúster 2 se encuentran aquellas viviendas con estratos altos, cuyo número de parqueaderos y baños es intermedio, pero tienen menor área construida y menor número de habitaciones.

En el clúster 3 se ubican las viviendas de bajos estratos que tienen mayor número de habitaciones y de baños, con un área construida intermedia, pero con bajo número de parqueaderos.

En el clúster 4 están las viviendas que tienen valores altos en las variables estudiadas, es decir, las viviendas de mayor precio y área construida, estrato alto, y mayor número de baños, habitaciones y parqueaderos.

4.3. Análisis de correspondencia

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.

  • Seleccionar las variables a analizar, se incluye el precio de la vivienda.
viviendaC2 = vivienda[,c(2,5,10,11)]
  • Conocer la distribución de los precios de las viviendas.
hist(viviendaC2$preciom)

  • Definir los intervalos bajo los cuales se analizará el precio, teniendo en cuenta que los valores oscilan entre 0 y 2000, en 8 grupos de $250M.
breaks <- seq(0, 2000, by = 250)
  • Crear una nueva base a partir de los intervalos.
vivienda_AC <- viviendaC2
vivienda_AC$preciom <- NULL  # Elimina la variable preciom
vivienda_AC$preciom_categorizado <- cut(viviendaC2$preciom, breaks = breaks, include.lowest = TRUE, labels = FALSE)
  • Transformar los datos de “vivienda_AC” a tipo factor.
labels <- paste0("[", breaks[-length(breaks)], "-", breaks[-1], ")")
vivienda_AC$preciom_categorizado <- cut(viviendaC2$preciom, breaks = breaks, include.lowest = TRUE, labels = labels)
vivienda_AC$zona <- as.factor(vivienda_AC$zona)
vivienda_AC$tipo <- as.factor(vivienda_AC$tipo)
vivienda_AC$barrio <- as.factor(vivienda_AC$barrio)
  • Crear gráficos de barras. La variable “barrio” tiene muchas categorías por lo que no se considera en el análisis de correspondencia.
GZ <- ggplot(vivienda_AC, aes(x=zona)) + geom_bar(fill= "blue") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

GT <- ggplot(vivienda_AC, aes(x=tipo)) + geom_bar(fill= "green")

GP <- ggplot(vivienda_AC, aes(x=preciom_categorizado)) + geom_bar(fill= "gray") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

grid.arrange(GZ, GT, GP, ncol = 3)

  • Realizar tablas cruzadas: Zona vs Tipo, Precio vs Tipo y, Precio vs Zona

Zona vs Tipo

tabla1 <- table(vivienda_AC$zona, vivienda_AC$tipo)
colnames(tabla1) <- c("APARTAMENTO", "CASA")
tabla1
##               
##                APARTAMENTO CASA
##   Zona Centro           24  100
##   Zona Norte          1198  722
##   Zona Oeste          1029  169
##   Zona Oriente          62  289
##   Zona Sur            2787 1939
chisq.test(tabla1)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla1
## X-squared = 690.93, df = 4, p-value < 2.2e-16

El resultado indica que se rechaza la hipótesis de independencia de las variables (p-value: 0.0000), indicando grado tipo de relación entre ellas.

resultados_ac_1 <- CA(tabla1)
fviz_screeplot(resultados_ac_1, addlabels = TRUE)+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

Los resultados indican que la primera componente resumen el 100%.

Precio vs Tipo

tabla2 <- table(vivienda_AC$preciom_categorizado, vivienda_AC$tipo)
colnames(tabla2) <- c("APARTAMENTO", "CASA" )
tabla2
##              
##               APARTAMENTO CASA
##   [0-250)            2302  525
##   [250-500)          1772 1462
##   [500-750)           575  593
##   [750-1000)          220  317
##   [1000-1250)         112  123
##   [1250-1500)          78  108
##   [1500-1750)          22   57
##   [1750-2000)          19   34
chisq.test(tabla2)
## 
##  Pearson's Chi-squared test
## 
## data:  tabla2
## X-squared = 805.48, df = 7, p-value < 2.2e-16

El resultado indica que se rechaza la hipótesis de independencia de las variables (p-value: 0.0000), indicando grado tipo de relación entre ellas.

resultados_ac_2 <- CA(tabla2)
fviz_screeplot(resultados_ac_2, addlabels = TRUE)+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")
## `geom_line()`: Each group consists of only one observation.
## ℹ Do you need to adjust the group aesthetic?

Los resultados indican que la primera componente resumen el 100%.

Precio vs Zona

tabla3 <- table(vivienda_AC$preciom_categorizado, vivienda_AC$zona)
colnames(tabla3) <- c("Zona Centro", "Zona Norte", "Zona Oeste", "Zona Oriente", "Zona Sur")
tabla3
##              
##               Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
##   [0-250)              49        805         98          228     1647
##   [250-500)            64        776        400          119     1875
##   [500-750)             8        219        323            3      615
##   [750-1000)            2         80        151            0      304
##   [1000-1250)           1         21        109            0      104
##   [1250-1500)           0         12         73            1      100
##   [1500-1750)           0          5         21            0       53
##   [1750-2000)           0          2         23            0       28
chisq.test(tabla3)
## Warning in chisq.test(tabla3): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  tabla3
## X-squared = 1090.2, df = 28, p-value < 2.2e-16

El resultado indica que se rechaza la hipótesis de independencia de las variables (p-value: 0.0000), indicando grado tipo de relación entre ellas.

resultados_ac_3 <- CA(tabla3)

El gráfico muestra que las viviendas con precios más altos están ubicadas en la zona oeste, las viviendas con precios medio-altos están en la zona Sur, las viviendas con precios medio-bajos están en la zona norte y las viviendas con precios bajos están en las zona centro y oriente.

fviz_screeplot(resultados_ac_3, addlabels = TRUE)+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")

Los resultados indican que la primera componente resumen el 89.1% y los dos primeros componentes prepresentados en el plano factorial, mientras que los dos primeros ejes resumen un 97.2% de los datos.

5. Conclusiones

Esta base de datos cuenta con variables numéricas que al ser transformadas permiten establecer correlaciones entre ellas, y realizar asociaciones con la variación de los precios de las viviendas, gracias al uso del ACP.

Por su parte, el análisis de conglomerados presenta una visión más amplia de lo que se observa con el ACP, dado que al definir los grupos de segmentación se logra identificar patrones en las características de las viviendas. La caracterización de las viviendas se puede traducir en oportunidades de negocio, e identificación de grupos foco.

El análisis de correspondencias presenta relaciones entre las variables categóricas que pueden no ser tan evidentes, lo cual es positivo al momento de establecer paramétros para la venta de viviendas.

6. Anexos

No se incluyen anexos, dado que todo el código está en contenido en el desarrollo del trabajo.