Actividad 2 - Caso C&A

Enunciado

Maria comenzó como agente de bienes raíces en Cali hace 10 años. Después de laborar dos años para una empresa nacional, se traslado a Bogotá y trabajó para otra agencia de bienes raíces. Sus amigos y familiares la convencieron de que con su experiencia y conocimientos del negocio debía abrir su propia agencia. Terminó por adquirir la licencia de intermediario y al poco tiempo fundó su propia compañía, C&A (Casas y Apartamentos) en Cali. Santiago y Lina, dos vendedores de la empresa anterior aceptaron trabajar en la nueva compaña. En la actualidad ocho agentes de bienes raíces colaboran con ella en C&A.

Actualmente las ventas de bienes raíces en Cali se han visto disminuidas de manera significativa en lo corrido del año. Durante este periodo muchas instituciones bancarias de ahorro y vivienda están prestando grandes sumas de dinero para la industria y la construcción comercial y residencial. Cuando el efecto producto de las tensiones políticas y sociales disminuya, se espera que la actividad económica de este sector se reactive.

Datos

Los datos de los tres últimos meses se adjuntan en la base que puede obtener con el siguiente código en R variable descripción

Datos
Variable Descripcion
zona ubicación de la vivienda : Zona Centro, Zona Norte,…
piso piso que ocupa la vivienda : primer piso, segundo piso…
estrato estrato socio-económico : 3,4,5,6
preciom precio de la vivienda en millones de pesos
areaconst área construida
parqueaderos número de parqueaderos
banios número de baños
habitaciones número de habitaciones
tipo tipo de vivienda : Casa, Apartamento
barrio barrio de ubicación de la vivienda : 20 de Julio, alamos,..
longitud coordenada geográfica
latitud coordenada geográfica

Actividad

  1. Realice un filtro a la base de datos e incluya solo las ofertas de : base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta.

  2. Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.

  3. Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

  4. Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

  5. Realice una partición en los datos de forma aleatoria donde 70% sea un set para entrenar el modelo y 30% para prueba. Estime el modelo con la muestra del 70%. Muestre los resultados.

  6. Realice predicciones con el modelo anterior usando los datos de prueba (30%).

  7. Calcule el error cuadrático medio, el error absoluto medio y el R2, interprete.

Setup

Instalacion de librerias y carga de datos

library(tidyverse) #Paquete usado para el tratamiento de datos
library(stringi) #Paquete para tratamiento de acentuacion de caracteres
library(dplyr) #Paquete para sintaxis de codigo
library(magrittr) #Paquete para sintaxis de codigo
library(Amelia) #Paquete usado para el tratamiento de datos faltantes
library(plotly)
library(caret)
library(fastDummies)
library(car)
library(GGally)
library(summarytools)
library(Metrics)
library(paqueteMODELOS)
library(dplyr)
library(skimr)
library(lmtest)
library(ggplot2)
library(reshape2)
library(mice)
library(factoextra)
library(dendextend)
library(FactoMineR)
library(psych)
data(vivienda)

Punto 1

  • Realice un filtro a la base de datos e incluya solo las ofertas de : base1: casas, de la zona norte de la ciudad. Presente los primeros 3 registros de las bases y algunas tablas que comprueben la consulta.
# Se verifican los valores en las columnas requeridas
unique(vivienda$zona)
## [1] "Zona Oriente" "Zona Sur"     "Zona Norte"   "Zona Oeste"   "Zona Centro" 
## [6] NA
unique(vivienda$tipo)
## [1] "Casa"        "Apartamento" NA
# Se crea la base de datos filtrada a casa de la zona norte
db <- filter(vivienda, zona == "Zona Norte" & tipo == "Casa")

# Se verifican los resultados del filtro
head(db,3)
## # A tibble: 3 × 13
##      id zona    piso  estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <chr>   <chr>   <dbl>   <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1  1209 Zona N… 02          5     320       150            2      4            6
## 2  1592 Zona N… 02          5     780       380            2      3            3
## 3  4057 Zona N… 02          6     750       445           NA      7            6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Tabla con el conteo de propiedades por zona, tipo y numero de pisos
tabla <- db %>%
  group_by(zona, tipo, piso) %>%
  summarise(count = n()) %>%
  ungroup()
