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.
El reto principal consisten en realizar un análisis integral y multidimensional de la base de datos para obtener una comprensión del mercado inmobiliario urbano. Se requiere aplicar diversas técnicas de análisis de datos, incluyendo:
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.
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.
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.
Visualización de resultados: Presentar gráficos, mapas y otros recursos visuales para comunicar los hallazgos de manera clara y efectiva a la dirección de la empresa.
## # 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>
## [1] 8322 13
se visualiza la cantidad de datos con el que se va trabajar para este caso es un conjunto que cuenta con 13 columnas caracteristicas y un total de 8322 observaciones de viviendas
#se hace un resumen de las variables numericas
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
Estrato: Los estratos varían entre 3 y 6, con una mediana de 5, lo que sugiere una concentración en estratos más altos.
Preciom (Precio por metro cuadrado): Hay una amplia variación en el precio por metro cuadrado, lo que podría ser un indicador clave de diferencias en la valoración de las propiedades en diferentes zonas o condiciones.
Areaconst (Área Construida): El área construida también varía significativamente, con valores extremos que podrían ser outliers o propiedades atípicas.
Parqueaderos y Baños: La cantidad de parqueaderos y baños también varía, y podría estar relacionada con el tamaño y lujo de la propiedad.
faltantes <- colSums(is.na(vivienda)) %>% as.data.frame()
# se verifica los datos faltantes como una tabla
#
gg_miss_var(vivienda, show_pct = FALSE)
La variable piso y parqueaderos tienen una cantidad significativamente mayor de datos faltantes comparada con otras variables. La ausencia de estos datos podría ser un indicativo de que es menos frecuente que se registre esta información o que no es aplicable a todas las propiedades (por ejemplo, propiedades sin parqueadero).
VIM::aggr(vivienda, cex.axis = 0.3, cex.lab = 0.9, plot = TRUE,delimiter = NULL)
# Se calcula el porcentaje de valores NA para cada variable
porcentaje_na <- map_dfr(names(vivienda), ~ {
data.frame(variable = .x, porcentaje_na =
round((sum(is.na(vivienda[[.x]])) / length(vivienda[[.x]])) * 100, 2))
})
# Imprimir porcentaje de NAs
porcentaje_na <- porcentaje_na %>%
arrange(desc(porcentaje_na))
print(porcentaje_na)
## variable porcentaje_na
## 1 piso 31.70
## 2 parqueaderos 19.29
## 3 id 0.04
## 4 zona 0.04
## 5 estrato 0.04
## 6 areaconst 0.04
## 7 banios 0.04
## 8 habitaciones 0.04
## 9 tipo 0.04
## 10 barrio 0.04
## 11 longitud 0.04
## 12 latitud 0.04
## 13 preciom 0.02
Parqueaderos: Este campo muestra la mayor proporción de datos faltantes, casi un 20% de las observaciones no tienen información de parqueaderos. Es importante considerar si esta variable es crucial para el análisis y si es posible imputar estos valores faltantes
El atributos “piso” presentan la mayor cantidad de datos faltantes, con 31,70% de registros ausentes, respectivamente. Los 11 atributos restantes tienen un máximo de 0,04%
Para variables continuas como preciom, areaconst, y banios, podrías considerar técnicas de imputación como la media, mediana, o imputación multivariante. Para variables categóricas como piso, la imputación por la moda
#Verificar si aún hay valores faltantes después de la imputación
any(is.na(vivienda))
## [1] TRUE
# se grafica los valors faltantes y en cero
md.pattern(vivienda,rotate.names =TRUE)
## 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
la presencia de registros con valores iguales a 0 en las variables correspondientes a “habitaciones” y “baños”. Una revisión detallada revela que estos valores atípicos se encuentran exclusivamente en el rango de 3 a 6, según los estratos identificados. Dado que los tipos de propiedades registradas son viviendas y apartamentos, resulta poco plausible que una propiedad carezca completamente de al menos una habitación o un baño.
Por consiguiente, abordaremos estas discrepancias tratándolas como valores faltantes (missing values). Este enfoque nos permitirá integrarlos al proceso de imputación de datos ausentes, con el objetivo de lograr una corrección más exhaustiva y precisa Este enfoque es efectivo
Utilizar la media para imputar valores faltantes ayuda a mantener la distribución original de los datos.
El método es simple y fácil de implementar, no requiere técnicas estadísticas avanzadas y es robusto frente a valores extremos.
La imputación con la media no introduce sesgo adicional en los datos y es menos sensible a valores extremos que otras medidas de tendencia central.
Se crea una funcion para eliminar los valores nulos y los ceros
# Función para calcular la moda
calcular_moda <- function(x) {
tabla <- table(x)
moda <- names(tabla[tabla == max(tabla)])
if (length(moda) > 1) moda <- moda[1] # En caso de múltiples modas, selecciona la primera
return(moda)
}
# Función para imputar valores faltantes y ceros
imputar_valores <- function(data) {
for (col_name in names(data)) {
# Verifica si la columna es numérica
if (is.numeric(data[[col_name]])) {
# Excluir NA y ceros para calcular la media
media_valida <- mean(data[[col_name]][data[[col_name]] != 0], na.rm = TRUE)
# Reemplaza NA y ceros con la media calculada
indices <- which(is.na(data[[col_name]]) | data[[col_name]] == 0)
data[[col_name]][indices] <- media_valida
} else {
# Imputar con la moda para columnas no numéricas
moda <- calcular_moda(data[[col_name]])
data[[col_name]][is.na(data[[col_name]])] <- moda
}
}
return(data)
}
Este proceso de imputación se llevará a cabo con el objetivo de mitigar posibles distorsiones en los resultados y garantizar una representación más exacta de la relación entre las características y los precios de las propiedades.
vivienda_limpia <- imputar_valores(vivienda)
# Revisa si la imputación se ha aplicado correctamente
sum(is.na(vivienda_limpia))
## [1] 0
# Eliminando las columnas 'id',usando subset()
#
vivienda_data <- subset(vivienda_limpia, select = -c(id,piso, barrio, parqueaderos))
vivienda_data_2 <- subset(vivienda_limpia, select = -c(id,piso, parqueaderos))
any(is.na( vivienda_data))
## [1] FALSE
md.pattern(vivienda_data,rotate.names = TRUE)
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
## zona estrato preciom areaconst banios habitaciones tipo longitud latitud
## 8322 1 1 1 1 1 1 1 1 1 0
## 0 0 0 0 0 0 0 0 0 0
Dado que todas las variables están completas,se puede avanzar directamente a realizar los análisis planificados, como el Análisis de Componentes Principales (PCA), Análisis de Conglomerados, Análisis de Correspondencia y las visualizaciones correspondientes sin tener que realizar pasos adicionales de limpieza de datos específicos para manejar los valores ausentes.
Realizar una verificación de la calidad de los datos para asegurarse de que no hay errores de entrada, valores atípicos inusuales o inconsistencias en los datos que puedan afectar tus análisis
Se convierten las variables categóricas a factores con etiquetas numéricas, Este enfoque es crucial para asegurarse de que las categorías tengan un tratamiento adecuado en análisis subsiguientes, evitando malinterpretaciones que podrían surgir si se tratara a estas variables como numéricas continuas.
Se verifica que todos los datos sean de tipo numerico
str(vivienda_data)
## tibble [8,322 × 9] (S3: tbl_df/tbl/data.frame)
## $ zona : num [1:8322] 4 4 4 5 2 2 2 2 2 2 ...
## $ 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 ...
## $ 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 : num [1:8322] 1 1 1 1 2 2 2 2 1 1 ...
## $ 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 ...
Se analizan las correlaciones
vivienda_num = vivienda_data[, c("zona","estrato","preciom","areaconst","habitaciones",
"longitud","latitud", "tipo","banios")]
vivienda_scaled = scale(vivienda_num)
print(cor(vivienda_scaled[, c("estrato","areaconst","habitaciones","longitud","latitud","zona", "tipo","banios")], vivienda_scaled[, c("preciom")]), method = "render")
## [,1]
## estrato 0.6098030
## areaconst 0.6873478
## habitaciones 0.2744352
## longitud -0.3435862
## latitud -0.1156669
## zona 0.0160652
## tipo -0.2564588
## banios 0.6821337
Estrato, Área Construida, Parqueaderos, y Baños: Todas estas variables muestran fuertes correlaciones positivas con el precio por metro cuadrado, indicando que a medida que estas características mejoran o aumentan, el precio por metro cuadrado también tiende a aumentar
Las demas variables excepto latitud y longitud presentan una correlación positiva pero más débil, sugiriendo un impacto menos directo sobre el precio comparado con otros atributos como el área construida o estracto.
La normalización garantizará que los rangos extensos no influyan de manera desproporcionada en las comparaciones y cálculos de distancia realizados por los algoritmos.
# se verifica que los datos no tengan variables faltantes
md.pattern(vivienda_data)
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
## zona estrato preciom areaconst banios habitaciones tipo longitud latitud
## 8322 1 1 1 1 1 1 1 1 1 0
## 0 0 0 0 0 0 0 0 0 0
# Normalizar todas las columnas numéricas del dataframe
vivienda_inter_normalized <- as.data.frame(lapply(vivienda_data, function(x) {
if (is.numeric(x)) { # Asegúrate de aplicar scale() solo a columnas numéricas
scale(x)
} else {
x # Retorna la columna sin cambios si no es numérica
}
}))
# Verificar los primeros registros para asegurar que los datos están normalizados
head(vivienda_inter_normalized)
## zona estrato preciom areaconst banios habitaciones
## 1 0.06163572 -1.5875138 -0.5596093 -0.7341272 -0.09098401 1.6622921
## 2 0.06163572 -1.5875138 -0.3465894 -0.3843261 -0.80050491 -0.4456050
## 3 0.06163572 -1.5875138 -0.2552951 0.3152762 -0.80050491 0.2570274
## 4 0.81484051 -0.6157311 -0.1031380 0.7350376 1.32805781 -0.4456050
## 5 -1.44477387 0.3560517 -0.5291779 -0.5942068 -0.80050491 -0.4456050
## 6 -1.44477387 0.3560517 -0.5900407 -0.6151949 -0.09098401 -0.4456050
## tipo longitud latitud
## 1 -1.2590014 0.9730220 0.3794392
## 2 -1.2590014 0.9333558 0.3763898
## 3 -1.2590014 0.7608937 0.4226005
## 4 -1.2590014 -0.6550196 0.4071187
## 5 0.7941849 0.8683951 0.9679811
## 6 0.7941849 0.6671894 -1.1244036
#se verifica que todas las medias esten cero
summary(vivienda_inter_normalized)
## zona estrato preciom areaconst
## Min. :-2.1980 Min. :-1.5875 Min. :-1.1439 Min. :-1.0140
## 1st Qu.:-0.6916 1st Qu.:-0.6157 1st Qu.:-0.6509 1st Qu.:-0.6642
## Median : 0.8148 Median : 0.3561 Median :-0.3162 Median :-0.3633
## Mean : 0.0000 Mean : 0.0000 Mean : 0.0000 Mean : 0.0000
## 3rd Qu.: 0.8148 3rd Qu.: 0.3561 3rd Qu.: 0.3229 3rd Qu.: 0.3782
## Max. : 0.8148 Max. : 1.3278 Max. : 4.7628 Max. :10.9842
## banios habitaciones tipo longitud
## Min. :-1.51003 Min. :-1.8509 Min. :-1.2590 Min. :-3.48052
## 1st Qu.:-0.80051 1st Qu.:-0.4456 1st Qu.:-1.2590 1st Qu.:-0.74585
## Median :-0.09098 Median :-0.4456 Median : 0.7942 Median :-0.08015
## Mean : 0.00000 Mean : 0.0000 Mean : 0.0000 Mean : 0.00000
## 3rd Qu.: 0.61854 3rd Qu.: 0.2570 3rd Qu.: 0.7942 3rd Qu.: 0.55854
## Max. : 4.87566 Max. : 4.4728 Max. : 0.7942 Max. : 3.77151
## latitud
## Min. :-1.98552
## 1st Qu.:-0.86426
## Median :-0.03282
## Mean : 0.00000
## 3rd Qu.: 0.80589
## Max. : 1.87789
La normalización es un paso crítico en el preprocesamiento de datos para Garantizar que los resultados y las interpretaciones no estén sesgados por las diferencias inherentes en las escalas originales de las variables.
Análisis de Componentes Principales es una técnica útil en la reducción de dimensionalidad, particularmente eficaz para descubrir patrones en datos de alta dimensión y visualizar la estructura subyacente de los datos.
prcomp(vivienda_inter_normalized)
## Standard deviations (1, .., p=9):
## [1] 1.8434723 1.4066388 1.2198251 0.8117494 0.6800355 0.5883929 0.4994722
## [8] 0.4836345 0.4289960
##
## Rotation (n x k) = (9 x 9):
## PC1 PC2 PC3 PC4 PC5
## zona -0.09834721 0.45569152 0.535945371 -0.06389593 -0.09312818
## estrato -0.28108931 0.37129933 -0.410152759 -0.28179211 -0.10926868
## preciom -0.44794031 0.07445802 -0.283595624 -0.27441847 0.12674365
## areaconst -0.45855539 -0.17207625 -0.009062715 -0.11642788 0.29198783
## banios -0.47797792 -0.06885336 -0.035567585 -0.03847673 -0.39619770
## habitaciones -0.33623879 -0.34680551 0.264772286 0.30881436 -0.57168862
## tipo 0.30763129 0.32970867 -0.361032516 -0.04207044 -0.59260162
## longitud 0.21222761 -0.36725961 0.243747323 -0.84588718 -0.20420729
## latitud 0.13854991 -0.50072501 -0.450446458 0.11622288 -0.03726735
## PC6 PC7 PC8 PC9
## zona 0.15584490 0.649305050 0.18988569 0.027181218
## estrato -0.49571966 0.248046331 -0.45487678 -0.096829980
## preciom 0.27928869 -0.063021835 0.24676520 0.692201246
## areaconst 0.56235007 0.067906123 -0.31873268 -0.488654150
## banios -0.20400079 -0.167183672 0.60845954 -0.409009140
## habitaciones 0.00702830 0.031685632 -0.42362342 0.306366911
## tipo 0.54118847 -0.088855306 -0.04321872 -0.103518196
## longitud -0.02673395 -0.002649729 -0.05158052 0.007684307
## latitud 0.02166167 0.686612212 0.20084505 -0.005955382
res.pca <- prcomp(vivienda_inter_normalized)
fviz_eig(res.pca, addlabels = TRUE)
Variables Clave: Las variables de areaconst, banios, y preciom son importantes en el primer componente, lo que refleja la importancia de las características físicas y de valor de las propiedades.
Variabilidad Geográfica: Los componentes que muestran altos loadings para zona, longitud, y latitud reflejan diferencias geográficas, que son esenciales para el análisis inmobiliario.
PC1: Explica el 37.8% de la varianza total, lo que indica que este componente capta una gran parte de la información en los datos.
PC2: Explica el 22% de la varianza.
PC3: Explica el 16.5% de la varianza.
Los siguientes componentes explican una porción cada vez menor de la varianza total, con una disminución notable en el porcentaje de varianza explicada a medida que avanzamos hacia componentes de orden superior.
fviz_pca_ind(res.pca, geom.ind = "point",
col.ind = "blue",
axes = c(1, 2),
pointsize = 1.5)
La mayoría de los puntos están agrupados cerca del centro, pero hay una considerable dispersión a lo largo del eje X, lo que indica que el primer componente principal tiene un rol significativo en diferenciar entre las observaciones
La mayor dispersión a lo largo del eje X que en el eje Y sugiere que las características que componen el PC1 son críticas para entender las diferencias entre las propiedades. La menor dispersión a lo largo del eje Y indica que el segundo componente, aunque importante, es secundario al primero en términos de explicar las diferencias.
No parece haber agrupaciones distintas o clústeres obvios en este gráfico, lo que puede indicar que las propiedades tienen variaciones continuas en las características observadas o que más de dos dimensiones son necesarias para captar agrupaciones claras.
fviz_pca_var(res.pca,
col.var = "contrib",
gradient.cols = c("#FF7F00", "#034D94"),
repel = TRUE)
Zona y Tipo: Estas variables se proyectan hacia la derecha y tienen una contribución significativa al segundo componente principal. Esto puede sugerir diferencias relacionadas con la ubicación geográfica y el tipo de propiedad en cuanto a cómo se agrupan los datos.
Estrato: Alineado mayormente a lo largo del segundo componente, sugiriendo que esta variable es importante para diferenciar datos en la dimensión de PC2.
Longitud y Latitud: Apuntan hacia abajo en el gráfico, indicando una fuerte influencia en ambos componentes, pero especialmente en PC2. Esto podría estar reflejando efectos geográficos.
Preciom, Banios, Areaconst, y Habitaciones: Estas variables apuntan hacia la izquierda y ligeramente hacia abajo, indicando una correlación negativa con variables como ‘zona’ y ‘tipo’ en PC1 y PC2.
Las variables que tienen las proyecciones más largas son candidatas importantes para incluir en modelos predictivos, ya que son las que más información aportan sobre la estructura de los datos.
El análisis de conglomerados es una herramienta poderosa para identificar segmentos de propiedades con características similares. Este enfoque puede revelar patrones y relaciones que no son obvios a simple vista y ayudar a la empresa a tomar decisiones estratégicas más informadas.
Segmentación de Propiedades: Agrupar propiedades por características como ubicación, tamaño, precio y facilidades. Esto puede ayudar a identificar nichos de mercado o a ajustar estrategias de marketing y ventas.
Estrategia de Precios: Identificar conglomerados de propiedades que comparten características similares y que podrían justificar una estrategia de precios similar.
Optimización de Inventarios: Determinar qué tipos de propiedades son comunes o raras, ayudando a la empresa a gestionar mejor su portafolio de propiedades.
Se aplicara el metodo del codo ya que es esencial para visualizar cómo cambia la suma de los cuadrados dentro de los clústeres (WCSS, por sus siglas en inglés) a medida que aumenta el número de clústeres. La WCSS mide la variabilidad interna de los clústeres y se busca minimizar este valor para obtener clústeres más cohesivos
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
options(encoding = "UTF-8")
# Determinar el número óptimo de clusters usando el método del codo
# Calcular la suma de cuadrados dentro de los clústeres para diferentes números de clústeres
k <- 3
wcss <- sapply(1:12, function(k) {
kmeans(vivienda_inter_normalized, centers = k, nstart = 25)$tot.withinss
})
# Crear el gráfico del codo
plot(1:12, wcss, type = "b", xlab = "Número de clústeres", ylab = "Suma de cuadrados dentro de los clústeres", main = "Método del Codo")
Observamos que la línea tiene un cambio más pronunciado entre 2 y 4 clústeres, indicando una rápida disminución en la suma de cuadrados dentro de los clústeres. Este es un indicador de que cada nuevo clúster agregado está capturando una cantidad significativa de variabilidad adicional en los datos
Basado en esta gráfica, el “codo” parece estar alrededor de 3 clústeres. Elegir más de 4 clústeres proporciona beneficios decrecientes en términos de disminución de la WCSS. Por lo tanto, 3 podría ser el número óptimo de clústeres para este conjunto de datos, ya que proporciona un buen equilibrio entre la suma de cuadrados dentro de los clústeres y el número de clústeres.
# Ajustar el modelo k-means con el número óptimo de clusters
k_optimo <- 3
set.seed(123)
modelo_kmeans <- kmeans(vivienda_inter_normalized, centers = k_optimo, nstart = 10)
# Asignar las etiquetas de cluster a cada observación en los datos
cluster_labels <- as.factor(modelo_kmeans$cluster)
# Agregar las etiquetas de cluster al conjunto de datos original
vivienda_limpia_cloustering <- mutate(vivienda_data, cluster = cluster_labels)
# Visualizar los clusters en función de algunas variables relevantes
ggplot(vivienda_limpia_cloustering, aes(x = estrato, y = preciom, color = cluster)) +
geom_point() +
labs(title = "Clusters de Propiedades Residenciales",
x = enc2utf8("Estrato Socioeconómico"),
y = "Precio de la Propiedad") +
theme_minimal() +
scale_color_discrete(name = "Cluster")
Cluster 1 (Rojo): Se observa que este cluster tiene puntos principalmente en los estratos 3, 4, 5 y 6. Las propiedades en este cluster parecen tener precios más bajos en comparación con otros clusters dentro del mismo estrato.
Cluster 2 (Verde): Este cluster tiene una distribución más amplia de precios en cada estrato y está presente en todos los estratos mostrados. Representa probablemente el segmento medio del mercado en términos de precio.
Cluster 3 (Azul): Este cluster parece contener propiedades que generalmente están en el extremo inferior de los precios, especialmente notorio en los estratos 5 y 6
El gráfico muestra claramente cómo el precio de las propiedades se segmenta por estrato socioeconómico. Los estratos más altos (5 y 6) tienden a tener una gama más amplia de precios comparados con los estratos más bajos, lo que podría indicar una mayor diversidad de propiedades en las zonas de mayor estrato
# Asumimos que 'vivienda_inter_normaliza' es tu dataframe con los datos normalizados
#
set.seed(123) # Para reproducibilidad
kmeans_result <- kmeans(vivienda_inter_normalized, centers = 3, nstart = 25)
# Visualizar los grupos formados
fviz_cluster(kmeans_result, data = vivienda_inter_normalized)
# Realizar agrupamiento jerárquico
hc <- hclust(dist(vivienda_inter_normalized), method = "ward.D2")
# Cortar el árbol para formar 3 grupos
clusters <- cutree(hc, k = 3)
Se visualiza los resultados de un análisis de conglomerados aplicado a datos de propiedades inmobiliarias, utilizando los dos primeros componentes principales (Dim1 y Dim2) para reducir la dimensionalidad y facilitar la visualización.
Los clusters están claramente separados en el espacio de los componentes principales, lo que indica que el método de clustering ha sido efectivo en diferenciar grupos con características distintas.
Cluster Rojo (1): Aparece predominantemente en el área derecha del gráfico, implicando que estas propiedades tienen características únicas que son capturadas por los valores positivos en Dim1.
Cluster Verde (2): Se localiza en la parte central e izquierda, indicando otro conjunto de características.
Cluster Azul (3): Está principalmente en la parte izquierda, mostrando diferencias claras comparado con los otros dos clusters.
# Gráfico de Barras (Distribución de Observaciones por Cluster para el Tipo de Propiedad)
# Primero, definamos los colores personalizados que planeas usar para el gráfico
colores_personalizados <- c("#009092", "#ffff00", "#e10221")
vivienda_limpia_cloustering$tipo <- as.factor(vivienda_limpia_cloustering$tipo)
# A continuación, el primer gráfico que muestra la distribución de observaciones por Cluster y Tipo de Propiedad
ggplot(vivienda_limpia_cloustering, aes(x = factor(cluster), fill = tipo)) +
geom_bar(position = "fill") +
labs(title = "Distribución de Observaciones por Cluster y Tipo de Propiedad", x = "Cluster", y = "Proporción") +
theme_minimal() +
scale_fill_manual(values = colores_personalizados) # Usar colores personalizados para el 'fill'
Cluster 1: Muestra una distribución casi equitativa entre casas y apartamentos, con una ligera mayoría de casas.
Cluster 2: Similar al Cluster 1, este grupo también presenta una distribución equilibrada, pero con una ligera mayoría de apartamentos.
Cluster 3: Este cluster destaca por una predominancia significativa de apartamentos sobre casas.
Los clusters 1 y 2, al mostrar una distribución más balanceada entre casas y apartamentos, podrían estar ubicados en áreas urbanas donde hay una demanda diversa tanto de casas como de apartamentos. Estos clusters pueden beneficiarse de estrategias de marketing que apunten a ambos segmentos de mercado.
El Cluster 3, con una mayoría clara de apartamentos, podría estar en una zona altamente urbanizada o con restricciones de espacio, lo que favorece a los edificios de apartamentos sobre las casas. Las estrategias de desarrollo y promoción en este cluster podrían enfocarse más en apartamentos, posiblemente ofreciendo características o comodidades que atraigan a los residentes urbanos.
# Diagrama de dispersión para la relación entre 'preciom' y 'areaconst'
ggplot(vivienda_limpia_cloustering, aes(x = preciom, y = areaconst, color = factor(cluster))) +
geom_point() +
labs(title = "Relación entre precio y área construida por clúster",
x = "Precio",
y = "Área construida",
color = "Clúster") +
theme_minimal() +
theme(legend.position = "bottom")
Clúster 1 (Rojo): Las propiedades en este clúster parecen tener un precio y área construida menores en comparación con los otros clústeres. Este clúster podría representar propiedades más económicas o más pequeñas.
Clúster 2 (Verde): Este clúster contiene propiedades con una gama más amplia de precios y áreas construidas, aunque predominantemente en el rango medio de ambos. Esto sugiere que podría incluir una variedad de propiedades residenciales que varían en tamaño y valor.
Clúster 3 (Azul): Las propiedades en este clúster tienden a tener un área construida relativamente consistente pero varían más en precio. Esto podría indicar propiedades que, aunque similares en tamaño, varían en características que afectan su precio, como ubicación, calidad de construcción, o amenidades.
# Gráfico de Densidad (Distribución de Precios por Cluster)
ggplot(vivienda_limpia_cloustering, aes(x = preciom, fill = cluster)) +
geom_density(alpha = 0.5) +
labs(title = "Distribución de Precios por Cluster", x = "Precio", y = "Densidad") +
theme_minimal()
Este clúster presenta la gama de precios más baja entre los tres, con una concentración significativa en precios muy bajos. La distribución es bastante estrecha, indicando que la mayoría de las propiedades en este clúster tienen precios similares y relativamente bajos. El pico está claramente definido y no se extiende mucho más allá de los 500 en el eje de precios.
Las propiedades en este clúster tienen una gama de precios más amplia y una distribución más plana comparada con el clúster 1, lo que sugiere una mayor variabilidad en los precios de las propiedades. La distribución alcanza un pico alrededor de los 500 pero se extiende hasta aproximadamente 1000, con una cola que se prolonga hacia precios más altos.
Este clúster tiene la gama de precios más amplia, extendiéndose desde precios bajos hasta más de 1500. La densidad de precios es menor en comparación con los otros dos clústeres, lo que indica que hay una diversidad significativa en el valor de las propiedades. Aunque el pico principal está alrededor de los 500 como en el clúster 2, la distribución es más ancha y la cola se extiende considerablemente hacia precios más altos.
# Mapa de Clusters (Si tienes datos geoespaciales)
ggplot(vivienda_limpia_cloustering, aes(x = longitud, y = latitud, color = cluster)) +
geom_point() +
labs(title = "Mapa de Clusters", x = "Longitud", y = "Latitud", color = "Cluster") +
theme_minimal()
Clúster 1 (Rojo): Este clúster parece concentrarse en la parte superior del mapa, lo que puede indicar una región específica de la ciudad o área que comparte características comunes en términos de precios, tipo de propiedad, u otras variables relevantes.
Clúster 2 (Verde): Distribuido principalmente en la parte central del mapa, este clúster podría representar una zona intermedia en términos de las características de las propiedades.
Clúster 3 (Azul): Localizado en la parte inferior, este clúster podría corresponder a otra área distinta que tiene atributos específicos de propiedades que lo diferencian de los otros dos clústeres.
La distribución de los clústeres puede ayudar a identificar áreas para el desarrollo futuro o la renovación urbana, alineando las inversiones con las características del mercado local.
# Calcular la matriz de correlación
correlation_matrix <- cor(vivienda_inter_normalized)
# Convertir la matriz de correlación en un marco de datos
correlation_df <- as.data.frame(as.table(correlation_matrix))
colnames(correlation_df) <- c("Var1", "Var2", "Correlation")
# Graficar la matriz de correlación como un mapa de calor
ggplot(data = correlation_df, aes(x = Var1, y = Var2, fill = Correlation)) +
geom_tile() +
scale_fill_gradient2(low = "green", high = "red", mid = "white", midpoint = 0) +
theme_minimal() +
labs(title = "Matriz de Correlación")
Número de baños y área construida: Esto sugiere que propiedades más grandes tienden a tener más baños, ademas de Estrato y precio: Indica que propiedades en estratos más altos tienden a tener precios más altos, lo que es esperado ya que el estrato suele reflejar la calidad y ubicación de la propiedad.
Variables como latitud y longitud parecen tener correlaciones débiles con otras variables, lo que podría sugerir que la ubicación geográfica exacta (en términos de coordenadas GPS) tiene menos influencia directa sobre las características de las propiedades comparadas con otras variables más descriptivas como el estrato o el área construida
El Análisis de Correspondencia (AC) es una técnica estadística multivariante diseñada para analizar tablas de contingencia que contienen algunas medidas de correspondencia entre las dos variables categóricas. Este método es particularmente útil para visualizar y explorar relaciones entre categorías de variables y es ideal para datos no métricos.
Se va a utilizar el Análisis de Correspondencia para explorar y visualizar las relaciones entre variables categóricas como zona, tipo de vivienda, y barrio socioeconómico en tu base de datos de propiedades
# Se crea una tabla de contingencia con la zona y el estrato
vivienda_data_2$estrato[vivienda_data_2$estrato == 4.63360980887126] <- 4
vivienda_data_2
## # A tibble: 8,322 × 10
## zona estrato preciom areaconst banios habitaciones tipo barrio longitud
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <chr> <dbl>
## 1 Zona Ori… 3 250 70 3 6 Casa 20 de… -76.5
## 2 Zona Ori… 3 320 120 2 3 Casa 20 de… -76.5
## 3 Zona Ori… 3 350 220 2 4 Casa 20 de… -76.5
## 4 Zona Sur 4 400 280 5 3 Casa 3 de … -76.5
## 5 Zona Nor… 5 260 90 2 3 Apar… acopi -76.5
## 6 Zona Nor… 5 240 87 3 3 Apar… acopi -76.5
## 7 Zona Nor… 4 220 52 2 3 Apar… acopi -76.5
## 8 Zona Nor… 5 310 137 3 4 Apar… acopi -76.5
## 9 Zona Nor… 5 320 150 4 6 Casa acopi -76.5
## 10 Zona Nor… 5 780 380 3 3 Casa acopi -76.5
## # ℹ 8,312 more rows
## # ℹ 1 more variable: latitud <dbl>
# Suponiendo que tu dataframe se llama 'data' y 'estrato' es la columna a modificar
vivienda_data_2$estrato <- ifelse(vivienda_data_2$estrato == 4.63360980887126, 4, vivienda_data_2$estrato)
tabla <- table(vivienda_data_2$zona, vivienda_data_2$estrato)
# Realizar el Análisis de Correspondencia Múltiple (ACM)
resultados_ac <- CA(tabla)
Las zonas están dispersas a lo largo de la primera dimensión, lo que indica diferencias significativas entre las zonas en términos de las variables analizadas. La segunda dimensión también muestra variabilidad, pero es menos pronunciada.
Zona Oriente y Zona Centro están más hacia el lado derecho del gráfico, posiblemente indicando similitudes en ciertas características que son diferentes de las zonas ubicadas más hacia la izquierda como Zona Oeste y Zona Sur.
La proximidad de las zonas entre sí puede indicar similitudes en las características de las propiedades o en los comportamientos del mercado inmobiliario. Por ejemplo, Zona Norte y Zona Centro están relativamente cerca, sugiriendo que podrían tener características en común más fuertes en comparación con Zona Oeste. Zona Oeste, estando un poco alejada de las otras zonas en Dim 1 y Dim 2, podría tener características únicas o un mercado inmobiliario diferente
# Asegurarse de que las variables son factores
vivienda_data_2$tipo <- as.factor(vivienda_data_2$tipo)
vivienda_data_2$zona <- as.factor(vivienda_data_2$zona)
vivienda_data_2$barrio <- as.factor(vivienda_data_2$barrio)
valores_prop <-resultados_ac$eig ; valores_prop
## eigenvalue percentage of variance cumulative percentage of variance
## dim 1 3.221853e-01 6.993563e+01 69.93563
## dim 2 1.275383e-01 2.768429e+01 97.61992
## dim 3 1.096206e-02 2.379496e+00 99.99942
## dim 4 2.686953e-06 5.832475e-04 100.00000
fviz_screeplot(resultados_ac, addlabels = TRUE, ylim = c(0, 80))+ggtitle("")+
ylab("Porcentaje de varianza explicado") + xlab("Ejes")
Este porcentaje muestra cuánta varianza en los datos originales es explicada por cada dimensión. Las dos primeras dimensiones juntas explican aproximadamente el 97.62% de la varianza total, lo que indica que la mayoría de la información significativa se puede visualizar utilizando solamente estas dos primeras dimensiones. Las dimensiones con los mayores valores propios y porcentajes de varianza explicada serán las más informativas para interpretar las relaciones entre las categorías de tus variables. Las diferencias significativas en los valores propios también sugieren que añadir más dimensiones (más allá de la segunda) no añadiría mucha más claridad o información.
El enfoque estadístico aplicado refuerza la validez de las tendencias previamente identificadas visualmente y establece una base sólida para guiar las decisiones estratégicas en el ámbito inmobiliario. A través de la reducción de dimensionalidad mediante Análisis de Componentes Principales (ACP), se logró identificar las variables numéricas más influyentes en la variabilidad del mercado inmobiliario, capturando el 59.8% de la varianza total con los dos primeros componentes, y llegando al 76.3% cuando se considera la combinación de los tress primeros CPs. El CP1, que explica el 37.8% de la variabilidad total, está principalmente asociado con variables como el estrato, precio y área construida.
El Análisis de Correspondencia Múltiple (ACM) reveló relaciones significativas entre las variables categóricas y numéricas, destacando cómo factores como el tipo de propiedad y la zona están relacionados con características como el precio y el tamaño. Este análisis capturó el 97.7% de la información total en sus dos primeras dimensiones, demostrando su eficacia en la reducción de la dimensionalidad y en la identificación de patrones clave.
En el Análisis de Conglomerados, el uso del método k-means permitió segmentar las propiedades en grupos distintivos. Se identificaron tres conglomerados principales: el conglomerado 2, caracterizado por una preponderancia de apartamentos; el conglomerado 3, dominado por casas; y el conglomerado 1, con una distribución equilibrada entre apartamentos y casas. Además, se observó una correlación positiva entre el estrato socioeconómico, el precio de la propiedad y la cantidad de conglomerados.
La gráfica del “PCA graph of individuals” reveló agrupamientos claros de propiedades, sugiriendo la existencia de segmentos distintos en el mercado, como propiedades de lujo y propiedades urbanas, entre otros. Esta visualización subraya la importancia de la segmentación en la estrategia de mercado.
Valoración Precisa: Se recomienda utilizar las variables más influyentes identificadas por el ACP para mejorar la valoración precisa de las propiedades, considerando factores clave como el estrato y el área construida.
Segmentación de Mercado: Los resultados del análisis de conglomerados deben ser utilizados para desarrollar estrategias de segmentación de mercado dirigidas a diferentes tipos de propiedades y perfiles de compradores.
Optimización de Inversiones: La comprensión más profunda y cuantificable del mercado inmobiliario proporcionada por este análisis puede conducir a la optimización de la inversión y la maximización de los beneficios, generando así una ventaja competitiva significativa en un entorno altamente dinámico y competitivo.
Este análisis exhaustivo no solo proporciona insights valiosos sobre la estructura y dinámica del mercado inmobiliario, sino que también establece una base cuantitativa para la toma de decisiones estratégicas, impulsando el éxito y la competitividad en el sector.