library(readxl)
library(tidyverse)
library(readxl)
Datos <- read_excel("YDRAY-Datos_Vivienda.xlsx")
attach(Datos)
library(corrplot)

El objetivo de realizar la regresión lineal múltiple es encontrar la relación que existe entre las variables con el precio por millon de la viviendo (Variable respuesta)

Análisis exploratorio de variables

Descripcion del tipo de variables presentes en la base de datos.

Para generar modelos de regresión lineal múltiple, es necesario contar con variables numéricas y dummies.

Variables Dummy:

Variables númericas:

str(Datos)    
## tibble [8,322 × 12] (S3: tbl_df/tbl/data.frame)
##  $ Zona              : chr [1:8322] "Zona Sur" "Zona Oeste" "Zona Sur" "Zona Sur" ...
##  $ piso              : chr [1:8322] "2" "2" "3" "NA" ...
##  $ Estrato           : num [1:8322] 6 4 5 6 6 6 6 5 4 6 ...
##  $ precio_millon     : num [1:8322] 880 1200 250 1280 1300 513 870 310 240 690 ...
##  $ Area_contruida    : num [1:8322] 237 800 86 346 600 160 490 82.5 80 150 ...
##  $ parqueaderos      : chr [1:8322] "2" "3" "NA" "4" ...
##  $ Banos             : num [1:8322] 5 6 2 6 7 4 6 2 2 5 ...
##  $ Habitaciones      : num [1:8322] 4 7 3 5 5 4 5 3 3 4 ...
##  $ Tipo              : chr [1:8322] "Casa" "Casa" "Apartamento" "Apartamento" ...
##  $ Barrio            : chr [1:8322] "pance" "miraflores" "multicentro" "ciudad jardín" ...
##  $ cordenada_longitud: num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
##  $ Cordenada_latitud : num [1:8322] 3.43 3.43 3.43 3.43 3.43 ...
Datos$cordenada_longitud <- NULL
Datos$Cordenada_latitud <- NULL

Algunas variables requeridas para el análisis no cumplen con los criterios necesarios para implementarlas en el modelo. Se procede a modificar estás variable

Zona

Datos$Zona <- as.factor(Datos$Zona)
levels(Datos$Zona)
## [1] "Zona Centro"  "Zona Norte"   "Zona Oeste"   "Zona Oriente" "Zona Sur"

Piso

Datos$piso <- replace(Datos$piso,  Datos$piso == "NA",   NA)
Datos$piso <- as.numeric(Datos$piso)
str(Datos$piso)
##  num [1:8322] 2 2 3 NA 2 3 2 5 9 6 ...

Estrato

str(Datos$Estrato)
##  num [1:8322] 6 4 5 6 6 6 6 5 4 6 ...

Parqueaderos

Datos$parqueaderos <- replace(Datos$parqueaderos, Datos$parqueaderos == "NA", NA )
Datos$parqueaderos <- as.numeric(Datos$parqueaderos)
str(Datos$parqueaderos)
##  num [1:8322] 2 3 NA 4 4 2 3 1 1 2 ...

Tipo

Datos$Tipo <- as.factor(Datos$Tipo)
levels(Datos$Tipo)
## [1] "Apartamento" "Casa"

Barrio

Datos$Barrio <- as.factor(Datos$Barrio)

sum(is.na(Datos$piso))
## [1] 2638

Valores Faltantes.

library(dplyr)
ValoresFaltantes <- map_dbl(Datos ,.f = function(x) sum(is.na(x)))
knitr::kable(ValoresFaltantes,col.names = "Valores faltantes")
Valores faltantes
Zona 3
piso 2638
Estrato 3
precio_millon 2
Area_contruida 3
parqueaderos 1605
Banos 3
Habitaciones 3
Tipo 3
Barrio 3

La variable piso tiene aproximadamente un 30 % de valores faltantes y paequeaderos un 18%.

Datos_long <- Datos %>% gather(key = "variable", value = "valor")
## Warning: attributes are not identical across measure variables;
## they will be dropped
Datos_long %>% group_by(variable) %>% 
  summarise( NaPorcentaje = sort((sum(is.na(valor))/length(valor))*100)) %>% 
  ggplot(aes(y=reorder(variable, (NaPorcentaje)) ,x=NaPorcentaje)) + geom_col() + ylab("Porcentaje de Na")

Determinamos si son datos faltantes aleatorios, completamente aleatorios o no aleatorios

DatosNa <- Datos %>%  filter(is.na(piso)) 

