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

Análisis exploratorio

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()

Análisis Bivariado

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

Modelación simple

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.

Modelación múltiple

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

Selección de variables

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

Interacción con variable dummy

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

Modelo múltiple transformación de datos

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.

Último punto - predicción

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 del modelo

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.