## `summarise()` has grouped output by 'zona', 'tipo'. You can override using the
## `.groups` argument.
print(tabla)
## # A tibble: 6 × 4
##   zona       tipo  piso  count
##   <chr>      <chr> <chr> <int>
## 1 Zona Norte Casa  01       84
## 2 Zona Norte Casa  02      194
## 3 Zona Norte Casa  03       65
## 4 Zona Norte Casa  04        6
## 5 Zona Norte Casa  07        1
## 6 Zona Norte Casa  <NA>    372

Punto 2

  • Realice un análisis exploratorio de datos enfocado en la correlación entre la variable respuesta (precio de la casa) en función del área construida, estrato, numero de baños, numero de habitaciones y zona donde se ubica la vivienda. Use gráficos interactivos con el paquete plotly e interprete los resultados.

Tipo de variables y NA’s

skim(db)
Data summary
Name db
Number of rows 722
Number of columns 13
_______________________
Column type frequency:
character 4
numeric 9
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
zona 0 1.00 10 10 0 1 0
piso 372 0.48 2 2 0 5 0
tipo 0 1.00 4 4 0 1 0
barrio 0 1.00 4 25 0 103 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id 0 1.0 2574.65 1986.26 58.00 766.25 2257.00 4225.00 8319.00 ▇▃▃▂▁
estrato 0 1.0 4.20 0.98 3.00 3.00 4.00 5.00 6.00 ▇▅▁▇▂
preciom 0 1.0 445.91 268.36 89.00 261.25 390.00 550.00 1940.00 ▇▃▁▁▁
areaconst 0 1.0 264.85 167.17 30.00 140.00 240.00 336.75 1440.00 ▇▃▁▁▁
parqueaderos 287 0.6 2.18 1.40 1.00 1.00 2.00 3.00 10.00 ▇▂▁▁▁
banios 0 1.0 3.56 1.52 0.00 2.00 3.00 4.00 10.00 ▅▇▃▁▁
habitaciones 0 1.0 4.51 1.83 0.00 3.00 4.00 5.00 10.00 ▁▇▅▂▁
longitud 0 1.0 -76.52 0.02 -76.59 -76.53 -76.52 -76.50 -76.47 ▁▁▇▆▂
latitud 0 1.0 3.46 0.03 3.33 3.45 3.47 3.48 3.50 ▁▁▁▂▇

Como podemos observar, solo hay dos variables con valores faltantes (piso y parqueadero) por contexto se infiere que campos vacios en estos significa que la casa es de un solo piso y que no tiene parqueaderos, por lo que se reemplazaran con 1 y 0 respectivamente.

Adicionalmente es necesario corregir el tipo de variables para piso (de caracter a numerica) y el estrato a categorica ordinal. Para la variable estrato, se le aplicara encoding para crear columnas individuales para cada valor

# Reemplazo NA para piso y parqueadero

db$piso <- replace(db$piso, is.na(db$piso), 1)
db$parqueaderos <-
    replace(db$parqueaderos, is.na(db$parqueaderos), 0)

# Correccion de tipo de variable
db$piso <- as.numeric(db$piso)

# copia de db antes de declarar estrato como categorica 
df <- db

# Convertir variable estrato a categorica ordinal
db$estrato <- factor(db$estrato, levels = seq(min(db$estrato), max(db$estrato)))

skim(db)
Data summary
Name db
Number of rows 722
Number of columns 13
_______________________
Column type frequency:
character 3
factor 1
numeric 9
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
zona 0 1 10 10 0 1 0
tipo 0 1 4 4 0 1 0
barrio 0 1 4 25 0 103 0

Variable type: factor

skim_variable n_missing complete_rate ordered n_unique top_counts
estrato 0 1 FALSE 4 5: 271, 3: 235, 4: 161, 6: 55

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id 0 1 2574.65 1986.26 58.00 766.25 2257.00 4225.00 8319.00 ▇▃▃▂▁
piso 0 1 1.48 0.72 1.00 1.00 1.00 2.00 7.00 ▇▁▁▁▁
preciom 0 1 445.91 268.36 89.00 261.25 390.00 550.00 1940.00 ▇▃▁▁▁
areaconst 0 1 264.85 167.17 30.00 140.00 240.00 336.75 1440.00 ▇▃▁▁▁
parqueaderos 0 1 1.31 1.53 0.00 0.00 1.00 2.00 10.00 ▇▁▁▁▁
banios 0 1 3.56 1.52 0.00 2.00 3.00 4.00 10.00 ▅▇▃▁▁
habitaciones 0 1 4.51 1.83 0.00 3.00 4.00 5.00 10.00 ▁▇▅▂▁
longitud 0 1 -76.52 0.02 -76.59 -76.53 -76.52 -76.50 -76.47 ▁▁▇▆▂
latitud 0 1 3.46 0.03 3.33 3.45 3.47 3.48 3.50 ▁▁▁▂▇