DatosNa[sample(nrow(DatosNa),20),]
## # A tibble: 20 × 10
##    Zona          piso Estrato precio_millon Area_contruida parqueaderos Banos
##    <fct>        <dbl>   <dbl>         <dbl>          <dbl>        <dbl> <dbl>
##  1 Zona Sur        NA       6           430            108            2     3
##  2 Zona Norte      NA       3           120             60           NA     2
##  3 Zona Sur        NA       3           580            450            4     4
##  4 Zona Norte      NA       5           350             85            1     2
##  5 Zona Sur        NA       4           149             60            1     2
##  6 Zona Oeste      NA       3           129             56           NA     2
##  7 Zona Sur        NA       6          1800            850            6     6
##  8 Zona Oeste      NA       6           800            310            2     4
##  9 Zona Norte      NA       4           190             78            1     2
## 10 Zona Sur        NA       3           148             87           NA     0
## 11 Zona Oriente    NA       3           310            340            1     2
## 12 Zona Sur        NA       6           650            164            2     5
## 13 Zona Sur        NA       4           125             47           NA     1
## 14 Zona Norte      NA       3           120             53           NA     1
## 15 Zona Sur        NA       5           270            121            1     2
## 16 Zona Oeste      NA       6           490            180            1     2
## 17 Zona Oeste      NA       5           330            112            2     4
## 18 Zona Sur        NA       4           365            145            3     3
## 19 Zona Norte      NA       5           850            525            1     4
## 20 Zona Sur        NA       4           135             48            1     1
## # … with 3 more variables: Habitaciones <dbl>, Tipo <fct>, Barrio <fct>

Podemos observar que los datos faltantes de piso se dan de forma aleatoria. De esta manera podemos realizar un modelo con datos imputados y analizar como se comporta este.

Correlación entre variables.

Númericas

a <-  Datos %>% na.omit() %>%select_if(is.numeric)
b<-cor(na.omit(a))
corrplot(b,type = "full",method = "number")

Las variables que tienen mayor correlacion con el Precio son Area_construida, parqueaderos, Baños.

Dummy

q1 <- ggplot(Datos,aes(x=Datos$Area_contruida,y=Datos$precio_millon, color =Zona))+
  geom_point(alpha=0.5,na.rm = T) + ggtitle("Precio vs Area") +
  xlab("Area construida") + ylab("Precio por millon") 
q1
## Warning: Use of `Datos$Area_contruida` is discouraged. Use `Area_contruida`
## instead.
## Warning: Use of `Datos$precio_millon` is discouraged. Use `precio_millon`
## instead.

Se puede concluir respecto al gráfico de dispersión que el precio aumenta a medida que aumenta el área construida, y el precio también aumenta respecto a la zona en donde fue construida.

q2 <- ggplot(Datos,aes(y=Datos$Area_contruida,x = as.factor(Estrato) ))+
  geom_boxplot(alpha=0.5) + ggtitle("Precio vs Area") +
  xlab("Estrato") + ylab("Precio por millon") 
q2
## Warning: Use of `Datos$Area_contruida` is discouraged. Use `Area_contruida`
## instead.
## Warning: Removed 3 rows containing non-finite values (stat_boxplot).

Se podría pensar que a mayor estrato mayor es el precio de la viviendo, puesto que las medias crecen a medida que aumenta el estrato, a excepción del estrato 4.

Tambien se observan valores atipicos, lo cual podriamos considerarlo normal, pues el precio de la viviendo no solo depende del estrato, existen otras variables que explican el precio.

Partición de los datos (test y trainign)

library(caret)
set.seed(123)
particion <- createDataPartition(y =na.omit(Datos$precio_millon) , p = 0.8,list = F )
DatosTraining <- Datos[particion,]
DatosTraining$piso <- as.factor(DatosTraining$piso)
DatosTraining$Barrio <- NULL


DatosTest <- Datos[-particion,]
DatosTest$piso <- as.factor(DatosTest$piso)
DatosTest$Barrio <- NULL

Creacion de modelos.

Modelo 1. (Todas las variables)

