Introducción

En este documento se presentan los procedimientos, métodos y resultados de una revisión de la oferta inmobiliaria urbana de Cali, con el objetivo principal de plantear un Modelo de Regresión Lineal Múltiple para predecir el precio de las viviendas de la zona norte de la ciudad en función de varias variables explicativas que se seleccionan aplicando un análisis exploratorio de los datos disponibles.

Para la construcción, prueba y evaluación del modelo final se siguieron una serie de pasos y actividades relacionadas con:

  • El entendimiento de los datos: filtrar los datos de interés que son las casas de la zona norte de Cali de los estratos 3, 4, 5 y 6, conocer en detalle la estructura del conjunto de datos, identificar datos faltantes y atípicos, conocer el tipo y la composición de cada variable e identificar la relación entre las variables.
  • La transformación y preparación del conjunto de datos: solo se identificaron 3 registros faltantes que se eliminaron, se convirtió el tipo de la variable estrato de numérico a categórico, se estandarizó las variables precio y área construida y de la variable categórica estrato se crearon 3 variables ficticias.
  • Planteamiento del Modelo de Regresión Múltiple, se prueba un modelo inicial incluyendo todas las variables explicativas disponibles en su forma original y un segundo modelo con las variables estandarizadas y no se observó ningún efecto en los resultados. Para encontrar el mejor modelo se aplicó el método Stepwise Forward y se encontró que la variable número de habitaciones no es significativa para explicar el precio de las casas, se presenta una breve interpretación de los resultados. -Validación de los supuestos del modelo: se validaron los supuestos del Modelo de Regresión Lineal Múltiple, normalidad de la distribución de los errores, los errores tienen media cero, homocedasticidad de los errores y no autocorrelación de los errores.
  • Partición del conjunto de datos en entrenamiento y prueba: aleatoriamente se dividieron los datos en un conjunto de entrenamiento (70%) y un conjunto de prueba (30%).
  • Ajuste del modelo con los datos de entrenamiento: se estimaron los coeficientes del modelo de regresión lineal múltiple para explicar el comportamiento de los precios en función del área, el número de baños y el estrato, obteniendo un coeficiente de determinación \(R^2\) del 69%.
  • Predicciones con el conjunto de prueba: se realizaron las predicciones en los 215 registros del conjunto de prueba para finalmente evaluar el desemepeño del modelo de acuerdo al Error Cuadrático Medio RMSE, al Error Absoluto Medio MAE y al Coeficiente de Determinación \(R^2\).

1. Entendimiento de los datos

Se inicia explorando el conjunto de datos para conocer su tamaño y el tipo de variables que contiene, determinar si las variables tienen los registros completos y si hay presencia de datos atípicos; es importante familiarizarse con el tipo de datos; también se realizan tablas y gráficos para resumir las principales variables con medidas estadísticas básicas. Se destaca que en esta parte no se realiza ninguna modificación sobre el conjunto de datos.

Cargar los datos de interés.

## Rows: 8,322
## Columns: 13
## $ id           <dbl> 1147, 1169, 1350, 5992, 1212, 1724, 2326, 4386, 1209, 159…
## $ zona         <chr> "Zona Oriente", "Zona Oriente", "Zona Oriente", "Zona Sur…
## $ piso         <chr> NA, NA, NA, "02", "01", "01", "01", "01", "02", "02", "02…
## $ estrato      <dbl> 3, 3, 3, 4, 5, 5, 4, 5, 5, 5, 6, 4, 5, 6, 4, 5, 5, 4, 5, …
## $ preciom      <dbl> 250, 320, 350, 400, 260, 240, 220, 310, 320, 780, 750, 62…
## $ areaconst    <dbl> 70, 120, 220, 280, 90, 87, 52, 137, 150, 380, 445, 355, 2…
## $ parqueaderos <dbl> 1, 1, 2, 3, 1, 1, 2, 2, 2, 2, NA, 3, 2, 2, 1, 4, 2, 2, 2,…
## $ banios       <dbl> 3, 2, 2, 5, 2, 3, 2, 3, 4, 3, 7, 5, 6, 2, 4, 4, 4, 3, 2, …
## $ habitaciones <dbl> 6, 3, 4, 3, 3, 3, 3, 4, 6, 3, 6, 5, 6, 2, 5, 5, 4, 3, 3, …
## $ tipo         <chr> "Casa", "Casa", "Casa", "Casa", "Apartamento", "Apartamen…
## $ barrio       <chr> "20 de julio", "20 de julio", "20 de julio", "3 de julio"…
## $ longitud     <dbl> -76.51168, -76.51237, -76.51537, -76.54000, -76.51350, -7…
## $ latitud      <dbl> 3.43382, 3.43369, 3.43566, 3.43500, 3.45891, 3.36971, 3.4…

