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)
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
Datos$Zona <- as.factor(Datos$Zona)
levels(Datos$Zona)
## [1] "Zona Centro" "Zona Norte" "Zona Oeste" "Zona Oriente" "Zona Sur"
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 ...
str(Datos$Estrato)
## num [1:8322] 6 4 5 6 6 6 6 5 4 6 ...
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 ...
Datos$Tipo <- as.factor(Datos$Tipo)
levels(Datos$Tipo)
## [1] "Apartamento" "Casa"
Datos$Barrio <- as.factor(Datos$Barrio)
sum(is.na(Datos$piso))
## [1] 2638
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.
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.
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.
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
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
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
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
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