devtools::install_github("centromagis/paqueteMODELOS", force =TRUE)
## Downloading GitHub repo centromagis/paqueteMODELOS@HEAD
## stringi (1.8.3  -> 1.8.4 ) [CRAN]
## rlang   (1.1.3  -> 1.1.4 ) [CRAN]
## cli     (3.6.2  -> 3.6.3 ) [CRAN]
## Rcpp    (1.0.12 -> 1.0.13) [CRAN]
## digest  (0.6.34 -> 0.6.37) [CRAN]
## curl    (5.2.1  -> 5.2.2 ) [CRAN]
## fastmap (1.1.1  -> 1.2.0 ) [CRAN]
## xfun    (0.46   -> 0.47  ) [CRAN]
## Installing 8 packages: stringi, rlang, cli, Rcpp, digest, curl, fastmap, xfun
## Installing packages into 'C:/Users/Cenigaa-PC/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
## package 'stringi' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'stringi'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\stringi\libs\icudt74l.dat
## a
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\stringi\libs\icudt74l.dat:
## Invalid argument
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\stringi\libs\x64\stringi.dll
## a
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\stringi\libs\x64\stringi.dll:
## Permission denied
## Warning: restored 'stringi'
## package 'rlang' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'rlang'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\rlang\libs\x64\rlang.dll
## a C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\rlang\libs\x64\rlang.dll:
## Permission denied
## Warning: restored 'rlang'
## package 'cli' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'cli'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\cli\libs\x64\cli.dll
## a C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\cli\libs\x64\cli.dll:
## Permission denied
## Warning: restored 'cli'
## package 'Rcpp' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'Rcpp'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\Rcpp\libs\x64\Rcpp.dll
## a C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\Rcpp\libs\x64\Rcpp.dll:
## Permission denied
## Warning: restored 'Rcpp'
## package 'digest' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'digest'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\digest\libs\x64\digest.dll
## a
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\digest\libs\x64\digest.dll:
## Permission denied
## Warning: restored 'digest'
## package 'curl' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'curl'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\curl\libs\x64\curl.dll
## a C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\curl\libs\x64\curl.dll:
## Permission denied
## Warning: restored 'curl'
## package 'fastmap' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'fastmap'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\fastmap\libs\x64\fastmap.dll
## a
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\fastmap\libs\x64\fastmap.dll:
## Permission denied
## Warning: restored 'fastmap'
## package 'xfun' successfully unpacked and MD5 sums checked
## Warning: cannot remove prior installation of package 'xfun'
## Warning in file.copy(savedcopy, lib, recursive = TRUE): problema al copiar
## C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\00LOCK\xfun\libs\x64\xfun.dll
## a C:\Users\Cenigaa-PC\AppData\Local\R\win-library\4.3\xfun\libs\x64\xfun.dll:
## Permission denied
## Warning: restored 'xfun'
## 
## The downloaded binary packages are in
##  C:\Users\Cenigaa-PC\AppData\Local\Temp\RtmpaOHyhT\downloaded_packages
## ── R CMD build ─────────────────────────────────────────────────────────────────
##          checking for file 'C:\Users\Cenigaa-PC\AppData\Local\Temp\RtmpaOHyhT\remotes4c443f35395\Centromagis-paqueteMODELOS-78ce06f/DESCRIPTION' ...  ✔  checking for file 'C:\Users\Cenigaa-PC\AppData\Local\Temp\RtmpaOHyhT\remotes4c443f35395\Centromagis-paqueteMODELOS-78ce06f/DESCRIPTION' (781ms)
##       ─  preparing 'paqueteMODELOS': (3.3s)
##    checking DESCRIPTION meta-information ...  ✔  checking DESCRIPTION meta-information
##       ─  checking for LF line-endings in source and make files and shell scripts
##       ─  checking for empty or unneeded directories
##       ─  building 'paqueteMODELOS_0.1.0.tar.gz'
##      
## 
## Installing package into 'C:/Users/Cenigaa-PC/AppData/Local/R/win-library/4.3'
## (as 'lib' is unspecified)
library(paqueteMODELOS)
## Loading required package: boot
## Loading required package: broom
## Loading required package: GGally
## Loading required package: ggplot2
## Registered S3 method overwritten by 'GGally':
##   method from   
##   +.gg   ggplot2
## Loading required package: gridExtra
## Loading required package: knitr
## Loading required package: summarytools
data("vivienda")
df = data.frame(vivienda)
dim(df)
## [1] 8322   13
head(df)
##     id         zona piso estrato preciom areaconst parqueaderos banios
## 1 1147 Zona Oriente <NA>       3     250        70            1      3
## 2 1169 Zona Oriente <NA>       3     320       120            1      2
## 3 1350 Zona Oriente <NA>       3     350       220            2      2
## 4 5992     Zona Sur   02       4     400       280            3      5
## 5 1212   Zona Norte   01       5     260        90            1      2
## 6 1724   Zona Norte   01       5     240        87            1      3
##   habitaciones        tipo      barrio  longitud latitud
## 1            6        Casa 20 de julio -76.51168 3.43382
## 2            3        Casa 20 de julio -76.51237 3.43369
## 3            4        Casa 20 de julio -76.51537 3.43566
## 4            3        Casa  3 de julio -76.54000 3.43500
## 5            3 Apartamento       acopi -76.51350 3.45891
## 6            3 Apartamento       acopi -76.51700 3.36971

