Realizar un estudio que le permita a la empresa inmobiliaria entender el mercado inmobiliario con la información disponible para que tome desicicones estratégicas e informadas.
library(paqueteMODELOS)
## Loading required package: boot
## Loading required package: broom
## Loading required package: GGally
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
## Loading required package: gridExtra
## Loading required package: knitr
## Loading required package: summarytools
data("vivienda")
str(vivienda)
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:8322] 1147 1169 1350 5992 1212 ...
## $ zona : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : chr [1:8322] NA NA NA "02" ...
## $ estrato : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
## $ preciom : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
## $ longitud : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
## - attr(*, "spec")=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>
# Conocer la estructura
library(summarytools)
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>
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>
dim(vivienda)
## [1] 8322 13
## LIMPIAR DATOS
colSums((is.na(vivienda)))
## id zona piso estrato preciom areaconst
## 3 3 2638 3 2 3
## parqueaderos banios habitaciones tipo barrio longitud
## 1605 3 3 3 3 3
## latitud
## 3
columnas_requeridas <- c("id", "zona", "estrato", "preciom", "areaconst",
"banios", "habitaciones", "tipo", "barrio", "longitud", "latitud")
vivienda <- vivienda[complete.cases(vivienda[, columnas_requeridas]), ]
print(dim(vivienda))
## [1] 8319 13
sin_piso <- vivienda[is.na(vivienda$piso), ]
num_casas_sin_piso <- sum(sin_piso$tipo == "Casa", na.rm = TRUE)
print(paste("Número de casas sin datos en 'piso':", num_casas_sin_piso))
## [1] "Número de casas sin datos en 'piso': 1254"
mediana_piso_casas <- median(vivienda$piso[vivienda$tipo == "Casa"], na.rm = TRUE)
vivienda$piso[is.na(vivienda$piso) & vivienda$tipo == "Casa"] <- mediana_piso_casas
sum(is.na(vivienda$piso[vivienda$tipo == "Casa"]))
## [1] 0
mediana_piso_apartamentos <- median(vivienda$piso[vivienda$tipo == "Apartamento"], na.rm = TRUE)
vivienda$piso[is.na(vivienda$piso) & vivienda$tipo == "Apartamento"] <- mediana_piso_apartamentos
sum(is.na(vivienda$piso[vivienda$tipo == "Apartamento"]))
## [1] 0
mediana_casas <- median(vivienda$parqueaderos[vivienda$tipo == "Casa"], na.rm = TRUE)
mediana_apartamentos <- median(vivienda$parqueaderos[vivienda$tipo == "Apartamento"], na.rm = TRUE)
vivienda$parqueaderos[is.na(vivienda$parqueaderos) & vivienda$tipo == "Casa"] <- mediana_casas
vivienda$parqueaderos[is.na(vivienda$parqueaderos) & vivienda$tipo == "Apartamento"] <- mediana_apartamentos
vivienda <- vivienda[!duplicated(vivienda), ]
vivienda_numericas <- vivienda[, sapply(vivienda, is.numeric)]
variables_seleccionadas <- c("estrato", "preciom", "areaconst", "parqueaderos", "banios", "habitaciones")
vivienda_numericas <- vivienda[, variables_seleccionadas, drop = FALSE]
boxplot(vivienda_numericas,
main = "Distribución de Variables Seleccionadas en Vivienda",
col = rainbow(ncol(vivienda_numericas)),
las = 2,
cex.axis = 0.8)
vivienda_numericas <- vivienda[, sapply(vivienda, is.numeric)]
porcentaje_outliers <- function(variable) {
Q1 <- quantile(variable, 0.25, na.rm = TRUE)
Q3 <- quantile(variable, 0.75, na.rm = TRUE)
IQR <- Q3 - Q1
limite_inferior <- Q1 - 1.5 * IQR
limite_superior <- Q3 + 1.5 * IQR
num_outliers <- sum(variable < limite_inferior | variable > limite_superior, na.rm = TRUE)
porcentaje <- (num_outliers / length(na.omit(variable))) * 100
return(porcentaje)
}
outliers_porcentaje <- sapply(vivienda_numericas, porcentaje_outliers)
print(outliers_porcentaje)
## id estrato preciom areaconst parqueaderos banios
## 0.0000000 0.0000000 6.6354129 4.5918981 6.8157230 0.8654886
## habitaciones longitud latitud
## 10.6743599 1.5626878 0.0000000
## ANALISIS EXPLORATORIO DE DATOS
datos <- data.frame(
Precio = c(150000, 200000, 180000, 250000, 175000),
Metros_Cuadrados = c(80, 100, 90, 120, 85),
Habitaciones = c(3, 4, 3, 5, 3),
Baños = c(2, 3, 2, 3, 2),
Ubicacion = c('Centro', 'Norte', 'Sur', 'Este', 'Oeste')
)
summary_vivienda <- summary(datos)
print(summary_vivienda)
## Precio Metros_Cuadrados Habitaciones Baños
## Min. :150000 Min. : 80 Min. :3.0 Min. :2.0
## 1st Qu.:175000 1st Qu.: 85 1st Qu.:3.0 1st Qu.:2.0
## Median :180000 Median : 90 Median :3.0 Median :2.0
## Mean :191000 Mean : 95 Mean :3.6 Mean :2.4
## 3rd Qu.:200000 3rd Qu.:100 3rd Qu.:4.0 3rd Qu.:3.0
## Max. :250000 Max. :120 Max. :5.0 Max. :3.0
## Ubicacion
## Length:5
## Class :character
## Mode :character
##
##
##
hist(vivienda$preciom, breaks = 30, col = "skyblue", main = "Distribución de Precios por m²")
install.packages("ggcorrplot")
## Warning: package 'ggcorrplot' is in use and will not be installed
library(ggcorrplot)
cor_matrix <- cor(vivienda[, c("preciom", "areaconst", "banios", "habitaciones","estrato","parqueaderos","banios","habitaciones")], use = "complete.obs")
ggcorrplot(cor_matrix, lab = TRUE)
## MODELADO # Análisis de Componentes Principales (PCA)
install.packages("emmeans")
## Installing package into 'C:/Users/Alejandro Mejía D/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
##
## There is a binary version available but the source version is later:
## binary source needs_compilation
## emmeans 1.10.1 1.10.7 FALSE
## installing the source package 'emmeans'
install.packages("FactoMineR")
## Installing package into 'C:/Users/Alejandro Mejía D/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
## package 'FactoMineR' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'FactoMineR'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Alejandro Mejía
## D\AppData\Local\R\win-library\4.2\00LOCK\FactoMineR\libs\x64\FactoMineR.dll a
## C:\Users\Alejandro Mejía
## D\AppData\Local\R\win-library\4.2\FactoMineR\libs\x64\FactoMineR.dll:
## Permission denied
## Warning: restored 'FactoMineR'
##
## The downloaded binary packages are in
## C:\Users\Alejandro Mejía D\AppData\Local\Temp\RtmpSklwiS\downloaded_packages
install.packages("factoextra")
## Installing package into 'C:/Users/Alejandro Mejía D/AppData/Local/R/win-library/4.2'
## (as 'lib' is unspecified)
## package 'factoextra' successfully unpacked and MD5 sums checked
##
## The downloaded binary packages are in
## C:\Users\Alejandro Mejía D\AppData\Local\Temp\RtmpSklwiS\downloaded_packages
library(FactoMineR)
library(factoextra)
## Welcome! Want to learn more? See two factoextra-related books at https://goo.gl/ve3WBa
vivienda_pca <- vivienda[, c("preciom", "areaconst", "banios", "habitaciones","parqueaderos")]
res.pca <- PCA(vivienda_pca, scale.unit = TRUE, ncp = 2, graph = FALSE)
fviz_screeplot(res.pca, addlabels = TRUE, ylim = c(0, 50))
fviz_pca_ind(res.pca, col.ind = "cos2", gradient.cols = c("blue", "red"))
fviz_pca_var(res.pca, col.var = "cos2", gradient.cols = c("blue", "red"))
vivienda_pca <- vivienda[, c("preciom", "areaconst", "banios", "habitaciones","parqueaderos")]
res.pca <- PCA(vivienda_pca, scale.unit = TRUE, ncp = 2, graph = FALSE)
fviz_contrib(res.pca, choice = "var", axes = 1, top = 10)
fviz_contrib(res.pca, choice = "var", axes = 2, top = 10)
fviz_pca_var(res.pca, col.var = "cos2", gradient.cols = c("#00AFBB", "#E7B800", "#FC4E07"), repel = TRUE)
# Análisis de Conglomerados (Clustering)
library(cluster)
# Elección del numero de clusters optimo
vivienda_scaled <- scale(vivienda_pca)
fviz_nbclust(vivienda_scaled, kmeans, method = "wss") +
ggtitle("Método del Codo - Número Óptimo de Clústeres")
fviz_nbclust(vivienda_scaled, kmeans, method = "silhouette") +
ggtitle("Método de la Silueta - Número Óptimo de Clústeres")
set.seed(123)
kmeans_res <- kmeans(vivienda_scaled, centers =2 )
vivienda$cluster <- as.factor(kmeans_res$cluster)
fviz_cluster(kmeans_res, data = vivienda_scaled)
aggregate(vivienda_pca, by = list(Cluster = vivienda$cluster), mean)
## Cluster preciom areaconst banios habitaciones parqueaderos
## 1 1 789.4765 330.8564 4.750104 4.884599 2.722291
## 2 2 288.9682 111.3791 2.443316 3.083926 1.371235
silhouette_scores <- silhouette(kmeans_res$cluster, dist(vivienda_scaled))
fviz_silhouette(silhouette_scores)
## cluster size ave.sil.width
## 1 1 2409 0.13
## 2 2 5910 0.62
# Análisis de Correspondencia
install.packages("FactoMineR")
## Warning: package 'FactoMineR' is in use and will not be installed
install.packages("factoextra")
## Warning: package 'factoextra' is in use and will not be installed
library(FactoMineR)
library(factoextra)
# Tabla de contingencia Zona Vs Estrato
tabla_contingencia <- table(vivienda$zona, vivienda$estrato)
res.ca <- CA(tabla_contingencia, graph = FALSE)
fviz_ca_biplot(res.ca,
repel = TRUE,
label = "all",
col.row = "blue",
col.col = "red",
title = "Análisis de Correspondencias: Zona vs Estrato",
axes.labs = c("Dimensión 1", "Dimensión 2"))
# Tabla de contingencia Zona Vs Barrio
tabla_contingencia <- table(vivienda$zona, vivienda$barrio)
res.ca <- CA(tabla_contingencia, graph = FALSE)
fviz_ca_biplot(res.ca,
repel = TRUE,
label = "all",
col.row = "blue",
col.col = "red",
title = "Análisis de Correspondencias: Zona vs Barrio",
axes.labs = c("Dimensión 1", "Dimensión 2"))
# Tabla de contingencia estrato Vs Barrio
tabla_contingencia <- table(vivienda$estrato, vivienda$barrio)
res.ca <- CA(tabla_contingencia, graph = FALSE)
fviz_ca_biplot(res.ca,
repel = TRUE,
label = "all",
col.row = "blue",
col.col = "red",
title = "Análisis de Correspondencias: estrato vs Barrio",
axes.labs = c("Dimensión 1", "Dimensión 2"))
## Conclusiones y Recomendaciones
Con la información disponible, y luego de aplica la metodología aplicada para conocer el mercado inmobiliario en la Ciudad de Cali, obtuvimos las siguientes conslusiones: La valoración de los inmuebles esta influida por su el área construida, el numero de baños el estrato y el numero de parqueaderos, que son factores claves que inciden directamente en los precios Por otro lado, se identifican dos grupos de propiedades, viviendas de alto costo cuyo precio promedio por metro cuadrado es de $780 Mil y viviendas de rango medio-bajo con precios de 272 mil el metro cuadrado, así mismo, las zonas de la ciudad en donde se ubican las propiedades con de mas alto valor, están ubicadadas en la zona oeste de la ciudad en donde predomina el estrato 6 y en la zona oriente predomina el estrato 3 con las viviendas de menor costo