Verificar la estandarización de la variable tipo de vivienda, es importante porque se filtra solo casas.

table(data$tipo, useNA="always")
## 
## Apartamento        Casa        <NA> 
##        5100        3219           3

Obtener un conjunto de datos de las variables con las que se va a trabajar: zona, estrato, preciom, areaconst, banios, habitaciones y tipo. La variable tipo para realizar el filto en el segmento de casas y la variable zona para realizar el filtro de las casas ubicadas en el norte.

data1 = data[, -c(1, 3, 7, 11, 12, 13)]

head(data1)
## # A tibble: 6 × 7
##   zona         estrato preciom areaconst banios habitaciones tipo       
##   <chr>          <dbl>   <dbl>     <dbl>  <dbl>        <dbl> <chr>      
## 1 Zona Oriente       3     250        70      3            6 Casa       
## 2 Zona Oriente       3     320       120      2            3 Casa       
## 3 Zona Oriente       3     350       220      2            4 Casa       
## 4 Zona Sur           4     400       280      5            3 Casa       
## 5 Zona Norte         5     260        90      2            3 Apartamento
## 6 Zona Norte         5     240        87      3            3 Apartamento

Filtrar el conjunto de datos por el segmento de casas de la zona norte:

data_casaN = data1[data1$zona=="Zona Norte" & data1$tipo=="Casa", ]
head(data_casaN)
## # A tibble: 6 × 7
##   zona       estrato preciom areaconst banios habitaciones tipo 
##   <chr>        <dbl>   <dbl>     <dbl>  <dbl>        <dbl> <chr>
## 1 Zona Norte       5     320       150      4            6 Casa 
## 2 Zona Norte       5     780       380      3            3 Casa 
## 3 Zona Norte       6     750       445      7            6 Casa 
## 4 Zona Norte       4     625       355      5            5 Casa 
## 5 Zona Norte       5     750       237      6            6 Casa 
## 6 Zona Norte       4     600       160      4            5 Casa

Eliminar las variables tipo y zona porque ya no se necesitan para el presente análisis:

Casas1 = data_casaN[, -c(1, 7)]

head(Casas1)
## # A tibble: 6 × 5
##   estrato preciom areaconst banios habitaciones
##     <dbl>   <dbl>     <dbl>  <dbl>        <dbl>
## 1       5     320       150      4            6
## 2       5     780       380      3            3
## 3       6     750       445      7            6
## 4       4     625       355      5            5
## 5       5     750       237      6            6
## 6       4     600       160      4            5

Identificar los registros faltantes por variable

En el conjunto de datos transformado para este análisis, que contiene cinco variables de interés y con el objetivo principal de modelar el precio (variable de respuesta o dependiente) a partir de cuatro variables de tipo numérico: estrato, areaconst, baños y habitaciones. La variable estrato se asume de tipo categórico (por ejemplo no tiene sentido promediar el estrato) y por lo tanto se realizará la transformación respectiva. De esta forma, se observa solo tres registros faltantes y se procede a eliminarlos.

sapply(Casas1, function(x) sum(is.na(x)))
##      estrato      preciom    areaconst       banios habitaciones 
##            3            3            3            3            3

Eliminar los NA

casas = Casas1[!is.na(Casas1$estrato), ]
casas = Casas1[!is.na(Casas1$preciom), ]
casas = Casas1[!is.na(Casas1$areaconst), ]
casas = Casas1[!is.na(Casas1$banios), ]
casas = Casas1[!is.na(Casas1$habitaciones), ]

head(casas)
## # A tibble: 6 × 5
##   estrato preciom areaconst banios habitaciones
##     <dbl>   <dbl>     <dbl>  <dbl>        <dbl>
## 1       5     320       150      4            6
## 2       5     780       380      3            3
## 3       6     750       445      7            6
## 4       4     625       355      5            5
## 5       5     750       237      6            6
## 6       4     600       160      4            5