Introducción

Este estudio se enfoca en explorar el mercado de viviendas, entender las tendencias y patrones en el mercado inmobiliario se ha vuelto esencial para inversores, desarrolladores y formuladores de políticas. A través de un análisis detallado de una base de datos de propiedades en venta, este estudio busca identificar patrones, relaciones y segmentaciones relvantes que permitan mejorar la toma de decisiones en cuanto a la compra, venta y valoracion de propiedades.

data('vivienda')
df = data.frame(vivienda)
dim(df)
## [1] 8322   13

No es extraño que en este tipo de aplicaciones haya información que carezca de datos por varias razones, puede haberse producido por un error en el proceso de recopilación de datos, que ciertas medidas no sean aplicables o que, simplemente, determinados campos se hallan dejado en blanco.

Para este caso tenemos los siguientes datos faltantes:

Datos Faltantes por Variable
Variable Datos_Faltantes
id 3
zona 3
piso 2638
estrato 3
preciom 2
areaconst 3
parqueaderos 1605
banios 3
habitaciones 3
tipo 3
barrio 3
longitud 3
latitud 3

Tal como se muestra en la tabla anterior se evidencia que para la variable “piso y parqueo” cuentan con el mayor numero de observaciones faltantes del data frame, el cual es una proporción muy grande comparado con el tamaño del data frame el cual es de \(8.330\) filas por \(13\) columnas.

Para manejar los datos faltantes en las variables “piso” y “parqueaderos” del dataframe y realizar un análisis descriptivo efectivo, se adoptaron estrategias, considerando el contexto y la naturaleza de los datos.

datos_nulos <- colSums(is.na(df)) %>% 
  as.data.frame() %>%
  tibble::rownames_to_column("Variable") %>%
  setNames(c("Variable", "Datos_Nulos"))

ggplot(datos_nulos, aes(x = Variable, y = Datos_Nulos, fill = Variable)) +
  geom_bar(stat = "identity", show.legend = FALSE) +
  theme_minimal() +
  labs(title = "Distribución de Datos Nulos por Variable",
       x = "Variable",
       y = "Cantidad de Datos Nulos") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

## Estrategias para Datos Faltantes

Analisís prelimínar

Primero, es crucial entender el significado de cada variable y cómo los datos faltantes pueden influir en el análisis:

\(Piso\): Indica el nivel en el que se encuentra una propiedad dentro de un edificio. Los datos faltantes podrían indicar casas o propiedades que no aplican a esta categoría. Parquea (Parqueadero): Refiere a la disponibilidad de espacio de estacionamiento. Los datos faltantes podrían significar que no se proporcionó esta información o que la propiedad no cuenta con parqueadero.

Imputación:

Para “Piso”: Se podría imputar los datos faltantes con un valor específico que indique “No Aplica” o \("0"\) para casas y terrenos que típicamente no tienen un número de piso.

Pero teniendo en cuenta el comportamiento típico de los tipos de vivienda en Colombia en donde normalmente los apartamentos son de \(1\) piso y las casas de \(1\) o mas pisos por unidad residencial; partiendo del supuesto anterior y aplicando una imputación estrategia para esta variable en donde los valores nulos para el tipo de vivienda apartamento se imputo por el valor escalar de \(1\) piso y para el tipo de vivienda casa se realizó una agrupación por zona y estrato calculando la moda e imputando por este valor de medida central los valores nulos.