Se consultan valores unicos de variables categoricas para identificar correcciones necesarias

columnas_categoricas = db %>%  select_if(is.character)
valores_unicos = sapply(columnas_categoricas, unique)
print(valores_unicos)
## $zona
## [1] "Zona Norte"
## 
## $tipo
## [1] "Casa"
## 
## $barrio
##   [1] "acopi"                     "alameda del río"          
##   [3] "alamos"                    "atanasio girardot"        
##   [5] "barranquilla"              "barrio tranquilo y"       
##   [7] "base aérea"               "berlin"                   
##   [9] "brisas de los"             "brisas del guabito"       
##  [11] "Cali"                      "calibella"                
##  [13] "calima"                    "calimio norte"            
##  [15] "cambulos"                  "centenario"               
##  [17] "chapinero"                 "chipichape"               
##  [19] "ciudad los álamos"         "colinas del bosque"       
##  [21] "cristales"                 "el bosque"                
##  [23] "el cedro"                  "el gran limonar"          
##  [25] "el guabito"                "el sena"                  
##  [27] "el tr√©bol"                "evaristo garcía"          
##  [29] "flora industrial"          "floralia"                 
##  [31] "gaitan"                    "granada"                  
##  [33] "jorge eliecer gaitán"      "juanamb√∫"                
##  [35] "la base"                   "la campiña"               
##  [37] "la esmeralda"              "la flora"                 
##  [39] "La Flora"                  "la floresta"              
##  [41] "la merced"                 "la rivera"                
##  [43] "la rivera i"               "la rivera ii"             
##  [45] "la riviera"                "la villa del"             
##  [47] "las acacias"               "las américas"            
##  [49] "las ceibas"                "las delicias"             
##  [51] "las granjas"               "los andes"                
##  [53] "los guaduales"             "los guayacanes"           
##  [55] "manzanares"                "menga"                    
##  [57] "metropolitano del norte"   "nueva tequendama"         
##  [59] "oasis de comfandi"         "occidente"                
##  [61] "pacara"                    "parque residencial el"    
##  [63] "paseo de los"              "paso del comercio"        
##  [65] "poblado campestre"         "popular"                  
##  [67] "portada de comfandi"       "portales de comfandi"     
##  [69] "porvenir"                  "prados del norte"         
##  [71] "quintas de salomia"        "rozo la torre"            
##  [73] "salomia"                   "san luís"                 
##  [75] "san luis"                  "san vicente"              
##  [77] "santa bárbara"             "santa mónica"             
##  [79] "santa mónica residencial"  "Santa Monica"             
##  [81] "santa monica"              "santa monica norte"       
##  [83] "santa monica residencial"  "santander"                
##  [85] "tejares de san"            "torres de comfandi"       
##  [87] "unión de vivienda"         "urbanización barranquilla"
##  [89] "urbanización la flora"     "urbanización la merced"   
##  [91] "urbanización la nueva"     "valle del lili"           
##  [93] "versalles"                 "villa colombia"           
##  [95] "villa de veracruz"         "villa del prado"          
##  [97] "Villa Del Prado"           "villa del sol"            
##  [99] "Villas De Veracruz"        "villas de veracruz"       
## [101] "vipasa"                    "zona norte"               
## [103] "zona oriente"
skim(df)
Data summary
Name df
Number of rows 722
Number of columns 13
_______________________
Column type frequency:
character 3
numeric 10
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
zona 0 1 10 10 0 1 0
tipo 0 1 4 4 0 1 0
barrio 0 1 4 25 0 103 0

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
id 0 1 2574.65 1986.26 58.00 766.25 2257.00 4225.00 8319.00 ▇▃▃▂▁
piso 0 1 1.48 0.72 1.00 1.00 1.00 2.00 7.00 ▇▁▁▁▁
estrato 0 1 4.20 0.98 3.00 3.00 4.00 5.00 6.00 ▇▅▁▇▂
preciom 0 1 445.91 268.36 89.00 261.25 390.00 550.00 1940.00 ▇▃▁▁▁
areaconst 0 1 264.85 167.17 30.00 140.00 240.00 336.75 1440.00 ▇▃▁▁▁
parqueaderos 0 1 1.31 1.53 0.00 0.00 1.00 2.00 10.00 ▇▁▁▁▁
banios 0 1 3.56 1.52 0.00 2.00 3.00 4.00 10.00 ▅▇▃▁▁
habitaciones 0 1 4.51 1.83 0.00 3.00 4.00 5.00 10.00 ▁▇▅▂▁
longitud 0 1 -76.52 0.02 -76.59 -76.53 -76.52 -76.50 -76.47 ▁▁▇▆▂
latitud 0 1 3.46 0.03 3.33 3.45 3.47 3.48 3.50 ▁▁▁▂▇