Entonces, para este análisis se dispone de un conjunto de datos compuesto por 722 registros y cinco variables, correspondientes a las casas de la zona norte de los estratos 3, 4, 5 y 6 de la ciudad de Cali.

dim(casas)
## [1] 722   5

Tabla de frecuencias para las variables estrato, baños y habitaciones.

Tabla de frecuencias para la variable estrato

table(casas$estrato)
## 
##   3   4   5   6 
## 235 161 271  55

Tabla de frecuencias para la variable baños

table(casas$banios)
## 
##   0   1   2   3   4   5   6   7   8   9  10 
##  10  17 165 187 171 101  46  11  11   1   2

Tabla de frecuencias para la variable habitaciones

table(casas$habitaciones)
## 
##   0   1   2   3   4   5   6   7   8   9  10 
##  20   2  12 171 222 137  60  42  29  14  13

Resumen estadístico de las variables preciom y areaconst

Resumen estadístico de la variable preciom

summarytools::descr(casas$preciom)
## Descriptive Statistics  
## casas$preciom  
## N: 722  
## 
##                     preciom
## ----------------- ---------
##              Mean    445.91
##           Std.Dev    268.36
##               Min     89.00
##                Q1    260.00
##            Median    390.00
##                Q3    550.00
##               Max   1940.00
##               MAD    220.17
##               IQR    288.75
##                CV      0.60
##          Skewness      1.76
##       SE.Skewness      0.09
##          Kurtosis      4.65
##           N.Valid    722.00
##         Pct.Valid    100.00

Histograma para la variable preciom

hist(casas$preciom, xlim=c(50, 2000), las=1, main="Distribución del preciom Casas en Cali", xlab="Precio(milesCOP/m2)", ylab="Frecuencia", col="#EE964B")

De acuerdo al histograma de la variable preciom, los datos analizados tienen una distribución sesgada a la derecha, lo que se corrobora en que la media 446 mil pesos es mayor a la mediana 390 mil pesos. Aunque el rango de la distribución de los datos es muy amplio el cuartil 3 es de 550 mil pesos, es decir el 75% ´de las casas del norte de Cali está por debajo de dicho precio.

Resumen estadístico de la variable areaconst

summarytools::descr(casas$areaconst)
## Descriptive Statistics  
## casas$areaconst  
## N: 722  
## 
##                     areaconst
## ----------------- -----------
##              Mean      264.85
##           Std.Dev      167.17
##               Min       30.00
##                Q1      140.00
##            Median      240.00
##                Q3      337.00
##               Max     1440.00
##               MAD      146.78
##               IQR      196.75
##                CV        0.63
##          Skewness        1.85
##       SE.Skewness        0.09
##          Kurtosis        6.24
##           N.Valid      722.00
##         Pct.Valid      100.00
hist(casas$areaconst, xlim=c(20, 1500), las=1, main="Distribución del areaconst Casas en Cali", xlab="Area(m2)", ylab="Frecuencia", col="#FF4040")

Como se observa la distribución está muy concentrada en áreas “pequeñas” para las viviendas de la ciudad de Cali, el cuartil 3 indica que el 75% de los datos tienen un área menor de 337 metros cuadrados.

Tablas para resumir el cruce de variables y las principales estadísticas

Llama la atención que en la base de datos no haya casas en los estratos 1 y 2, se corrobora que en el conjunto de datos original tampoco había registros en dichos estratos.

Tabla del PRECIOM por ESTRATO

C1 = aggregate(casas$preciom, list(casas$estrato), FUN=mean)
colnames(C1)=c("Estrato", "Media del Precio")
C1
##   Estrato Media del Precio
## 1       3         244.1532
## 2       4         438.7702
## 3       5         549.5277
## 4       6         818.2545

Diagrama de cajas y bigotes del PRECIOM por ESTRATO

boxplot(casas$preciom~casas$estrato, main="Precio Casas Norte Cali", ylab="Precio(milesCOP/m2)", xlab="Estrato", las=1, col=c("#FAEBD7", "#7FFFD4", "#98F5FF", "#7FFF00"))