\[ \text{Moda} = \underset{x}{\operatorname{argmax}} \, P(X = x) \]

Para “Parquea”: En el caso de los parqueaderos, se podría imputar los valores faltantes con “0” para indicar la ausencia de parqueadero, suponiendo que la falta de información implica la falta del mismo, o un valor que denote “Información no proporcionada”;Para este análisis se razono de manera similar que en la imputación para tipo de viviendas casas, donde se tuvo en cuenta el valor más común de numero de parqueadero correspondiente a la zona de Cali, estrato y tipo de vivienda.

Analisís exploratrorio de los datos (EDA)

Posterior al manejo de datos faltantes correspondientes a la data frame y para entender el comportamiento de los precios de vivienda, se aplicaron técnicas de estadística descriptiva agrupando por las varibales “zona, tipo, estrato”, las cuales permitieron establecer y visualizar patrones de comportamiento de los precios de vivienda.

Para el cumplimiento del objetivo trazado se calcularon las siguientes medidas:

  1. Media: \[ \bar{x} = \frac{1}{n} \sum_{i=1}^{n} x_i \]
  2. Mediana: \[ \tilde{x} = \begin{cases} x_{(m+1)/2} & \text{si } n \text{ es impar} \\ \frac{1}{2} (x_{m/2} + x_{m/2 + 1}) & \text{si } n \text{ es par} \end{cases} \]
  3. Desviación estándar:

\[ \sigma = \sqrt{\frac{1}{n} \sum_{i=1}^{n} (x_i - \bar{x})^2} \]

Como resultado de haber realizado las imputaciones correspondientes, se obtuvo un data frame tidy y sin datos nulos tal como se muestra en la siguiente tabla:

##           id         zona         piso      estrato      preciom    areaconst 
##            3            3            5            3            2            3 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##         1605            3            3            3            3            3 
##      latitud      parquea 
##            3          872
Datos Faltantes por Variable
Variable Datos_Faltantes
id 0
zona 0
piso 0
estrato 0
preciom 0
areaconst 0
parqueaderos 0
banios 0
habitaciones 0
tipo 0
barrio 0
longitud 0
latitud 0
parquea 0

Filtrado de la Base de Datos

df_apartamentos <- df_sin_nulos %>%
  filter(tipo=='Apartamento')

head(df_apartamentos,3)
##     id       zona piso estrato preciom areaconst parqueaderos banios
## 1 1212 Zona Norte    1       5     260        90            1      2
## 2 1724 Zona Norte    1       5     240        87            1      3
## 3 2326 Zona Norte    1       4     220        52            2      2
##   habitaciones        tipo barrio  longitud latitud parquea
## 1            3 Apartamento  acopi -76.51350 3.45891       1
## 2            3 Apartamento  acopi -76.51700 3.36971       1
## 3            3 Apartamento  acopi -76.51974 3.42627       2
table(df_apartamentos$tipo)
## 
## Apartamento 
##        4231

2- Análisis Exploratorio de Datos

# Cargar librería plotly
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
# Crear gráficos interactivos
fig1 <- plot_ly(df_apartamentos, x = ~areaconst, y = ~preciom, type = 'scatter', mode = 'markers', 
                marker = list(size = 10, color = 'rgba(219, 64, 82, .8)', line = list(width = 2, color = 'rgba(219, 64, 82, .8)'))) %>%
  layout(title = 'Área Construida vs Precio',
         xaxis = list(title = 'Área Construida'),
         yaxis = list(title = 'Precio'))

fig2 <- plot_ly(df_apartamentos, x = ~estrato, y = ~preciom, type = 'box', 
                boxmean = TRUE) %>%
  layout(title = 'Estrato vs Precio',
         xaxis = list(title = 'Estrato'),
         yaxis = list(title = 'Precio'))

fig3 <- plot_ly(df_apartamentos, x = ~banios, y = ~preciom, type = 'scatter', mode = 'markers', 
                marker = list(size = 10, color = 'rgba(64, 94, 219, .8)', line = list(width = 2, color = 'rgba(64, 94, 219, .8)'))) %>%
  layout(title = 'Número de Baños vs Precio',
         xaxis = list(title = 'Número de Baños'),
         yaxis = list(title = 'Precio'))