Analisis Grafico de Variables

Distribucion de preciom

shapiro.test(db$preciom)
## 
##  Shapiro-Wilk normality test
## 
## data:  db$preciom
## W = 0.86297, p-value < 2.2e-16
plot_ly(db, x = ~preciom, type = "histogram")%>%
  layout(title = "Distribucion de preciom")

Como se puede deducir por los resultados del test de shapiro, la variable preciom no tiene una distribucion normal

Precio vs caracteristicas de inmuebles

# precio vs Estrato
plot_ly(data = db, x = ~preciom, y = ~estrato, type = 'box', orientation = 'h') %>%
 layout(title = 'Precio vs Estrato')
# precio vs piso
plot_ly(data = db, x = ~preciom, y = ~piso, type = 'box', orientation = 'h') %>%
 layout(title = 'Precio vs Piso')
# precio vs habitaciones

plot_ly(db, x = ~preciom, y = ~habitaciones, type = "box", orientation = 'h')%>%
  layout(title = "Precio vs habitaciones")
# precio vs banios
plot_ly(db, x = ~preciom, y = ~banios, type = "box", orientation = 'h')%>%
  layout(title = "Precio vs banios")
# precio vs banios
plot_ly(db, x = ~preciom, y = ~parqueaderos, type = "box", orientation = 'h')%>%
  layout(title = "Precio vs banios")
#precio vs area
plot_ly(db, x = ~preciom, y = ~areaconst, color = ~estrato, type = )%>%layout(title = "Precio vs area")

Basados en un analisis graficio inicial, podemos inferir que el estrato y el area tienen una correlacion positiva con el precio, mientras que variables como banios, piso, habitaciones o parqueaderos, tienen una relacion mucho mas leve o casi nula respectivamente. Se requerira realizar un analisis de correlacion para ver el impacto real de cada variable

Correlaciones

La correlacion se calculara con el dataset df en lugar de db para poder calcular la correlacion con la variable estrato de manera mas sencilla

corr=df[,c("preciom","areaconst","estrato","banios","habitaciones", "parqueaderos")]
(ggpairs(corr))

La grafica de correlaciones verifica las inferencias que se habian hecho con las graficas, hay una fuerte correlacion entre preciom y areaconst y estrato, banios tiene una correlacion positiva y habitaciones/parqueadero tienen una correlacion mucho mas baja.

Punto 3

  • Estime un modelo de regresión lineal múltiple con las variables del punto anterior (precio = f(área construida, estrato, número de cuartos, número de parqueaderos, número de baños ) ) e interprete los coeficientes si son estadísticamente significativos. Las interpretaciones deber están contextualizadas y discutir si los resultados son lógicos. Adicionalmente interprete el coeficiente R2 y discuta el ajuste del modelo e implicaciones (que podrían hacer para mejorarlo).

Normalizacion

Antes de construir el modelo, se realizara la normalizacion de las variables continuas para que todas queden en escalas similares.

nm = preProcess(db, method = "range")

db_nm = predict(nm,db)