Como es de espearar, a medida que aumenta el estrato aumenta el promedio del precio de las casas de la zona norte de Cali. El precio promedio del estrato 6 casi que cuadrúplica el precio promedio de las casas del estrato 3.

Tabla del AREACONST por ESTRATO

C2 = aggregate(casas$areaconst, list(casas$estrato), FUN=mean)
colnames(C2)=c("Estrato", "Media del Area Construida")
C2
##   Estrato Media del Area Construida
## 1       3                  166.0889
## 2       4                  261.9804
## 3       5                  325.2554
## 4       6                  397.6018

Diagrama de cajas y bigotes del AREACONST por ESTRATO

boxplot(casas$areaconst~casas$estrato, main="Area Construida Casas Norte Cali", ylab="Area(m2)", xlab="Estrato", las=1, col=c("#FAEBD7", "#7FFFD4", "#98F5FF", "#7FFF00"))

Relación entre las variables cuantitativas

library(psych)

corPlot(casas[, 2:5], stars = TRUE)

plot(x=casas$areaconst, y=casas$preciom, main="Gráfico de Dispersión Precio ~ Area", xlab="Area m2", ylab="Precio x m2 miles de COP")

plot(x=casas$banios, y=casas$preciom, main="Gráfico de Dispersión Precio ~ Baños", xlab="# Baños", ylab="Precio x m2 miles de COP")

plot(x=casas$habitaciones, y=casas$preciom, main="Gráfico de Dispersión Precio ~ Habitaciones", xlab="# Habitaciones", ylab="Precio x m2 miles de COP")

Desde el punto de vista de la relación lineal media entre la variable de respuesta preciom y la variable explicativa areaconst (Coeficiente de Correlación 0.73) si es conveniente plantear un modelo de regresión para explicar los cambios en el precio en función del área construida. Aunque se observa una correlación débil entre la variable baños y el precio y un muy baja correlación entre la variable habitaciones y el precio, también se pueden incluir en el modelo para explorar su aporte.

2. Transformación y preparación de los datos

Aunque la variable ESTRATO es originalmente de tipo numérico, no tiene sentido procesarla así en el modelo de Regresión Lineal Múltiple, entonces se la va a transformar a tipo categórico, como se puede apreciar en el diagrama de cajas y bigotes no es conveniente juntar estratos para categorizarlos porque hay diferencias observables en los precios y áreas de cada estrato, entonces se mantienen los estratos Tres, Cuatro, Cinco y Seis..

casas$estrato[casas$estrato== 3] <- "Tres"
casas$estrato[casas$estrato== 4] <- "Cuatro"
casas$estrato[casas$estrato== 5] <- "Cinco"
casas$estrato[casas$estrato== 6] <- "Seis"

head(casas)
## # A tibble: 6 × 5
##   estrato preciom areaconst banios habitaciones
##   <chr>     <dbl>     <dbl>  <dbl>        <dbl>
## 1 Cinco       320       150      4            6
## 2 Cinco       780       380      3            3
## 3 Seis        750       445      7            6
## 4 Cuatro      625       355      5            5
## 5 Cinco       750       237      6            6
## 6 Cuatro      600       160      4            5

Dado que se desea incluir la variable categórica estrato en el modelo de Regresión Lineal Múltiple** es necesario crear 3 variables ficticias, en función del Estrato Tres, que solo pueden tomar el valor de 0 ó 1.

casas$F1 = as.numeric(casas$estrato=="Cuatro")
casas$F2 = as.numeric(casas$estrato=="Cinco")
casas$F3 = as.numeric(casas$estrato=="Seis")

head(casas)
## # A tibble: 6 × 8
##   estrato preciom areaconst banios habitaciones    F1    F2    F3
##   <chr>     <dbl>     <dbl>  <dbl>        <dbl> <dbl> <dbl> <dbl>
## 1 Cinco       320       150      4            6     0     1     0
## 2 Cinco       780       380      3            3     0     1     0
## 3 Seis        750       445      7            6     0     0     1
## 4 Cuatro      625       355      5            5     1     0     0
## 5 Cinco       750       237      6            6     0     1     0
## 6 Cuatro      600       160      4            5     1     0     0

3. Modelo de Regresión Lineal Múltiple inicial