fig4 <- plot_ly(df_apartamentos, x = ~habitaciones, y = ~preciom, type = 'scatter', mode = 'markers', 
                marker = list(size = 10, color = 'rgba(82, 184, 219, .8)', line = list(width = 2, color = 'rgba(82, 184, 219, .8)'))) %>%
  layout(title = 'Número de Habitaciones vs Precio',
         xaxis = list(title = 'Número de Habitaciones'),
         yaxis = list(title = 'Precio'))

fig5 <- plot_ly(df_apartamentos, x = ~zona, y = ~preciom, type = 'box', 
                boxmean = TRUE) %>%
  layout(title = 'Zona vs Precio',
         xaxis = list(title = 'Zona'),
         yaxis = list(title = 'Precio'))

# Mostrar gráficos
fig1
fig2
fig3
fig4
fig5

Área Construida vs Precio

El gráfico de dispersión muestra una relación positiva entre el área construida y el precio, es decir, a medida que aumenta el área construida, también lo hace el precio de la vivienda. Sin embargo, existe una variabilidad significativa en los precios para un mismo rango de área, lo que sugiere que otras variables también están influyendo en el precio.

Estrato vs Precio

El gráfico de caja muestra que el precio de las viviendas tiende a aumentar con el estrato. Los estratos más altos (5 y 6) tienen una mediana de precio más elevada y presentan mayor dispersión en los valores, lo que indica que en estos estratos hay una mayor variabilidad en el precio de las propiedades.

Número de Baños vs Precio

Existe una relación positiva entre el número de baños y el precio, aunque existe una variabilidad que es significativa. A medida que el número de baños aumenta, también lo hace el precio, pero la relación no es perfectamente lineal, y hay casos donde propiedades con menos baños tienen un precio similar o incluso superior a propiedades con más baños.

Número de Habitaciones vs Precio

De manera similar al número de baños, se observa una tendencia positiva entre el número de habitaciones y el precio. Sin embargo, hay una alta dispersión, especialmente en propiedades con 3 o 4 habitaciones, donde los precios pueden variar ampliamente.

Zona vs Precio

El gráfico de caja para las zonas muestra que las propiedades en la Zona Oeste tienden a tener los precios más altos, seguidas por la Zona Norte. Las zonas Centro, Oriente y Sur presentan precios medianos más bajos y menos dispersión.

3- Estimación del Modelo de Regresión Lineal Múltiple

data_dummy <- model.matrix(~ zona - 1, data = df_apartamentos)


df_apartamentos_dummy <- cbind(df_apartamentos, data_dummy)

# Ver los primeros registros para verificar la transformación
head(df_apartamentos_dummy)
##     id       zona piso estrato preciom areaconst parqueaderos banios
## 1 1212 Zona Norte    1       5     260        90            1      2
## 2 1724 Zona Norte    1       5     240        87            1      3
## 3 2326 Zona Norte    1       4     220        52            2      2
## 4 4386 Zona Norte    1       5     310       137            2      3
## 5 7497 Zona Norte    2       6     520        98            2      2
## 6 5424 Zona Norte    3       4     320       108            2      3
##   habitaciones        tipo barrio  longitud latitud parquea zonaZona Centro
## 1            3 Apartamento  acopi -76.51350 3.45891       1               0
## 2            3 Apartamento  acopi -76.51700 3.36971       1               0
## 3            3 Apartamento  acopi -76.51974 3.42627       2               0
## 4            4 Apartamento  acopi -76.53105 3.38296       2               0
## 5            2 Apartamento  acopi -76.54999 3.43505       2               0
## 6            3 Apartamento  acopi -76.53638 3.40770       2               0
##   zonaZona Norte zonaZona Oeste zonaZona Oriente zonaZona Sur
## 1              1              0                0            0
## 2              1              0                0            0
## 3              1              0                0            0
## 4              1              0                0            0
## 5              1              0                0            0
## 6              1              0                0            0
colnames(df_apartamentos_dummy) <- gsub(' ', '_', colnames(df_apartamentos_dummy))
colnames(df_apartamentos_dummy)
##  [1] "id"               "zona"             "piso"             "estrato"         
##  [5] "preciom"          "areaconst"        "parqueaderos"     "banios"          
##  [9] "habitaciones"     "tipo"             "barrio"           "longitud"        
## [13] "latitud"          "parquea"          "zonaZona_Centro"  "zonaZona_Norte"  
## [17] "zonaZona_Oeste"   "zonaZona_Oriente" "zonaZona_Sur"
modelo_multiple <- lm(preciom ~ areaconst + estrato + banios + habitaciones + parqueaderos + zonaZona_Centro + zonaZona_Norte + zonaZona_Oeste + zonaZona_Oriente + zonaZona_Sur, data = df_apartamentos_dummy)