head(db_nm)
## # A tibble: 6 × 13
##      id zona     piso estrato preciom areaconst parqueaderos banios habitaciones
##   <dbl> <chr>   <dbl> <fct>     <dbl>     <dbl>        <dbl>  <dbl>        <dbl>
## 1 0.139 Zona N… 0.167 5         0.125    0.0851          0.2    0.4          0.6
## 2 0.186 Zona N… 0.167 5         0.373    0.248           0.2    0.3          0.3
## 3 0.484 Zona N… 0.167 6         0.357    0.294           0      0.7          0.6
## 4 0.533 Zona N… 0.167 4         0.290    0.230           0.3    0.5          0.5
## 5 0.729 Zona N… 0.167 5         0.357    0.147           0.2    0.6          0.6
## 6 0.940 Zona N… 0.167 4         0.276    0.0922          0.1    0.4          0.5
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>

Modelo

Ahora se procede a construir el modelo con la base de datos normalizada con estimacion paso a paso

# se define el modelo  ingenuo  y= b0
modelo_b0 <- lm(preciom ~ 1, data = db_nm)

#define model with all predictors
modelo_all <- lm(preciom ~ areaconst + estrato + habitaciones + banios, data = db_nm)

# Se aplica el proceso forward stepwise regression
forward <-
    step(
        modelo_b0,
        direction = 'forward',
        scope = formula(modelo_all),
        trace = 0
    )

# Visualización de los resultados
forward$anova
##          Step Df  Deviance Resid. Df Resid. Dev       AIC
## 1             NA        NA       721  15.155592 -2787.559
## 2 + areaconst -1 8.1062698       720   7.049322 -3338.206
## 3   + estrato -3 1.6524931       717   5.396829 -3525.066
## 4    + banios -1 0.2596723       716   5.137157 -3558.669
summary(forward)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios, data = db_nm)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.52338 -0.03951 -0.00883  0.02446  0.57754 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -0.016267   0.008280  -1.964   0.0499 *  
## areaconst    0.632884   0.031820  19.889  < 2e-16 ***
## estrato4     0.045537   0.009129   4.988 7.66e-07 ***
## estrato5     0.074512   0.008500   8.766  < 2e-16 ***
## estrato6     0.177094   0.013953  12.693  < 2e-16 ***
## banios       0.146421   0.024339   6.016 2.85e-09 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.0847 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

Como podemos ver, el modelo explica un 66% de los datos, adicionalmente el p-value siendo altamente significativo en contra de la hipotesis nula, nos permite afirmar que al menos uno de los valores tiene impacto en el precio.

A pesar de que 66% de la variabilidad es un numero aceptable, se podria mejorar agregando variables adicionales como el numero de pisos o el barrio. De contar con mas informacion como si es una vivienda independiente o parte de un conjunto cerrado, instalaciones adicionales como parques, piscinas, etc. se podria obtener una R2 mas elevada.

Lamentablemente al haber normalizado los valores, se pierde interpretabilidad en cuanto al incremento/impacto de cada variable en unidades “reales”.

Punto 4

  • Realice la validación de supuestos del modelo e interprete los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).

Linealidad

par(mfrow = c(2, 2)) 
plot(forward)

La dispersion aleatoria alrededor de 0 en el grafico de Residuals vs Fitted, nos indica que no hay problemas con la linealidad del modelo.

Normalidad

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

El resultado del test shapiro indica una evidencia extremadamente fuerte en contra de la hipótesis nula y sugiere que los datos no siguen una distribución normal. Esto en cierta forma es esperado puesto que al observar al inicio del ejercicio se observo que el precio no tiene una distribucion normal.

Dado que no tenemos mas variables disponibles para ussar, una alternativa podria ser realizar transformaciones sobre las variables

Varianza Constante

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

Este resultado en la prueba de Breush-Pagan, indica que hay una fuerte evidencia en contra de la homocedasticidad en el modelo. En otras palabras, la varianza de los errores no es constante a lo largo del rango de los valores ajustados. Para intentar solucionarlo, se deben considerar técnicas de corrección o modelos alternativos que puedan manejar la variación no constante de la varianza.

Multicolinealidad

Para evaluar la multicolinealidad se utilizara el Factor de Inflación de la Varianza o VIF

vif(forward)
##               GVIF Df GVIF^(1/(2*Df))
## areaconst 1.430202  1        1.195910
## estrato   1.376739  3        1.054732
## banios    1.382317  1        1.175720

Como podemos ver, las variables presentan un VIF de entre 1 y 5, este rango se considera aceptable y no se presentarian problemas significativos por lo que no es necesario realizar ninguna correccion

Punto 5

  • Realice una partición en los datos de forma aleatoria donde 70% sea un set para entrenar el modelo y 30% para prueba. Estime el modelo con la muestra del 70%. Muestre los resultados.