El Modelo de Regresión Lineal Múltiple incial que se platea es explicar los cambios en el precio de las casas de la zona norte de Cali en función de su área construida, el número de baños, el número de habitaciones y el estrato. Dado que el estrato se asume como variable de tipo categórico con cuatro categorías (Estrato Tres, Cuatro, Cinco y Seis) se crean tres variables ficticias F1, F2 y F3, cuyos únicos valores posibles son 0 ó 1, para las categorías Estrato Cuatro, Estrato Cinco y Estrato Seis dejando como base la categoría Estrato Tres.

modelo1 = lm(preciom ~ areaconst + banios + habitaciones + F1 + F2 + F3, data = casas)
summary(modelo1)
## 
## Call:
## lm(formula = preciom ~ areaconst + banios + habitaciones + F1 + 
##     F2 + F3, data = casas)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -972.05  -73.02  -15.60   45.95 1064.25 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   30.27964   17.60512   1.720   0.0859 .  
## areaconst      0.82657    0.04289  19.274  < 2e-16 ***
## banios        25.83183    5.34112   4.836 1.62e-06 ***
## habitaciones   1.81876    4.10123   0.443   0.6576    
## F1            85.86991   17.27886   4.970 8.40e-07 ***
## F2           139.49127   16.13506   8.645  < 2e-16 ***
## F3           330.33116   26.46332  12.483  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 156.9 on 715 degrees of freedom
## Multiple R-squared:  0.6611, Adjusted R-squared:  0.6583 
## F-statistic: 232.5 on 6 and 715 DF,  p-value: < 2.2e-16

La interpretación de los resultados del Modelo de Regresión Lineal Múltiple inicial (modelo1) se pueden resumir en cuatro aspectos:

Primero De acuerdo al p-value de la Prueba F, el modelo1 es estadísticamente significativo, es decir, las variables independientes (área construida, número de baños, número de habitaciones y estrato) si contribuyen a explicar el comportamiento del precio de las casas de la zona norte de Cali.

Segundo Por el coeficiente de determinación \(R^2\) se concluye que las variables independientes incluidas en el modelo1 (área construida, numero de baños, número de habitaciones y estrato) explican en un 66.11% el comportamiento de los precios de las casas de la zona norte de Cali.

Tercero De acuerdo al p-value de la Prueba t se puede concluir que las variables: área construida, número de baños y las tres ficticias relacionadas al estrato, son estadísticamente significativas y contribuyen a explicar el comportamiento del precio de las casas de la zona norte de Cali. Es acorde con la realidad que el precio de una casa esté explicado por su área construida, número de baños y estrato; pero no es tan coherente con la realidad que, en el modelo1, el número de habitaciones no contribuya a explicar los precios de las casas. El interpecto del modelo no es estadísticamente significativo en el modelo1.

Cuarto El valor y el signo de los coeficientes del modelo1 indican la intensidad y la dirección de la relación de las variables independientes con el precio, de cauerdo a la naturaleza de las variables es de esperar que todos los coeficientes tengan signos positivos porque a mayor: área, número de baños, número de habitaciones y a mayor estrato es de esperar un mayor precio de las casas.

Para mejorar los resultados del modelo1 se puede realizar una estandarización de las variables preciom y areaconst (por tener un rango de variación muy amplio) y aplicar una estimación paso a paso (Stepwise) para dejar las vairables que aporten más en la explicación del comportamiento del precio de las casas.

Estandarización de las variables

casas1 = casas%>%mutate_each_(list(~scale(.)%>%as.vector),
                 vars = c("preciom", "areaconst"))
## Warning: `mutate_each_()` was deprecated in dplyr 0.7.0.
## ℹ Please use `across()` instead.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
head(casas1)
## # A tibble: 6 × 8
##   estrato preciom areaconst banios habitaciones    F1    F2    F3
##   <chr>     <dbl>     <dbl>  <dbl>        <dbl> <dbl> <dbl> <dbl>
## 1 Cinco    -0.469    -0.687      4            6     0     1     0
## 2 Cinco     1.24      0.689      3            3     0     1     0
## 3 Seis      1.13      1.08       7            6     0     0     1
## 4 Cuatro    0.667     0.539      5            5     1     0     0
## 5 Cinco     1.13     -0.167      6            6     0     1     0
## 6 Cuatro    0.574    -0.627      4            5     1     0     0