summary(modelo_multiple)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios + habitaciones + 
##     parqueaderos + zonaZona_Centro + zonaZona_Norte + zonaZona_Oeste + 
##     zonaZona_Oriente + zonaZona_Sur, data = df_apartamentos_dummy)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1575.10   -57.54     2.34    49.58   966.99 
## 
## Coefficients: (1 not defined because of singularities)
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      -244.66618   16.14892 -15.151   <2e-16 ***
## areaconst           1.87580    0.04827  38.860   <2e-16 ***
## estrato            46.30401    3.11505  14.865   <2e-16 ***
## banios             54.23233    3.34406  16.217   <2e-16 ***
## habitaciones      -36.31317    3.75492  -9.671   <2e-16 ***
## parqueaderos       85.24179    4.06811  20.954   <2e-16 ***
## zonaZona_Centro    -8.85070   42.70307  -0.207    0.836    
## zonaZona_Norte      8.67129    5.42203   1.599    0.110    
## zonaZona_Oeste     84.50759    5.94077  14.225   <2e-16 ***
## zonaZona_Oriente  -10.18237   29.20283  -0.349    0.727    
## zonaZona_Sur             NA         NA      NA       NA    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 134.6 on 4221 degrees of freedom
## Multiple R-squared:  0.7945, Adjusted R-squared:  0.7941 
## F-statistic:  1813 on 9 and 4221 DF,  p-value: < 2.2e-16

Intercepto (-244.67) indica que el precio base cuando todas las variables independientes son cero o los parametros. no tiene mucho sentido en este contexto (pues no existen propiedades con todas las características en cero), por ello es importante analizar los parametros.

Área construida (1.88) lo que indica que, en promedio, por cada metro cuadrado adicional de área construida, el precio de la propiedad aumenta en 1.88 millones de pesos. El valor t (38.860) y el valor p (<2e-16) sugieren que este coeficiente es altamente significativo y es importante para la regresion.

Estrato (46.30) el coeficiente también es positivo y significativo. Un aumento en el estrato se asocia con un aumento de 46.30 millones de pesos en el precio de la propiedad, lo que tiene sentido dado que las propiedades en estratos más altos tienden a ser más costosas.

Número de baños (54.23) Por cada baño adicional, el precio de la propiedad aumenta en 54.23 millones de pesos, y este coeficiente también es estadísticamente significativo.

Número de habitaciones (-36.31), es poco comun que el número de habitaciones tiene un coeficiente negativo, lo que implica que, manteniendo las demás variables constantes, un aumento en el número de habitaciones está asociado con una reducción en el precio. Esto podría ser sintoma de un problema con la multicolinealidad o podría reflejar que en ciertas zonas, un mayor número de habitaciones está asociado a propiedades de menor tamaño o calidad (esto merece una revisión más detallada).

Parqueaderos (85.24): Cada parqueadero adicional está asociado con un aumento de 85.24 millones de pesos en el precio de la propiedad. Este coeficiente es altamente significativo y consistente con lo esperado, dado que tener más parqueaderos es un atributo valioso.

2. Zonas

Las variables relacionadas con las zonas tienen el siguiente comportamiento:

Zona Centro (-8.85): El coeficiente es negativo, pero no es significativo (p = 0.836), lo que sugiere que el precio de las propiedades en la Zona Centro no difiere significativamente de la zona de referencia (probablemente la “Zona Sur” que está excluida por la singularidad del modelo).

Zona Norte (8.67): El coeficiente es positivo, pero no es estadísticamente significativo (p = 0.110), lo que indica que el precio de las propiedades en la Zona Norte tampoco difiere mucho de la zona de referencia.

