El presente informe ejecutivo muestra un análisis de información sobre el mercado inmobiliario de la ciudad de Cali. El foco de este documento apunta a cuatro topicos de interés de la compañia B&C:
El precio de las viviendas en diferentes zonas de ciudad.
El tipo de viviendas más vendidas.
Características más demandadas.
Evolución del mercado de bienes raíces en Cali.
Para contextualizar la situación del mercado inmobiliario en la actualidad es preciso tener presente que se espera que este sector continúe creciendo en el largo plazo debido al comportamiento del mercado en los últimos años. En 2021, las ventas del sector en Cali llegaron a $6700 millones y en 2022 a $6100 mil millones. Adicionalmente, la coyuntura ecónomica nos permite ser optimistas en vista que variables relevantes como la inversión extranjera directa, la confianza del consumidor y la sostenibilidad de la economía regional apalancan este optimismo, no en vano apesar del desarrollo sostenido del sector inmobiliario la demanada del sector no se reduce, por el contrario se proyecta siga creciendo.
Mediante este documento se busca facilitar la toma de desiciones de la compañia B&C acercandoles información concisa y veraz sobre el mercado inmobiliario. Esta información permitirá encontrar el nicho de mercado y desarrollar las estratregias de mercadeo óptimas que permitan ubicar los potenciales clientes gracias a un servicio personalizado y precios atractivos.
Los métodos utilizados en este estudio permiten garantizar un apropiado uso de la información disponible y un acercamiento de alta presición a la realidad del mercado. Los métodos utilizados parra generar este reporte se resumen así:
Primero se depuraron los registros sin información.
Segundo se quitaron registros duplicados.
Tercero se estandarizaron los datos de las variables.
El anterior ejercicio se conoce como preprocesamiento, como está relacionado se quitaron registros con datos faltantes en todas sus variables lo cual hace que los registros fueran irrelevantes, se quitaron los registros con datos duplicados en todas sus variables y por último, se parametrizaron los datos de las variables.
El resultado de este ejercicio permitirá trabajar desde la base ajustada con 8319 registros de los 8330 registros iniciales. Los registros con datos faltantes serán tratados más adelante y se hará un apartado especial para esta acción.
Es quizás el mayor desafío de este desarrollo y por ende, se hace un acercamiento con diferentes estrategías que garanticen que el resultado es el mejor posible con la información disponible.
Se realiza un acercamiento estadístico a tráves de herramientas como tablas descriptivas de datos y uso de gráficos descriptivos.
Gracias a este desarrollo se tendrá el entendimiento general del sector mediante herramientas visuales de facil compresión.
Primero se presenta la base de datos con la cual se va a trabajar.
file.choose()
## [1] "C:\\Users\\edwin\\OneDrive\\Documentos\\MAESTRIA CIENCIA DE DATOS\\METODOS Y SIMULACION ESTADISTICA\\vivienda_faltantes.csv"
bbdd_viviendas=read.csv("C:\\Users\\edwin\\OneDrive\\Documentos\\MAESTRIA CIENCIA DE DATOS\\METODOS Y SIMULACION ESTADISTICA\\vivienda_faltantes.csv")
#Primero visualizamos el tamaño de la bbdd, las variables, el tipo de variables
str(bbdd_viviendas)
## 'data.frame': 8330 obs. of 13 variables:
## $ id : int 8312 8311 8307 8296 8297 8298 8299 8300 8286 8287 ...
## $ zona : chr "Zona Oeste" "Zona Oeste" "Zona Oeste" "Zona Sur" ...
## $ piso : int 4 1 NA 2 NA NA 2 NA NA 2 ...
## $ estrato : int 6 6 5 3 5 5 6 5 5 5 ...
## $ preciom : int 1300 480 1200 220 330 1350 305 480 275 285 ...
## $ areaconst: num 318 300 800 150 112 390 125 280 74 120 ...
## $ parquea : int 2 1 4 1 2 8 2 4 1 2 ...
## $ banios : int 4 4 7 2 4 10 3 4 2 4 ...
## $ habitac : int 2 4 5 4 3 10 3 4 3 3 ...
## $ tipo : chr "Apartamento" "Casa" "Casa" "Casa" ...
## $ barrio : chr "arboleda" "normandía" "miraflores" "el guabal" ...
## $ longitud : num -76576 -76571 -76568 -76565 -76565 ...
## $ latitud : num 3454 3454 3455 3417 3408 ...
Inicialmente se realiza depuración de los registros que tienen datos faltantes en todas sus variables.
#Generamos los datos faltantes
faltantes <- colSums(is.na(bbdd_viviendas))
#Visualizamos los datos faltantes
faltantes
## id zona piso estrato preciom areaconst parquea banios
## 3 3 2641 3 2 3 1606 3
## habitac tipo barrio longitud latitud
## 3 3 3 3 3
#sin contar las variables piso y parquea, las variables tienen datos faltantes pero el número de registros no son representantivos en la base
bd_viviendas <- bbdd_viviendas[complete.cases(bbdd_viviendas[,1]),]
faltantes <- colSums(is.na(bd_viviendas))
#confirmamos que ya no hay datos faltantes
faltantes
## id zona piso estrato preciom areaconst parquea banios
## 0 0 2638 0 0 0 1603 0
## habitac tipo barrio longitud latitud
## 0 0 0 0 0
Posteriormente se realiza una depuración de registros cuyos datos estan duplicados en todas las variables
#depuramos duplicidad de registros
viviendas <- unique(bd_viviendas)
Ahora ejecutamos algunas acciones para ajustar los datos de las variables de cada registro en búsqueda de una base estandarizada.
#estandarizar los tipos de vivienda a solo dos clases de registros
viviendas$tipo <- str_replace(viviendas$tipo,"apto","Apartamento")
viviendas$tipo <- str_replace(viviendas$tipo,"APARTAMENTO","Apartamento")
viviendas$tipo <- str_replace(viviendas$tipo,"casa","Casa")
viviendas$tipo <- str_replace(viviendas$tipo,"CASA","casa")
viviendas$tipo <- str_replace(viviendas$tipo,"Casa","casa")
viviendas$barrio <- str_replace(viviendas$barrio,"ó","o")
viviendas$barrio <- str_replace(viviendas$barrio,"ñ","ñ")
viviendas$barrio <- str_replace(viviendas$barrio,"Ã-","i")
viviendas$barrio <- str_replace(viviendas$barrio,"é","e")
viviendas$barrio <- str_replace(viviendas$barrio,"á","a")
viviendas$barrio <- str_replace(viviendas$barrio,"é","e")
viviendas$barrio <- str_replace(viviendas$barrio,"í","i")
viviendas$barrio <- str_replace(viviendas$barrio,"ó","o")
viviendas$barrio <- str_replace(viviendas$barrio,"ú","u")
viviendas$barrio <- str_replace(viviendas$barrio,"√∫","u")
viviendas$barrio <- str_replace(viviendas$barrio,"el caney","caney")
viviendas$barrio <- str_replace(viviendas$barrio,"El Caney","caney")
viviendas$barrio <- str_replace(viviendas$barrio,"agua blanca","aguablanca")
viviendas$barrio <- str_replace(viviendas$barrio,"ñ","ñ")
viviendas$barrio <- str_replace(viviendas$barrio,"barrio ","")
viviendas$barrio <- str_replace(viviendas$barrio,"cali bella","calibella")
viviendas$barrio <- str_replace(viviendas$barrio,"ciudadela pasoancho","ciudadela paso ancho")
viviendas$barrio <- str_replace(viviendas$barrio,"pampa linda","pampa linda")
Ahora podemos ver la nueva base de datos y un resumen de los principales indicadores.
#confirmamos el estado de la nueva base
str(viviendas)
## 'data.frame': 8319 obs. of 13 variables:
## $ id : int 8312 8311 8307 8296 8297 8298 8299 8300 8286 8287 ...
## $ zona : chr "Zona Oeste" "Zona Oeste" "Zona Oeste" "Zona Sur" ...
## $ piso : int 4 1 NA 2 NA NA 2 NA NA 2 ...
## $ estrato : int 6 6 5 3 5 5 6 5 5 5 ...
## $ preciom : int 1300 480 1200 220 330 1350 305 480 275 285 ...
## $ areaconst: num 318 300 800 150 112 390 125 280 74 120 ...
## $ parquea : int 2 1 4 1 2 8 2 4 1 2 ...
## $ banios : int 4 4 7 2 4 10 3 4 2 4 ...
## $ habitac : int 2 4 5 4 3 10 3 4 3 3 ...
## $ tipo : chr "Apartamento" "casa" "casa" "casa" ...
## $ barrio : chr "arboleda" "normandia" "miraflores" "el guabal" ...
## $ longitud : num -76576 -76571 -76568 -76565 -76565 ...
## $ latitud : num 3454 3454 3455 3417 3408 ...
summary(viviendas)
## id zona piso estrato
## Min. : 1 Length:8319 Min. : 1.000 Min. :3.000
## 1st Qu.:2080 Class :character 1st Qu.: 2.000 1st Qu.:4.000
## Median :4160 Mode :character Median : 3.000 Median :5.000
## Mean :4160 Mean : 3.771 Mean :4.634
## 3rd Qu.:6240 3rd Qu.: 5.000 3rd Qu.:5.000
## Max. :8319 Max. :12.000 Max. :6.000
## NA's :2635
## preciom areaconst parquea 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 :1602
## habitac tipo barrio longitud
## Min. : 0.000 Length:8319 Length:8319 Min. :-76576.00
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76507.00
## Median : 3.000 Mode :character Mode :character Median : -76.54
## Mean : 3.605 Mean :-21866.06
## 3rd Qu.: 4.000 3rd Qu.: -76.52
## Max. :10.000 Max. : -76.46
##
## latitud
## Min. : 3.333
## 1st Qu.: 3.390
## Median : 3.449
## Mean : 971.300
## 3rd Qu.:3367.000
## Max. :3497.000
##
Desde aquí iniciaremos un tratamiento especial para las variables “piso” y ” parquea” que contienen 2635 y 1602 datos perdidos respectivamente. Se realizará un modelado para mantener la información de estos registros de las otras variables y mitigar la posibilidad de sesgos en la muestra si retiraramos estos registros de la base. Podemos observar con mayor claridad la situación descrita a través de la siguientes ilustraciones.
grafico <- md.pattern(viviendas, rotate.names = TRUE)
Este último gráfico nos brinda una visión más detallada de los datos perdidos en las variables respecto al total de la muestra. Se observa que 726 registros tienen datos faltantes para ambas variables en cuestión, 876 registros tienen datos faltantes en la variable parquea, 1909 registros tienen datos faltantes para la variable piso y 4808 registros no presentan datos faltantes.
Haremos un análisis descriptivo previo a la imputación de datos para medir el efecto de la imputación realizada.
Analicemos la distribución de los datos dentro de la variable parquea.
hist(viviendas$parquea)
Es claro que la mayoría de los datos están concentrados a la izquierda de la distribucíon y que los datos son menores o iguales a 3. Esta información ratifica lo mostrado a través del resumen inicial donde observamos que la media se acerca a 2 y la mediana es dos incluso el tercer cuartil muestra que los datos son iguales o menores a dos. De acuerdo a esta evidencia es coherente reemplazar los datos faltantes con la mediana.
mediana_parquea <- median(viviendas$parquea, na.rm = TRUE)
viviendas$parquea[is.na(viviendas$parquea)] <- mediana_parquea
De manera similar observaremos la distribución de los datos de la variables piso.
hist(viviendas$piso)
observamos que el comportamiento de la distribución es similar a la variable parquea.
media_piso <- mean(viviendas$piso, na.rm = TRUE)
viviendas$piso[is.na(viviendas$piso)] <- media_piso
A continuación se puede confirmar que a través del reemplazo de los datos faltantes en la variable parquea con la mediana y el reemplazo de los datos faltantes en la variable piso con la media, hemos completado el proceso de estandarización de la base de datos.
gg_miss_var(viviendas)
Precio de las Viviendas Según la Zona de Ubicación
table(viviendas$zona, viviendas$tipo)
##
## Apartamento casa
## Zona Centro 24 100
## Zona Norte 1198 722
## Zona Oeste 1029 169
## Zona Oriente 62 289
## Zona Sur 2786 1940
zona_vivi <- table(viviendas$tipo, viviendas$zona )
barplot(zona_vivi, main="Tipos de Vivivenda por Zonas",
xlab="Zona",
col=c("#008B8B","#6E8B3D", "#8B3E2F", "#68228B", "#CDAD00"),
legend = rownames(zona_vivi ),
las=1, ylim = c(0,5000),
names.arg=c("Norte","Oriente","Centro","Occidente","Sur"))
Podemos apreciar que la gran mayoría de los inmuebles se encuentran ubicados en la zona sur así mismo se puede notar que la mayoría de los inmuebles son de tipo Apartamento.
table(viviendas$tipo)
##
## Apartamento casa
## 5099 3220
Precio_v_zonas = aggregate(by = list(viviendas$zona,viviendas$tipo), viviendas$preciom, FUN=mean)
colnames(Precio_v_zonas)=c("Zona", "Tipo de vivienda", "Precio promedio de vivienda")
Precio_v_zonas <- Precio_v_zonas[with(Precio_v_zonas, order(-Precio_v_zonas$`Precio promedio de vivienda`)), ]
Precio_v_zonas
## Zona Tipo de vivienda Precio promedio de vivienda
## 8 Zona Oeste casa 736.3550
## 3 Zona Oeste Apartamento 667.9271
## 10 Zona Sur casa 612.0077
## 7 Zona Norte casa 445.9058
## 6 Zona Centro casa 339.2400
## 5 Zona Sur Apartamento 297.3550
## 2 Zona Norte Apartamento 285.1619
## 9 Zona Oriente casa 244.8201
## 1 Zona Centro Apartamento 186.5833
## 4 Zona Oriente Apartamento 152.5968
Así mismo, podemos observar el precio promedio por tipos de inmuebles según las zonas de la ciudad.
caract <- table(viviendas$tipo, viviendas$piso)
barplot(caract, main="Piso por Tipo de Vivivenda",
xlab="Pisos",
col=c("#B0E2FF","#CAE1FF"),
legend = rownames(caract),
las=1, ylim = c(0,5000))
Realizaremos un análisis para validar datos atípicos en las variables
boxplot(viviendas$parquea, vertical=TRUE, xlab="Parqueaderos")
par(mfrow=c(1,2))
boxplot(viviendas$piso, vertical=TRUE, xlab="Piso")
boxplot(viviendas$estrato, vertical=TRUE, xlab="Estrato")
boxplot(viviendas$preciom, vertical=TRUE, xlab="Precio")
boxplot(viviendas$areaconst, vertical=TRUE, xlab="Area Construida")
boxplot(viviendas$habitac, vertical=TRUE, xlab="Habitaciones")
boxplot(viviendas$banios, vertical=TRUE, xlab="Baños")
Las variables parquea y piso so pena de tener una gran catidad de datos faltantes contenian información relevante y apesar de usar un método de imputación muy básico se logra obtener información significativa y con reducción de sesgos
El 56.7% de las viviendas está en la zona sur esto confirmar que es una zona m{as densamente poblada con un gran incentivo por estar ubicado en esta zona de la ciudad.
En promedio el 60.3 % de viviendas son Apartamentos y el 39.7 % son Casa.
El tipo de viviendas mas vendidas estan entre los pisos 3 y 4.
En la Zona Oeste se encuentran las Casas y Apartamentos con mayor costo promedio. 765 millones y 698 millones respectivamente.
En las Zonas Centro y Oriente se encuentran los inmuebles más económicos
En el diagrama de cajas para la variable estrato, variable baños y variable piso la mediana de estas se encuentra en dentro de la caja, pero en la parte superior por lo que tiene una leve tendencia a que existan valores atípicos.
En el diagrama de cajas para la variable preciom, variable parquea variable areaconst la mediana se encuentra en la mitad de la caja por lo que se concluye que la información es simétrica, a pesar de esto existen valores atípicos.
En el diagrama de cajas para la variable habitac la mediana esta por debajo del valor de la casa por lo que existe gran cantidad de datos sesgados, de igual manera para los datos atípicos se encuentra por encima y por debajo de la caja.