Particion

set.seed(1)  
train_db <- createDataPartition(y = db_nm$preciom,
                                            p = 0.7,
                                            list = FALSE)
train <- db_nm[train_db,]
test <- db_nm[-train_db,]

# Validacion de particion para el df de training
nrow(train)/nrow(db_nm)*100
## [1] 70.22161

Modelo

# se define el modelo  ingenuo  y= b0
modelo_b0_train <- lm(preciom ~ 1, data = train)

#define model with all predictors
modelo_all_train <- lm(preciom ~ areaconst + estrato + habitaciones + banios, data = train)

# Se aplica el proceso forward stepwise regression
forward_train <-
    step(
        modelo_b0_train,
        direction = 'forward',
        scope = formula(modelo_all_train),
        trace = 0
    )

# Visualización de los resultados
forward_train$anova
##          Step Df  Deviance Resid. Df Resid. Dev       AIC
## 1             NA        NA       506  11.295638 -1926.676
## 2 + areaconst -1 5.9059935       505   5.389645 -2299.824
## 3   + estrato -3 1.2813812       502   4.108263 -2431.464
## 4    + banios -1 0.1849877       501   3.923276 -2452.823
summary(forward_train)
## 
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios, data = train)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.52156 -0.04043 -0.00759  0.02562  0.57968 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -0.01613    0.01030  -1.566 0.117981    
## areaconst    0.62957    0.03804  16.550  < 2e-16 ***
## estrato4     0.04325    0.01125   3.846 0.000136 ***
## estrato5     0.07605    0.01068   7.119 3.78e-12 ***
## estrato6     0.18317    0.01715  10.680  < 2e-16 ***
## banios       0.14981    0.03082   4.860 1.57e-06 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.08849 on 501 degrees of freedom
## Multiple R-squared:  0.6527, Adjusted R-squared:  0.6492 
## F-statistic: 188.3 on 5 and 501 DF,  p-value: < 2.2e-16

Como podemos ver, el R2 baja en un 1% con respecto a entrenamiento con el dataset completo

Punto 6

  • Realice predicciones con el modelo anterior usando los datos de prueba (30%).
prediccion <- predict(forward_train, newdata = test, type = "response")
db_predict <- data.frame(test$preciom, prediccion)


head(db_predict)
##   test.preciom prediccion
## 1   0.12479741 0.17343104
## 2   0.05456510 0.16470926
## 3   0.04916261 0.06900372
## 4   0.11669368 0.11091171
## 5   0.15721232 0.25538833
## 6   0.09778498 0.16277006
plot_ly(db_predict, x=~test.preciom, y=~prediccion) %>% layout(title="test.preciom vs prediccion - Normalizado")
## No trace type specified:
##   Based on info supplied, a 'scatter' trace seems appropriate.
##   Read more about this trace type -> https://plotly.com/r/reference/#scatter
## No scatter mode specifed:
##   Setting the mode to markers
##   Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode

Punto 7

  • Calcule el error cuadrático medio, el error absoluto medio y el R2, interprete.
# Calcular el error cuadrático medio (MSE)
mse <- mean((test$preciom-prediccion)^2)

# Calcular el error absoluto medio (MAE)
mae <- mae(test$preciom, prediccion)

# Calcular R^2
r_squared <- cor(test$preciom, prediccion)^2

# Imprimir los resultados
print(paste("variable respuesta promedio - test:", mean(test$preciom)))
## [1] "variable respuesta promedio - test: 0.189793072255098"
print(paste("prediccion promedio:", mean(prediccion)))
## [1] "prediccion promedio: 0.194245294367316"
print(paste("Error cuadrático medio (MSE):", mse))
## [1] "Error cuadrático medio (MSE): 0.00566793128112028"
print(paste("Error absoluto medio (MAE):", mae))
## [1] "Error absoluto medio (MAE): 0.0493990005971985"
print(paste("R^2:", r_squared))
## [1] "R^2: 0.685974287234246"

Teniendo en cuenta que el valor promedio de la variable respuesta, el MSE y MAE calculados tienen un resultado considerablemente bajo, esto en combinacion con un R^2 de 0.68 nos dice que el modelo tiene un buen ajuste a los datos y explica una buena porcion de la variabilidad en la variable respuesta.