Zona Oeste (84.51): Este coeficiente es positivo y altamente significativo (p < 2e-16). Las propiedades en la Zona Oeste son, en promedio, 84.51 millones de pesos más costosas que las de la zona de referencia.

Zona Oriente (-10.18): El coeficiente es negativo, pero no es significativo (p = 0.727), lo que sugiere que no hay una diferencia importante en el precio de las propiedades en la Zona Oriente comparado con la zona de referencia.

Zona Sur (NA): No aparece en el modelo debido a la singularidad, lo que significa que se ha utilizado como la zona de referencia contra la cual se comparan todas las demás zonas.

3. Medidas de Ajuste del Modelo

R-squared = 0.7945: El valor indica que el 79.45% de la variabilidad en los precios de las propiedades es explicada por las variables incluidas en el modelo. Este es un ajuste bastante bueno para un modelo de regresión lineal múltiple en un contexto como este.

R-squared ajustado = 0.7941, también es alto y muy cercano, lo que indica que la cantidad de variables incluidas en el modelo no está introduciendo demasiada complejidad innecesaria (overfitting).

Residual Standard Error = 134.6: Esto indica la dispersión de los residuos dado el rango de precios que estamos manejando, es aceptable.

tambien clacule un modelo de regresion lineal multiple sin aplicar one hot encoding a la variable zona, y se obtuvo los mismas magnitudes que con el presente analisis.

modelo_multiple_2 <- lm(preciom ~ areaconst + estrato + banios + habitaciones + parqueaderos + zona, data = df_apartamentos)


summary(modelo_multiple_2)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios + habitaciones + 
##     parqueaderos + zona, data = df_apartamentos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1575.10   -57.54     2.34    49.58   966.99 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      -253.51688   44.94648  -5.640 1.81e-08 ***
## areaconst           1.87580    0.04827  38.860  < 2e-16 ***
## estrato            46.30401    3.11505  14.865  < 2e-16 ***
## banios             54.23233    3.34406  16.217  < 2e-16 ***
## habitaciones      -36.31317    3.75492  -9.671  < 2e-16 ***
## parqueaderos       85.24179    4.06811  20.954  < 2e-16 ***
## zonaZona Norte     17.52200   42.83789   0.409    0.683    
## zonaZona Oeste     93.35829   43.00841   2.171    0.030 *  
## zonaZona Oriente   -1.33167   51.45000  -0.026    0.979    
## zonaZona Sur        8.85070   42.70307   0.207    0.836    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 134.6 on 4221 degrees of freedom
## Multiple R-squared:  0.7945, Adjusted R-squared:  0.7941 
## F-statistic:  1813 on 9 and 4221 DF,  p-value: < 2.2e-16

4- Manejo de multicolinealidad

calculo de VIF (vARIANCE INFLATION FACTOR)

para mejorar el modelo podemos excluir los valores con p-value muy altos, lo cuales parecen no afectar el precio.

df_apartamentos_dummy <- df_apartamentos_dummy %>%
  select(-zonaZona_Sur)

df_apartamentos_dummy <- df_apartamentos_dummy %>%
  select( -zonaZona_Centro,  -zonaZona_Norte,  -zonaZona_Oeste)
modelo_multiple_3 <- lm(preciom ~ areaconst + estrato + banios + habitaciones + parqueaderos  + zonaZona_Oriente , data = df_apartamentos_dummy)


summary(modelo_multiple_3)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios + habitaciones + 
##     parqueaderos + zonaZona_Oriente, data = df_apartamentos_dummy)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1699.55   -57.73    -0.75    48.63  1005.46 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      -278.06714   15.92413 -17.462   <2e-16 ***
## areaconst           2.00528    0.04844  41.398   <2e-16 ***
## estrato            56.12485    3.08239  18.208   <2e-16 ***
## banios             54.79733    3.42229  16.012   <2e-16 ***
## habitaciones      -42.59509    3.81389 -11.168   <2e-16 ***
## parqueaderos       90.46495    4.14538  21.823   <2e-16 ***
## zonaZona_Oriente   -9.31453   29.83071  -0.312    0.755    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 137.7 on 4224 degrees of freedom
## Multiple R-squared:  0.7845, Adjusted R-squared:  0.7842 
## F-statistic:  2563 on 6 and 4224 DF,  p-value: < 2.2e-16
#vif_valores <- vif(modelo_multiple_3)