Modelo2 con variables estandarizadas

modelo2 = lm(preciom ~ areaconst + banios + habitaciones + F1 + F2 + F3, data = casas1)
summary(modelo2)
## 
## Call:
## lm(formula = preciom ~ areaconst + banios + habitaciones + F1 + 
##     F2 + F3, data = casas1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.6221 -0.2721 -0.0581  0.1712  3.9657 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -0.732992   0.076113  -9.630  < 2e-16 ***
## areaconst     0.514877   0.026714  19.274  < 2e-16 ***
## banios        0.096256   0.019902   4.836 1.62e-06 ***
## habitaciones  0.006777   0.015282   0.443    0.658    
## F1            0.319975   0.064386   4.970 8.40e-07 ***
## F2            0.519783   0.060124   8.645  < 2e-16 ***
## F3            1.230904   0.098610  12.483  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5846 on 715 degrees of freedom
## Multiple R-squared:  0.6611, Adjusted R-squared:  0.6583 
## F-statistic: 232.5 on 6 and 715 DF,  p-value: < 2.2e-16

Al realizar la estandarización de las variables el coeficiente de determinación \(R^2\) del modelo2 se mantiene igual que el del modelo1 en el 66.11%. La única diferencia entre los dos modelos es que en el modelo2 mejora la significancia estadística de intercepto.

Estimación paso a paso o Stepwise

# Definir el modelo inicial, solo el intercepto
modelo0 = lm(preciom ~ 1, data = casas1)

# Modelo con todos los predictores
modelo_all = lm(preciom ~ areaconst + banios + habitaciones + F1 + F2 + F3, data = casas1)

# Aplicar el proceso forward Stepwise Regression
forward = step(modelo0, direction = 'forward', scope = formula(modelo_all), trace = 0)

# Visualizar los resultados
forward$anova
##          Step Df   Deviance Resid. Df Resid. Dev          AIC
## 1             NA         NA       721   721.0000    0.9993068
## 2 + areaconst -1 385.641195       720   335.3588 -549.6470143
## 3        + F3 -1  40.870921       719   294.4879 -641.4804148
## 4    + banios -1  23.818816       718   270.6691 -700.3745709
## 5        + F2 -1  17.785140       717   252.8839 -747.4462554
## 6        + F1 -1   8.492953       716   244.3910 -770.1107139

Se visualiza el resultado final del modelo

summary(forward)
## 
## Call:
## lm(formula = preciom ~ areaconst + F3 + banios + F2 + F1, data = casas1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -3.6099 -0.2725 -0.0609  0.1687  3.9835 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -0.71505    0.06444 -11.097  < 2e-16 ***
## areaconst    0.51753    0.02602  19.889  < 2e-16 ***
## F3           1.22147    0.09624  12.693  < 2e-16 ***
## banios       0.10099    0.01679   6.016 2.85e-09 ***
## F2           0.51393    0.05863   8.766  < 2e-16 ***
## F1           0.31408    0.06297   4.988 7.66e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5842 on 716 degrees of freedom
## Multiple R-squared:  0.661,  Adjusted R-squared:  0.6587 
## F-statistic: 279.3 on 5 and 716 DF,  p-value: < 2.2e-16

De acuero a los resultados anteriores el modelo adecuado y el que se utilizará para la estimación del precio excluye la variable número de habitaciones. Entonces, se va a explicar el precio de las casas en función de su área construida, el número de baños y las tres variables ficticias relacionadas al estrato.

4. Validación de los supuestos del modelo.

Los errores son variables aleatorias normales

Se puede validar la distribución normal de los errores analizando el gráfico Q-Q.

qqnorm(forward$residuals)
qqline(forward$residuals)

