knitr::opts_chunk$set(echo = TRUE, results = "show", message = FALSE, warning = FALSE)
library (readxl)
library(dplyr)
library(ggplot2)
library(plotly)
library(knitr) #Facilita la creación de informes con R Markdown, combinando texto, código y resultados.
library(kableExtra) #Para crear tablas con formato más avanzado y estilizado
library(tidyr) #Ayuda a transformar y reorganizar los datos
library(RecordLinkage) #Realiza tareas de emparejamiento de registros,
library(leaflet) #Permite crear mapas interactivos con datos geoespaciale
library(htmltools) #Ayuda a generar y manipular contenido HTML
library(readxl)
datos <- read_excel("/Users/sofiaartunduaga/Desktop/Econometría/datos.xlsx")
id=1:dim(datos)[1]
datos=data.frame(id,datos)
pos = which(jarowinkler("normandia",datos$Barrio)>0.98&datos$Tipo=="Apartamento")
datos_sub=datos[pos,]
head(datos_sub)
## id Zona piso Estrato precio_millon Area_contruida parqueaderos
## 685 685 Zona Oeste NA 6 1050 171 3
## 2790 2790 Zona Oeste 10 6 1200 315 3
## 2791 2791 Zona Oeste NA 6 1500 530 4
## 2838 2838 Zona Oeste NA 6 950 203 NA
## 3158 3158 Zona Oeste NA 6 1350 236 3
## 3378 3378 Zona Oeste NA 6 270 62 1
## Banos Habitaciones Tipo Barrio cordenada_longitud
## 685 3 3 Apartamento normandia -76.50100
## 2790 4 3 Apartamento normandia -76.52200
## 2791 7 4 Apartamento normandia -76.52200
## 2838 3 3 Apartamento normandia -76.52222
## 3158 5 3 Apartamento normandia -76.52400
## 3378 2 2 Apartamento normandia -76.52600
## Cordenada_latitud
## 685 3.40100
## 2790 3.48300
## 2791 3.42100
## 2838 3.42056
## 3158 3.45700
## 3378 3.43400
library(dplyr)
names(datos_sub)
## [1] "id" "Zona" "piso"
## [4] "Estrato" "precio_millon" "Area_contruida"
## [7] "parqueaderos" "Banos" "Habitaciones"
## [10] "Tipo" "Barrio" "cordenada_longitud"
## [13] "Cordenada_latitud"
length(pos)
## [1] 155
library(pander)
precio <- datos_sub$precio_millon
area <- datos_sub$Area_contruida
habitaciones <- datos_sub$Habitaciones
baños <- datos_sub$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 | 1850 | 260 | 781.8 | 621 | 418.9 | 0.5359 |
Área | 530 | 62 | 182.3 | 166 | 91.51 | 0.502 |
# Habitaciones | 4 | 2 | 3.084 | 3 | 0.5578 | 0.1809 |
# Baños | 7 | 0 | 3.516 | 3 | 1.181 | 0.3358 |
Interpretación
El análisis exploratorio inicial de los datos de apartamentos en Normandía revela una dispersión considerable en el precio, con una media de 1121 y una mediana de 1100, sugiriendo una distribución aproximadamente simétrica aunque con colas. La variabilidad es más pronunciada en el área, donde la media (398.4) excede la mediana (347), lo que apunta a una distribución asimétrica positiva, influenciada por la presencia de valores atípicos de mayor tamaño. En contraste, las variables de número de habitaciones y baños presentan una menor dispersión y distribuciones más centradas. La identificación de valores mínimos de cero en habitaciones y baños plantea interrogantes sobre la integridad o la naturaleza de dichas observaciones, requiriendo una investigación más detallada. En suma, la heterogeneidad observada en el tamaño y precio de los apartamentos subraya la importancia de considerar esta variabilidad en modelos predictivos posteriores, así como la necesidad de una depuración de datos para abordar las posibles anomalías identificadas.
# Boxplot de área construida
boxplot(precio_millon ~ Tipo, data = datos_sub,
main = "Precio por Tipo de Vivienda",
xlab = "Tipo", ylab = "Precio (millones)", col = "purple")
Interpretación
El precio típico (mediana) para este tipo de vivienda es de unos 600 millones, con el 50% central entre 500 y 1050 millones. Hay una dispersión notable de precios, desde 250 hasta 1700 millones
library(ggplot2)
library(plotly)
# Crear gráfico interactivo con correlación
ggplotly(
ggplot(datos_sub, aes(x = Area_contruida, y = precio_millon)) +
geom_point(color = "red", 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 5. Relación entre Área Construida y Precio\nCoef. de correlación:",
round(cor(datos_sub$precio_millon, datos_sub$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)
)
)
Interpretación
El gráfico revela una relación positiva moderada (correlación de 0.52) entre el área construida y el precio de las viviendas en Cali, donde generalmente a mayor área corresponde un mayor precio. Sin embargo, la dispersión de los puntos sugiere que otros factores también influyen significativamente en el precio, y la línea de tendencia curva indica una posible relación no lineal, donde el aumento de precio por metro cuadrado adicional podría variar según el tamaño de la vivienda.
require(leaflet)
#мара
#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_sub$cordenada_longitud, lat = datos_sub$Cordenada_latitud, radius
= 1, color = "red", label = paste0( 'ID',datos_sub$ID, 'Precio:', datos_sub$precio_millon,'Area:',
datos_sub$Area_contruida, 'Barrio:', datos_sub$Barrio,' Lat: ' ,datos_sub$Cordenada_latitud, 'Long:',datos_sub$cordenada_longitud)) %>% addTiles()
Gráfico de dispersión entre precio viviendas y baños
Sub1= ggplot(data = datos_sub,mapping = aes(x=Banos,y=precio_millon))+geom_point()+theme_bw()+geom_smooth()
ggplotly(Sub1)
cor(datos_sub$precio_millon, datos_sub$Banos)
## [1] 0.7534205
Interpretación
La gráfica muestra la relación entre el número de baños y el precio en millones, con una correlación positiva moderada de 0.3750677. Esto sugiere que, en general, a mayor número de baños, mayor es el precio de la propiedad, aunque esta relación no es extremadamente fuerte. Se observa una tendencia interesante donde los precios inicialmente descienden hasta aproximadamente 2 baños, para luego aumentar constantemente. La mayor concentración de datos se encuentra entre 4-6 baños, donde también existe mayor variabilidad en los precios. Esta dispersión considerable de los datos explica por qué la correlación es moderada y no alta, indicando que el número de baños influye en el precio, pero no es el único factor determinante
mod1_simple = lm(precio_millon~Area_contruida,data=datos_sub)
summary (mod1_simple)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -652.82 -101.43 -59.13 64.60 801.28
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 62.914 38.330 1.641 0.103
## Area_contruida 3.943 0.188 20.972 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 213.5 on 153 degrees of freedom
## Multiple R-squared: 0.7419, Adjusted R-squared: 0.7402
## F-statistic: 439.8 on 1 and 153 DF, p-value: < 2.2e-16
mod2_simple = lm(precio_millon~Banos,data=datos_sub)
summary (mod2_simple)
##
## Call:
## lm(formula = precio_millon ~ Banos, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -653.45 -173.64 -36.51 172.52 798.11
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -158.11 69.93 -2.261 0.0252 *
## Banos 267.31 18.86 14.173 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 276.4 on 153 degrees of freedom
## Multiple R-squared: 0.5676, Adjusted R-squared: 0.5648
## F-statistic: 200.9 on 1 and 153 DF, p-value: < 2.2e-16
mod3_simple = lm(precio_millon~Habitaciones,data=datos_sub)
summary (mod3_simple)
##
## Call:
## lm(formula = precio_millon ~ Habitaciones, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -687.5 -234.3 -130.8 293.2 993.2
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -136.34 174.69 -0.78 0.436
## Habitaciones 297.72 55.75 5.34 3.3e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 385.9 on 153 degrees of freedom
## Multiple R-squared: 0.1571, Adjusted R-squared: 0.1516
## F-statistic: 28.52 on 1 and 153 DF, p-value: 3.296e-07
Interpretación
V1: El área construida es el factor más importante, con un R² de 0.27, lo que significa que explica el 27% de las variaciones en el precio. Por cada unidad extra de área, el precio sube 0.91 millones. Esta relación es muy significativa estadísticamente (p<0.001).
V2: Los baños tienen una influencia moderada, con un R² de 0.14 (explica el 14% de la variación). Cada baño adicional aumenta el precio en 131.16 millones, también con alta significancia (p<0.001).
V3: Las habitaciones tienen el menor impacto, con un R² muy bajo de 0.02 (solo explica el 2% de la variación). Cada habitación extra aumenta el precio en 63.34 millones, con significancia estadística apenas aceptable (p=0.0348).
Entonces , si queremos predecir el precio de una propiedad, debemos fijarnos principalmente en el área construida, luego en el número de baños, y las habitaciones tienen menor relevancia.
par(mfrow=c(2,2))
plot(mod2_simple)
Interpretación
Se observa cierta heterogeneidad en los residuos y una ligera curvatura en la línea roja, sugiriendo una relación no perfectamente lineal. El gráfico Q-Q confirma que los residuos son aproximadamente normales, con pequeñas desviaciones en los extremos. Existe una leve heteroscedasticidad visible en el gráfico Scale-Location.
mod_multiple = lm(precio_millon~Area_contruida+Habitaciones+Banos,data=datos_sub)
summary (mod_multiple)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida + Habitaciones +
## Banos, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -675.52 -130.68 -34.03 65.48 743.67
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -15.760 90.744 -0.174 0.862
## Area_contruida 3.070 0.257 11.943 < 2e-16 ***
## Habitaciones -42.383 34.441 -1.231 0.220
## Banos 104.839 21.394 4.900 2.44e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 199.4 on 151 degrees of freedom
## Multiple R-squared: 0.7778, Adjusted R-squared: 0.7734
## F-statistic: 176.2 on 3 and 151 DF, p-value: < 2.2e-16
mod_step= step(mod_multiple)
## Start: AIC=1645.53
## precio_millon ~ Area_contruida + Habitaciones + Banos
##
## Df Sum of Sq RSS AIC
## - Habitaciones 1 60225 6065312 1645.1
## <none> 6005087 1645.5
## - Banos 1 954997 6960084 1666.4
## - Area_contruida 1 5672772 11677859 1746.6
##
## Step: AIC=1645.07
## precio_millon ~ Area_contruida + Banos
##
## Df Sum of Sq RSS AIC
## <none> 6065312 1645.1
## - Banos 1 910388 6975699 1664.8
## - Area_contruida 1 5620457 11685769 1744.7
Interpretación:
La regresión múltiple muestra que el área construida y el número de baños son predictores significativos del precio (p<0.001), mientras que el número de habitaciones no es estadísticamente significativo (p=0.226). Por cada unidad de área construida, el precio aumenta en promedio 0.77 millones, y cada baño adicional aumenta el precio en 98.37 millones. Curiosamente, el coeficiente para habitaciones es negativo (-36.86), sugiriendo que, manteniendo constantes las otras variables, más habitaciones podrían asociarse con precios ligeramente menores. El modelo explica aproximadamente el 32% de la variabilidad en los precios (R² ajustado=0.3144), una mejora respecto a los modelos simples anteriores.
La selección de variables mediante AIC confirma estos hallazgos, eliminando “Habitaciones” del modelo por no mejorar significativamente la predicción. El modelo final recomendado incluye solo área construida y baños, con un AIC de 2329.8, ligeramente mejor que el modelo completo (AIC=2330.2).
par(mfrow=c(2,2))
plot(mod_multiple)
Interpretación:
Se observa que el modelo presenta limitaciones similares al modelo simple. En el gráfico “Residuos vs Fitted”, la línea roja muestra cierta pendiente decreciente, indicando que los residuos no son completamente aleatorios. El gráfico Q-Q muestra que los residuos siguen aproximadamente una distribución normal, aunque con ligeras desviaciones en los extremos.
El gráfico Scale-Location revela heteroscedasticidad, ya que la dispersión de los residuos estandarizados no es constante a lo largo de los valores ajustados y el gráfico “Residuos vs Leverage” identifica algunos datos atípicos con alta influencia
Entonces, a pesar de incluir múltiples predictores, el modelo sigue requiriendo ajustes para corregir la heteroscedasticidad y considerar el tratamiento de los valores atípicos influyentes
mod_int = lm(precio_millon ~ Area_contruida + Banos, data = datos_sub)
summary (mod_int)
##
## Call:
## lm(formula = precio_millon ~ Area_contruida + Banos, data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -673.19 -141.40 -32.27 68.45 720.71
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -108.4280 50.7211 -2.138 0.0341 *
## Area_contruida 3.0489 0.2569 11.868 < 2e-16 ***
## Banos 95.0994 19.9099 4.776 4.16e-06 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 199.8 on 152 degrees of freedom
## Multiple R-squared: 0.7756, Adjusted R-squared: 0.7726
## F-statistic: 262.7 on 2 and 152 DF, p-value: < 2.2e-16
par(mfrow=c(2,2))
plot(mod_int)
Interpretación
El modelo explica aproximadamente el 32% de la variación en el precio de los apartamentos en Normandía basándose en estas dos variables. Esto significa que hay otros factores no incluidos en el modelo que también influyen en el precio. Los gráficos de diagnóstico sugieren que, si bien hay una relación lineal aproximada, existen algunas observaciones que podrían influir en el modelo y cierta desviación de la normalidad en los errores
mod_log=lm(precio_millon~log(Area_contruida)+Banos+Habitaciones,data = datos_sub)
summary (mod_log)
##
## Call:
## lm(formula = precio_millon ~ log(Area_contruida) + Banos + Habitaciones,
## data = datos_sub)
##
## Residuals:
## Min 1Q Median 3Q Max
## -403.0 -132.1 -13.7 102.2 734.8
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -2513.66 204.70 -12.279 < 2e-16 ***
## log(Area_contruida) 635.41 49.30 12.889 < 2e-16 ***
## Banos 92.16 20.91 4.408 1.97e-05 ***
## Habitaciones -85.09 33.51 -2.539 0.0121 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 191.9 on 151 degrees of freedom
## Multiple R-squared: 0.7943, Adjusted R-squared: 0.7902
## F-statistic: 194.3 on 3 and 151 DF, p-value: < 2.2e-16
par(mfrow=c(2,2))
plot(mod_log)
Interpretación
La transformación logarítmica del área construida mejoró el modelo de predicción del precio de apartamentos en Normandía, elevando el R2 a 0.44 y reduciendo el error de predicción. El área (ahora en logaritmo) y el número de baños son predictores significativos del precio, indicando que a mayor área y más baños, mayor es el precio esperado. El número de habitaciones no resultó ser un predictor significativo.
Si un constructor desea lanzar al mercado apartamentos en Normandía con un diseño estándar de 70 metros cuadrados y 3 habitaciones, ¿cómo variaría el precio estimado si ofrece opciones de 2 o 4 baños?
# Datos para el apartamento con 2 baños
apartamento_2_banos <- data.frame(Area_contruida = 70, Banos = 2, Habitaciones = 3)
prediccion_2_banos <- predict(mod_log, newdata = apartamento_2_banos)
cat("Precio estimado con 2 baños:", prediccion_2_banos, "millones\n")
## Precio estimado con 2 baños: 114.9493 millones
# Datos para el apartamento con 4 baños
apartamento_4_banos <- data.frame(Area_contruida = 70, Banos = 4, Habitaciones = 3)
prediccion_4_banos <- predict(mod_log, newdata = apartamento_4_banos)
cat("Precio estimado con 4 baños:", prediccion_4_banos, "millones\n")
## Precio estimado con 4 baños: 299.2752 millones
Aplicación
Permite a compradores y vendedores obtener una valoración de referencia para negociaciones, a inversores identificar oportunidades en el mercado, y a desarrolladores optimizar el diseño y precio de nuevos proyectos. También facilita el análisis de tendencias del mercado inmobiliario local y la valoración eficiente de portafolios de propiedades.
Monetización
Si el modelo es preciso, se puede monetizar ofreciendo servicios de valoración a inmobiliarias, avaluadores o inversores mediante suscripciones o informes de mercado. También se podría brindar consultoría a desarrolladores para la fijación de precios y diseño de proyectos, integrar el modelo en plataformas inmobiliarias a través de APIs, o desarrollar herramientas de software especializadas para agentes y usuarios finales. La clave es la precisión y el valor que el modelo aporta a los diferentes actores del mercado.