#print(vif_valores)

Teniendo en cuanta estos valores de VIF, no se evidencia problemas de multicolinealidad cuando eliminamos las varibales que no tienen mucho peso a la hora predecir la varible precio.

5- Partición de Datos en Conjunto de Entrenamiento y Prueba

set.seed(123)


train_index <- sample(1:nrow(df_apartamentos_dummy), 0.7 * nrow(df_apartamentos_dummy))


train_data <- df_apartamentos_dummy[train_index, ]
test_data <- df_apartamentos_dummy[-train_index, ]

cat("Tamaño del conjunto de entrenamiento:", nrow(train_data), "\n")
## Tamaño del conjunto de entrenamiento: 2961
cat("Tamaño del conjunto de prueba:", nrow(test_data), "\n")
## Tamaño del conjunto de prueba: 1270

estimacion del modelo con los datos de prueba

modelo_train <- lm(preciom ~ areaconst + estrato + banios + habitaciones + parqueaderos + zonaZona_Oriente, data = train_data)


summary(modelo_train)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios + habitaciones + 
##     parqueaderos + zonaZona_Oriente, data = train_data)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1289.34   -53.85     0.84    45.81   996.22 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      -244.40511   19.06791 -12.818   <2e-16 ***
## areaconst           2.29894    0.06105  37.660   <2e-16 ***
## estrato            50.38583    3.66816  13.736   <2e-16 ***
## banios             45.38624    4.12927  10.991   <2e-16 ***
## habitaciones      -45.24009    4.63109  -9.769   <2e-16 ***
## parqueaderos       87.58094    5.10471  17.157   <2e-16 ***
## zonaZona_Oriente    0.44907   33.53182   0.013    0.989    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 136.3 on 2954 degrees of freedom
## Multiple R-squared:  0.7954, Adjusted R-squared:  0.795 
## F-statistic:  1914 on 6 and 2954 DF,  p-value: < 2.2e-16

6- Predicciones con los datos de prueba

predicciones <- predict(modelo_train, newdata = test_data)


test_data$predicciones <- predicciones


head(test_data)
##      id       zona piso estrato preciom areaconst parqueaderos banios
## 3  2326 Zona Norte    1       4     220        52            2      2
## 6  5424 Zona Norte    3       4     320       108            2      3
## 14 1770 Zona Norte    6       5     170        56            1      1
## 22 8255 Zona Oeste    2       6    1130       237            3      4
## 34 7617 Zona Oeste    5       6     950       217            3      5
## 43 8060 Zona Oeste    6       6     850       194            2      5
##    habitaciones        tipo    barrio  longitud latitud parquea
## 3             3 Apartamento     acopi -76.51974 3.42627       2
## 6             3 Apartamento     acopi -76.53638 3.40770       2
## 14            2 Apartamento     acopi -76.51735 3.37251       1
## 22            3 Apartamento aguacatal -76.56001 3.45770       3
## 34            4 Apartamento aguacatal -76.55081 3.45659       3
## 43            3 Apartamento aguacatal -76.55450 3.45077       2
##    zonaZona_Oriente predicciones
## 3                 0     206.8973
## 6                 0     381.0242
## 14                0     178.7518
## 22                0     911.3266
## 34                0     865.4939
## 43                0     770.2774

7- Calculo de mtericas

rmse <- sqrt(mean((test_data$preciom - test_data$predicciones)^2))
cat("Error Cuadrático Medio (RMSE):", rmse, "\n")
## Error Cuadrático Medio (RMSE): 143.2745
mae <- mean(abs(test_data$preciom - test_data$predicciones))
cat("Error Absoluto Medio (MAE):", mae, "\n")
## Error Absoluto Medio (MAE): 85.39021
sst <- sum((test_data$preciom - mean(test_data$preciom))^2)
sse <- sum((test_data$preciom - test_data$predicciones)^2)
r_squared <- 1 - (sse/sst)
cat("R^2 en el conjunto de prueba:", r_squared, "\n")
## R^2 en el conjunto de prueba: 0.7487219

Teniendo en cuanta el contexto de y el origen de los datos, junto con las imputaciones relaizadas para el manejo de los datos faltentes, que para RMSE se tiene en magnitus un erros de aproximadamente 143 millones.