# cargar librerías
library(readxl)
library(dplyr)
library(ggplot2)
library(plotly)
library(knitr)
library(kableExtra)
library(tidyr)
library(RecordLinkage)
library(leaflet)
library(htmltools)
library(pander)
library(readxl)
datos <- read_excel("Datos_Vivienda.xlsx")
#Crear un ID para cada vivienda
id=1:dim(datos)[1]
datos=data.frame(id,datos)
#filtro
require(RecordLinkage)
pos = which(jarowinkler("salomia", datos$Barrio)>0.98)
datos_salomia=datos[pos,]
head(datos_salomia)
| id | Zona | piso | Estrato | precio_millon | Area_contruida | parqueaderos | Banos | Habitaciones | Tipo | Barrio | cordenada_longitud | Cordenada_latitud | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 164 | 164 | Zona Norte | 3 | 3 | 155 | 62 | 1 | 2 | 3 | Apartamento | salomia | -76.48707 | 3.46684 |
| 165 | 165 | Zona Norte | 3 | 3 | 155 | 62 | 1 | 2 | 3 | Apartamento | salomia | -76.48707 | 3.46684 |
| 457 | 457 | Zona Norte | NA | 3 | 300 | 195 | 2 | 4 | 4 | Casa | salomia | -76.49622 | 3.46290 |
| 527 | 527 | Zona Norte | NA | 3 | 118 | 62 | NA | 1 | 3 | Apartamento | salomia | -76.49800 | 3.46700 |
| 537 | 537 | Zona Norte | 4 | 3 | 118 | 62 | NA | 1 | 3 | Apartamento | salomia | -76.49827 | 3.46595 |
| 544 | 544 | Zona Norte | NA | 3 | 115 | 64 | NA | 1 | 3 | Apartamento | salomia | -76.49858 | 3.46462 |
#Nombres variables
names(datos_salomia)
## [1] "id" "Zona" "piso"
## [4] "Estrato" "precio_millon" "Area_contruida"
## [7] "parqueaderos" "Banos" "Habitaciones"
## [10] "Tipo" "Barrio" "cordenada_longitud"
## [13] "Cordenada_latitud"
En este análisis exploraremos las características de las viviendas ubicadas en el barrio Salomia, en Cali-Valle, con el objetivo de comprender la distribución y variabilidad de variables clave como el precio, el área construida, el número de habitaciones y el número de baños.
# Calcular estadísticas descriptivas básicas
precio <- datos_salomia$precio_millon
area <- datos_salomia$Area_contruida
habitaciones <- datos_salomia$Habitaciones
baños <- datos_salomia$Banos
descriptive_stats <- data.frame(
variable = c("Precio", "Área", "# Habitaciones", "# Baños"),
Max = c(max(precio), max(area), max(habitaciones), max(baños)),
Min = c(min(precio), min(area), min(habitaciones), min(baños)),
Media = c(mean(precio), mean(area), mean(habitaciones), mean(baños)),
Mediana = c(median(precio), median(area), median(habitaciones), median(baños)),
Desvest = c(sd(precio), sd(area), sd(habitaciones), sd(baños)),
CoefVar = c(sd(precio) / mean(precio), sd(area) / mean(area), sd(habitaciones) / mean(habitaciones), sd(baños) / mean(baños))
)
pander(descriptive_stats)
| variable | Max | Min | Media | Mediana | Desvest | CoefVar |
|---|---|---|---|---|---|---|
| Precio | 1100 | 92 | 242.6 | 152 | 189.6 | 0.7819 |
| Área | 510 | 47 | 139.7 | 65 | 129.1 | 0.9237 |
| # Habitaciones | 10 | 2 | 3.775 | 3 | 2.057 | 0.5448 |
| # Baños | 8 | 1 | 2.525 | 2 | 1.71 | 0.677 |
El análisis descriptivo revela que las variables de Precio y Área presentan una alta dispersión y una distribución sesgada a la derecha, como lo indica la diferencia considerable entre la media y la mediana, así como los altos coeficientes de variación (0.78 y 0.92, respectivamente), lo que sugiere la presencia de valores atípicos o propiedades significativamente más costosas y grandes que el promedio. Por otro lado, las variables # Habitaciones y # Baños son más homogéneas, con distribuciones más simétricas y menor variabilidad relativa. Estos resultados sugieren la necesidad de considerar transformaciones como el logaritmo del área o el precio, o incluso la exclusión de outliers, para mejorar la precisión y validez del modelo de regresión.
# Crear gráfico interactivo con correlación
ggplotly(
ggplot(datos_salomia, aes(x = Area_contruida, y = precio_millon)) +
geom_point(color = "blue", alpha = 0.8, size = 2) + # Puntos con color y transparencia
geom_smooth(method = "loess", color = "grey", se = TRUE) + # Línea de tendencia
labs(
title = paste("Figura 1. Relación entre Área Construida y Precio\nCoef. de correlación:",
round(cor(datos_salomia$precio_millon, datos_salomia$Area_contruida, use = "complete.obs"), 2)),
x = "Área Construida (m²)",
y = "Precio (Millones)",
caption = "Fuente: Datos de Vivienda"
) +
theme_minimal() +
theme(
plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.title = element_text(size = 12),
axis.text = element_text(size=10)
)
)
El precio de viviendas en Salomia tiene una alta correlación (0.91) con el área construida. Esta correlación es notablemente más alta en este barrio comparado con la correlación de todo el conjunto de datos que es 0.68.
g1.1=ggplot(data = datos_salomia,mapping = aes(x=precio_millon))+geom_histogram(fill="red")+theme_bw()
ggplotly(g1.1)
Con el histograma vemos que la mayoría de viviendas en este barrio se concentra en un rango de precios de 100 a 300 millones. Siendo el dato que más se repite 140 millones.
require(leaflet)
#мара 2
#Etiqueta enriquecida (Tabel) muestra información detallada del punto, incluyendo:
#ID del inmueble.
#precio en millones.
#Área construida.
#Barrio.
#Latitud y longitud.
#Añade un fondo de mapa base → addtiles()
leaflet() %>% addCircleMarkers(lng = datos_salomia$cordenada_longitud, lat = datos_salomia$Cordenada_latitud, radius
= 1, color = "green", label = paste0( 'ID',datos_salomia$ID, 'Precio:', datos_salomia$precio_millon,'Area:',
datos_salomia$Area_contruida, 'Barrio:', datos_salomia$Barrio,' Lat: ' ,datos_salomia$Cordenada_latitud, 'Long:',datos_salomia$cordenada_longitud)) %>%addTiles()
##exploración bivariada
g3= ggplot(data = datos_salomia,mapping = aes(x=Habitaciones,y=precio_millon))+geom_point()+theme_bw()+geom_smooth()
ggplotly(g3)
##correlación
cor(datos_salomia$precio_millon, datos_salomia$Habitaciones)
## [1] 0.6490976
##exploración bivariada
g4= ggplot(data = datos_salomia,mapping = aes(x=Banos,y=precio_millon))+geom_point()+theme_bw()+geom_smooth()
ggplotly(g4)
##correlación
cor(datos_salomia$precio_millon, datos_salomia$Banos)
## [1] 0.8828418
Con las gráficas anteriores y los coeficientes de variación, vemos que pareciera que los baños impactan más fuerte al precio que las habitaciones, esto lo confirmaremos con los siguientes modelos simples:
mod_simple1 = lm(precio_millon~Area_contruida,data=datos_salomia)
summary (mod_simple1)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida, data = datos_salomia)
##
## Residuals:
## Min 1Q Median 3Q Max
## -174.90 -25.92 3.52 16.34 373.69
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 54.93903 18.31366 3.00 0.00475 **
## Area_contruida 1.34274 0.09684 13.87 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 78.05 on 38 degrees of freedom
## Multiple R-squared: 0.835, Adjusted R-squared: 0.8306
## F-statistic: 192.2 on 1 and 38 DF, p-value: < 2.2e-16
mod_simple2 = lm(precio_millon~Habitaciones,data=datos_salomia)
summary (mod_simple2)
##
## Call:
## lm(formula = precio_millon ~ Habitaciones, data = datos_salomia)
##
## Residuals:
## Min 1Q Median 3Q Max
## -135.57 -76.67 -20.64 14.22 784.13
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 16.61 48.78 0.341 0.735
## Habitaciones 59.85 11.38 5.260 5.88e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 146.1 on 38 degrees of freedom
## Multiple R-squared: 0.4213, Adjusted R-squared: 0.4061
## F-statistic: 27.67 on 1 and 38 DF, p-value: 5.878e-06
mod_simple3 = lm(precio_millon~Banos,data=datos_salomia)
summary (mod_simple3)
##
## Call:
## lm(formula = precio_millon ~ Banos, data = datos_salomia)
##
## Residuals:
## Min 1Q Median 3Q Max
## -167.01 -53.13 -12.04 25.31 321.24
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -4.743 25.672 -0.185 0.854
## Banos 97.938 8.452 11.587 4.88e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 90.23 on 38 degrees of freedom
## Multiple R-squared: 0.7794, Adjusted R-squared: 0.7736
## F-statistic: 134.3 on 1 and 38 DF, p-value: 4.88e-14
Como mencionamos anteriormente el modelo con la variable baños funciona bastante mejor que el modelo con la variable habitaciones.
El modelo simple que mejor funciona es el primero que usa las variables Área construida y Precio en millones, ya que el 83.5% de la variabilidad del precio se explica por el área construida.
El modelo indica que por cada metro cuadrado adicional de área construida, el precio estimado en viviendas del barrio Salomia aumenta en 1.34 millones de pesos.
par(mfrow=c(2,2))
plot(mod_simple1)
Aunque el modelo funciona bien tiene leves problemas de
heterocedasticidad en los residuos, también se identifican varios
outliers que afectan al modelo. Se propone entonces el siguiente
modelo:
mod_multiple = lm(precio_millon~Area_contruida+Banos+Habitaciones,data=datos_salomia)
summary (mod_multiple)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida + Banos + Habitaciones,
## data = datos_salomia)
##
## Residuals:
## Min 1Q Median 3Q Max
## -175.720 -27.658 -3.304 13.267 226.798
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 73.047 25.239 2.894 0.00642 **
## Area_contruida 1.220 0.202 6.038 6.18e-07 ***
## Banos 41.126 13.236 3.107 0.00368 **
## Habitaciones -27.757 8.769 -3.165 0.00315 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 65.34 on 36 degrees of freedom
## Multiple R-squared: 0.8904, Adjusted R-squared: 0.8813
## F-statistic: 97.53 on 3 and 36 DF, p-value: < 2.2e-16
mod_step= step(mod_multiple)
## Start: AIC=338.15
## precio_millon ~ Area_contruida + Banos + Habitaciones
##
## Df Sum of Sq RSS AIC
## <none> 153673 338.15
## - Banos 1 41213 194886 345.65
## - Habitaciones 1 42771 196444 345.97
## - Area_contruida 1 155628 309301 364.13
Según lo anterior el modelo que mejor funciona (con menor AIC) es el que tiene las 3 variables: Area construida, baños y habitaciones
par(mfrow=c(2,2))
plot(mod_multiple)
Sin embargo vemos que el modelo múltiple tiene una situación similar al simple y necesita un ajuste ya que los residuos no son completamente homocedásticos y existen datos atípicos que impactan fuertemente al modelo.
mod_interaccion = lm(precio_millon~Tipo:Area_contruida,data=datos_salomia)
summary (mod_interaccion)
##
## Call:
## lm(formula = precio_millon ~ Tipo:Area_contruida, data = datos_salomia)
##
## Residuals:
## Min 1Q Median 3Q Max
## -174.57 -23.56 4.38 19.18 380.46
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 69.6499 32.5215 2.142 0.0389 *
## TipoApartamento:Area_contruida 1.0056 0.6210 1.619 0.1139
## TipoCasa:Area_contruida 1.2998 0.1251 10.386 1.62e-12 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 78.78 on 37 degrees of freedom
## Multiple R-squared: 0.8363, Adjusted R-squared: 0.8274
## F-statistic: 94.51 on 2 and 37 DF, p-value: 2.885e-15
par(mfrow=c(2,2))
plot(mod_interaccion)
En este modelo el R cuadrado es bastante alto (83%), pero sólo el tipo
casa es significativo. El modelo nos dice que en el barrio Salomia, en
el tipo de vivienda casa se espera que por cada aumento en el
metro cuadrado el precio de la casa aumente 1.3 millones
mod_log=lm(precio_millon~log(Area_contruida)+Banos+Habitaciones,data = datos_salomia)
summary (mod_log)
##
## Call:
## lm(formula = precio_millon ~ log(Area_contruida) + Banos + Habitaciones,
## data = datos_salomia)
##
## Residuals:
## Min 1Q Median 3Q Max
## -152.417 -21.847 3.035 27.577 272.167
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -560.331 109.567 -5.114 1.06e-05 ***
## log(Area_contruida) 158.531 30.440 5.208 7.95e-06 ***
## Banos 67.218 11.527 5.832 1.17e-06 ***
## Habitaciones -26.958 9.514 -2.833 0.0075 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 70 on 36 degrees of freedom
## Multiple R-squared: 0.8742, Adjusted R-squared: 0.8638
## F-statistic: 83.42 on 3 and 36 DF, p-value: 2.841e-16
par(mfrow=c(2,2))
plot(mod_log)
Este modelo es el que mejor cumple los supuestos, por lo tanto será el usado para el pronóstico.
Fórmula: precio_millon= 158.5 log(Area_contruida) + 67.2 Banos + -26.958 Habitaciones
Se espera que un aumento del 1% en el área construida haya un aumento de aproximadamente 1.59 millones en el precio, manteniendo constantes las demás variables. Cada baño adicional se asocia con un aumento de aproximadamente 67.2 millones en el precio, manteniendo constantes las demás variables. Cada habitación adicional, sorprendentemente, se asocia con una disminución de aproximadamente 27 millones en el precio,
El modelo explica aproximadamente el 87.4% de la variabilidad en el precio de las propiedades. En promedio, los errores de predicción del modelo son de ±70 millones.
Según el modelo, es mejor invertir en baños que en habitaciones en viviendas del barrio Salomia, y si es posible
¿Que pasa al predecir con este modelo transformado, por ejemplo cual seria el precio estimado de una vivienda con un área de 150, 2 baños y 3 habitacones?
mod_predict=predict(mod_log,list(Area_contruida=150,Banos=2,Habitaciones=3))
mod_predict
## 1
## 287.5737
Una vivienda con las características especificadas tendría un precio promedio estimado de aproximadamente 287 millones de pesos.
Este modelo es especialmente útil para agencias inmobiliarias, agentes de bienes raíces, inversionistas y desarrolladores, ya que permite estimar el valor de mercado de una propiedad en el barrio Salomia con base en variables clave como el área construida, el número de baños y habitaciones. Además, sirve como herramienta para evaluar el potencial de valorización según características estructurales específicas, facilitando decisiones de compra, venta o remodelación.
También resulta valioso para propietarios, quienes pueden usar esta información para planificar mejoras en su vivienda. Por ejemplo, si aumentan el área construida en un 10%, el modelo predice un incremento promedio de 10.6 millones de pesos en el precio, lo que les permite evaluar si la inversión en ampliación es rentable.