modelo1 <- lm(data = DatosTraining , formula = precio_millon ~ .)
summary(modelo1)
## 
## Call:
## lm(formula = precio_millon ~ ., data = DatosTraining)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -839.57  -80.29   -8.87   56.38  991.09 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      -219.34318   34.09170  -6.434 1.40e-10 ***
## ZonaZona Norte   -111.36126   30.93824  -3.599 0.000323 ***
## ZonaZona Oeste     16.57031   31.91313   0.519 0.603629    
## ZonaZona Oriente  -63.92935   34.79137  -1.838 0.066212 .  
## ZonaZona Sur      -95.01494   30.64382  -3.101 0.001945 ** 
## piso2             -36.38909    9.05465  -4.019 5.96e-05 ***
## piso3             -34.11580    9.44494  -3.612 0.000308 ***
## piso4             -43.93791   10.97761  -4.003 6.39e-05 ***
## piso5             -32.78432   11.62888  -2.819 0.004839 ** 
## piso6             -30.52462   14.44590  -2.113 0.034662 *  
## piso7             -11.82107   15.75206  -0.750 0.453032    
## piso8              15.10917   15.39264   0.982 0.326366    
## piso9              37.84427   17.37192   2.178 0.029431 *  
## piso10             18.76953   18.69384   1.004 0.315418    
## piso11              2.22127   22.63168   0.098 0.921819    
## piso12              6.32801   21.87777   0.289 0.772410    
## Estrato            78.84637    3.84052  20.530  < 2e-16 ***
## Area_contruida      0.88537    0.02954  29.969  < 2e-16 ***
## parqueaderos       74.90367    3.26030  22.974  < 2e-16 ***
## Banos              62.39291    3.30511  18.878  < 2e-16 ***
## Habitaciones      -23.63249    2.86989  -8.235 2.44e-16 ***
## TipoCasa          -25.22350    8.72192  -2.892 0.003850 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 163.4 on 3856 degrees of freedom
##   (2779 observations deleted due to missingness)
## Multiple R-squared:  0.7545, Adjusted R-squared:  0.7532 
## F-statistic: 564.5 on 21 and 3856 DF,  p-value: < 2.2e-16
DatosTest$predic <- predict(object = modelo1 , newdata = DatosTest)
library(MLmetrics)
## 
## Attaching package: 'MLmetrics'
## The following objects are masked from 'package:caret':
## 
##     MAE, RMSE
## The following object is masked from 'package:base':
## 
##     Recall
Datos12 <- na.omit(DatosTest)

RMSE(Datos12$precio_millon , Datos12$predic )
## [1] 159.1439

Modelo 2. (variables númericas)

modelo2 <- lm(data = DatosTraining, formula = precio_millon ~ Area_contruida + parqueaderos + Habitaciones + Estrato )
DatosTest$predic2 <- predict(modelo2, newdata = DatosTest)
DatosTest12 <- na.omit(DatosTest) 

RMSE(DatosTest12$precio_millon,DatosTest12$predic2)
## [1] 170.6468

Modelo 3 (Area construida + Zona + Estrato)

modelo3 <- lm(data = DatosTraining, formula = precio_millon ~ Area_contruida + Zona + Estrato)
DatosTest$predic3 <- predict(object = modelo3 ,newdata = DatosTest)
DatosTest13 <- na.omit(DatosTest)
RMSE(DatosTest13$predic3,DatosTest13$precio_millon)
## [1] 178.3948

Modelo 4

modelo4 <- lm(formula = precio_millon ~ Zona + piso + Estrato + Area_contruida + 
    parqueaderos + Banos + Habitaciones + Tipo, data = DatosTraining)
summary(modelo4)
## 
## Call:
## lm(formula = precio_millon ~ Zona + piso + Estrato + Area_contruida + 
##     parqueaderos + Banos + Habitaciones + Tipo, data = DatosTraining)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -839.57  -80.29   -8.87   56.38  991.09 
## 
## Coefficients:
##                    Estimate Std. Error t value Pr(>|t|)    
## (Intercept)      -219.34318   34.09170  -6.434 1.40e-10 ***
## ZonaZona Norte   -111.36126   30.93824  -3.599 0.000323 ***
## ZonaZona Oeste     16.57031   31.91313   0.519 0.603629    
## ZonaZona Oriente  -63.92935   34.79137  -1.838 0.066212 .  
## ZonaZona Sur      -95.01494   30.64382  -3.101 0.001945 ** 
## piso2             -36.38909    9.05465  -4.019 5.96e-05 ***
## piso3             -34.11580    9.44494  -3.612 0.000308 ***
## piso4             -43.93791   10.97761  -4.003 6.39e-05 ***
## piso5             -32.78432   11.62888  -2.819 0.004839 ** 
## piso6             -30.52462   14.44590  -2.113 0.034662 *  
## piso7             -11.82107   15.75206  -0.750 0.453032    
## piso8              15.10917   15.39264   0.982 0.326366    
## piso9              37.84427   17.37192   2.178 0.029431 *  
## piso10             18.76953   18.69384   1.004 0.315418    
## piso11              2.22127   22.63168   0.098 0.921819    
## piso12              6.32801   21.87777   0.289 0.772410    
## Estrato            78.84637    3.84052  20.530  < 2e-16 ***
## Area_contruida      0.88537    0.02954  29.969  < 2e-16 ***
## parqueaderos       74.90367    3.26030  22.974  < 2e-16 ***
## Banos              62.39291    3.30511  18.878  < 2e-16 ***
## Habitaciones      -23.63249    2.86989  -8.235 2.44e-16 ***
## TipoCasa          -25.22350    8.72192  -2.892 0.003850 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 163.4 on 3856 degrees of freedom
##   (2779 observations deleted due to missingness)
## Multiple R-squared:  0.7545, Adjusted R-squared:  0.7532 
## F-statistic: 564.5 on 21 and 3856 DF,  p-value: < 2.2e-16