shapiro.test(forward$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  forward$residuals
## W = 0.83045, p-value < 2.2e-16

El Gráfico Q-Q Plot de normalidad de los residuales muestra que no siguen una distribución normal, esta conclusión se evidencia también con el resultado de la prueba de normalidad Shapiro-Wilk en la que se rechaza la hipótesis nula porque el p-value (0.00) es menor a alfa (0.05).

El no cumplir con el supuesto de normalidad puede deberse a la presencia de datos atípicos, se puede probbar estudiando los datos extramos revisando si se deben a errores de registro o transcricpión para depurar el conjunto de datos.

Los errores tienen media cero

summarytools::descr(forward$residuals)
## Descriptive Statistics  
## forward$value  
## N: 722  
## 
##                                     value
## ----------------- -----------------------
##              Mean                    0.00
##           Std.Dev                    0.58
##               Min                   -3.61
##                Q1                   -0.27
##            Median                   -0.06
##                Q3                    0.17
##               Max                    3.98
##               MAD                    0.33
##               IQR                    0.44
##                CV   -31999919286694912.00
##          Skewness                    1.55
##       SE.Skewness                    0.09
##          Kurtosis                   10.92
##           N.Valid                  722.00
##         Pct.Valid                  100.00

Los errores tienen media aproximadamente igual a cero.

Los errores tienen varianza constante (homocedasticidad)

Se valida la hocedasticidad a través del Test Breusch-Pagan:

\[H_{0}: V[\epsilon_{i}]=\sigma^2, H_{a}: V[\epsilon_{i}]\neq\sigma^2\]

lmtest::bptest(forward)
## 
##  studentized Breusch-Pagan test
## 
## data:  forward
## BP = 132.54, df = 5, p-value < 2.2e-16

El \(p-valor\) es muy pequeño, prácticamente cero, entonces se rechaza la hipótesis nula y hay evidencias de falta de hocedasticidad.

Los errores son mutuamente independientes o no autocorrelación de los errores

Se valida la no autocorrelación de errores a través del Test Durbin-Watson:

\[H_{0}: V[\epsilon_{i},\epsilon_{j}]=0, V[\epsilon_{i},\epsilon_{j}]\neq0\]

lmtest::dwtest(forward)
## 
##  Durbin-Watson test
## 
## data:  forward
## DW = 1.69, p-value = 1.163e-05
## alternative hypothesis: true autocorrelation is greater than 0

El \(p-valor\) es muy pequeño, practicamente cero, entonces se rechaza la hipótesis nula por lo que hay evidencia de que los errores presentan una autocorrelación mayor a cero.

Se puede probar algunos ajustes como el análisis de los datos atípicos para evaluar si es conveniente eliminarlos y también probar la transformación, por ejemplo logarítmica, de las variables explicativas y de la variable de resupuesta para evaluar si se pueden validar los supuestos necesarios para aplicar un Modelo de Regresión Lineal Múltiple.

5. Partición del conjunto de datos en entrenamiento (70%) y prueba (30%).

library(caret)
## Warning: package 'caret' was built under R version 4.3.3
## Warning: package 'ggplot2' was built under R version 4.3.3

A continuación, se realiza la partición del conjunto de datos original denominado casas, compuesto por 722 registros válidos. La partición se realiza de forma aleatoria generando un conjunto de entrenamiento denominado Train con 507 registros (70%) y un conjunto de prueba denominado Test con 215 registros (30%).

set.seed(123)
IndexTraining = createDataPartition(y = casas$preciom, p=0.7, list = FALSE, times = 1)
Train = casas[IndexTraining, ]
Test = casas[-IndexTraining, ]
dim(casas)
## [1] 722   8
Train
## # A tibble: 507 × 8
##    estrato preciom areaconst banios habitaciones    F1    F2    F3
##    <chr>     <dbl>     <dbl>  <dbl>        <dbl> <dbl> <dbl> <dbl>
##  1 Cinco       320       150      4            6     0     1     0
##  2 Seis        750       445      7            6     0     0     1
##  3 Cuatro      625       355      5            5     1     0     0
##  4 Cinco       750       237      6            6     0     1     0
##  5 Cinco       490       118      4            4     0     1     0
##  6 Tres        500       210      6            6     0     0     0
##  7 Tres        380       300      5            8     0     0     0
##  8 Cuatro      305       117      3            4     1     0     0
##  9 Cuatro      350       118      3            3     1     0     0
## 10 Cinco       395       165      4            4     0     1     0
## # ℹ 497 more rows
Test
## # A tibble: 215 × 8
##    estrato preciom areaconst banios habitaciones    F1    F2    F3
##    <chr>     <dbl>     <dbl>  <dbl>        <dbl> <dbl> <dbl> <dbl>
##  1 Cinco       780       380      3            3     0     1     0
##  2 Cuatro      600       160      4            5     1     0     0
##  3 Cinco       420       200      4            5     0     1     0
##  4 Tres        230       160      2            3     0     0     0
##  5 Tres        190       435      0            0     0     0     0
##  6 Tres        180       120      3            3     0     0     0
##  7 Cinco       520       455      5            4     0     1     0
##  8 Cuatro      485       320      4            0     1     0     0
##  9 Cinco       390       357      3            6     0     1     0
## 10 Seis        680       146      5            5     0     0     1
## # ℹ 205 more rows

Ahora se ajusta un Modelo de Regresión Lienal Múltiple con el conjunto de datos Test para explicar el precio de las viviendas, siguiendo la recomendación del Stepwise, en función del área construida, el número de baños y las tres variables ficticias relacionadas con el estrato.

MODEL = lm(preciom ~ areaconst + banios + F1 + F2 + F3, data = Train)
summary(MODEL)
## 
## Call:
## lm(formula = preciom ~ areaconst + banios + F1 + F2 + F3, data = Train)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -749.29  -76.44  -15.37   43.62 1037.66 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  24.60285   18.05432   1.363 0.173585    
## areaconst     0.91612    0.04914  18.642  < 2e-16 ***
## banios       26.46739    4.98477   5.310 1.65e-07 ***
## F1           75.78409   19.48263   3.890 0.000114 ***
## F2          127.53363   18.64275   6.841 2.30e-11 ***
## F3          308.57370   30.99644   9.955  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 154 on 501 degrees of freedom
## Multiple R-squared:  0.6916, Adjusted R-squared:  0.6886 
## F-statistic: 224.7 on 5 and 501 DF,  p-value: < 2.2e-16

Estimando el modelo con el conjunto de datos de entretnamiento se mejora el coeficiente de determinación \(R^2\) a 69.16%.

6. Predicciones con el conjunto de prueba.

Utilizando los coeficientes de MODEL se estiman los precios de las casas de los 215 registros del conjunto Test.

precio_Py = round(predict(object = MODEL, newdata = Test), 1)
predicciones = data.frame(Test$preciom, precio_Py)
head(predicciones, 20)
##    Test.preciom precio_Py
## 1           780     579.7
## 2           600     352.8
## 3           420     441.2
## 4           230     224.1
## 5           190     423.1
## 6           180     213.9
## 7           520     701.3
## 8           485     499.4
## 9           390     558.6
## 10          680     599.3
## 11          800     692.9
## 12          700     763.1
## 13          620     643.8
## 14          790     753.9
## 15          750     499.8
## 16          600     646.0
## 17          280     344.7
## 18          460     786.2
## 19          600     561.3
## 20          850     849.3

7. Calcular e interpretar las medidas de desempeño del Modelo de Regresión Lineal Múltiple.

Error Cuadrático Medio RMSE

Se puede calcular el Error Cuadrático Medio con la siguiente ecuación:

sqrt(mean((Test$preciom - precio_Py)^2))
## [1] 164.8191

El Error Cuadrático Medio es una medida que indica, en promedio, que tan lejos están los precios de la predicción con respecto a los precios reales. El RMSE es una forma sencilla de ver qué tan bien el Modelo de Regresión Lineal Múltiple planteado MODEL: predecir los precios de las casas del norte de Cali en función del área construida, el número de baños y el estrato. En este caso se obtiene un valor alto de RMSE y se puede interpretar como un ajuste bajo, entre mayor sea el RMSE, mayor será la diferencia entre los precios de la predicción los precios reales de las casas.

Error Absoluto Medio MAE

Se puede calcular el Error Absoluto Medio con la siguiente ecuación:

sum(abs(Test$preciom - precio_Py))/215
## [1] 99.19302

El Error Absoluto Medio es el promedio de la diferencia entre los precios de las predicciones y el precio real de cada casa que se proyectó.

Coeficiente de Determinación \(R^2\)

El Coeficiente de Determinación \(R^2\)** mide que tanto se ajusta un modelo de regresión a los datos, en este caso, el \(R^2\) indica que las variables independientes incluidas en MODEL (área construida, numero de baños y estrato) explican en un 69.16% el comportamiento de los precios de las casas de la zona norte de Cali.