1. Introducción

El siguiente informe se ejecuta un análisis de viviendas y modelos de regresión linea multiple para la compañía C&A, con el objetivo de responder a una solicitud de asesoría para la compra de dos viviendas por parte de una compañía internacional. Este documento se divide en las secciones: Introducción, objetivos, métodos, resultados, conclusiones.

2. Objetivo

  • Realizar recomendaciones de compra de vivida para dos casos requeridos por una compañía internacional.

3. Métodos

Este informe realiza un análisis de la información suministrada por la empresa B&C, para lo cual se realizan los siguientes pasos para cada escenario/caso de vivienda: 1) Filtrar la base de datos, 2) exploración y entendimiento del dataframe, 3) Estimación de un modelo de regresión lineal con múltiples variables, 4) validación de supuestos e interpretación de resultados, 5) predicción de precio de vivienda, 6) reportar ofertas.

Importación de información

# install.packages("devtools") # solo la primera vez
# devtools::install_github("dgonxalex80/paqueteMODELOS", force =TRUE)
library(paqueteMODELOS)
data("vivienda")
head(vivienda)

Notando que la tabla se encuentra conformada por 13 columnas: id, zona, piso, estrato, preciom, areaconst, parqueaderos, banios, habitaciones, tipo, barrio, longitud y latitud. Se requiere entonces conocer que tipo de información se encuentra almacenada en estas columnas, obteniendo entonces la tabla a continuación.

str(vivienda,vec.len=2, digits.d=2, give.attr=FALSE)
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ id          : num [1:8322] 1147 1169 ...
##  $ zona        : chr [1:8322] "Zona Oriente" "Zona Oriente" ...
##  $ piso        : chr [1:8322] NA NA ...
##  $ estrato     : num [1:8322] 3 3 3 4 5 ...
##  $ preciom     : num [1:8322] 250 320 350 400 260 ...
##  $ areaconst   : num [1:8322] 70 120 220 280 90 ...
##  $ parqueaderos: num [1:8322] 1 1 2 3 1 ...
##  $ banios      : num [1:8322] 3 2 2 5 2 ...
##  $ habitaciones: num [1:8322] 6 3 4 3 3 ...
##  $ tipo        : chr [1:8322] "Casa" "Casa" ...
##  $ barrio      : chr [1:8322] "20 de julio" "20 de julio" ...
##  $ longitud    : num [1:8322] -77 -77 ...
##  $ latitud     : num [1:8322] 3.4 3.4 ...

Como se pudo observar la información se divide en cadenas de texto y numeros de la siguiente forma:

  1. Character: zona, piso, tipo, barrio
  2. Numeric: id, estrato, preciom, areaconst, parqueaderos, banios, habitaciones, longitud, latitud

Adicionalmente se identifica que hay 8322 registros, definiendo que cada registro es una fila de la tabla con 13 atributos que lo componen.

Durante esta revisión se identifican varios valores nulos en las columnas, por lo cual se preprocesara esta información. En la siguiente matriz se puede visualizar los valores nulos por columnas, identificando que hay lineas/registros con todas las columnas vacias, las cuales pueden ser removidas sin generar afectacion en el analisis, para esto se genera un nuevo dataframe llamada “df”.

require(mice)
require(VIM)
md.pattern(vivienda, plot=TRUE, rotate.names=TRUE)

##      preciom id zona estrato areaconst banios habitaciones tipo barrio longitud
## 4808       1  1    1       1         1      1            1    1      1        1
## 1909       1  1    1       1         1      1            1    1      1        1
## 876        1  1    1       1         1      1            1    1      1        1
## 726        1  1    1       1         1      1            1    1      1        1
## 1          1  0    0       0         0      0            0    0      0        0
## 2          0  0    0       0         0      0            0    0      0        0
##            2  3    3       3         3      3            3    3      3        3
##      latitud parqueaderos piso     
## 4808       1            1    1    0
## 1909       1            1    0    1
## 876        1            0    1    1
## 726        1            0    0    2
## 1          0            0    0   12
## 2          0            0    0   13
##            3         1605 2638 4275
df <- vivienda[rowSums(is.na(vivienda)) != ncol(vivienda), ]

Al revisar el nuevo dataframe (df) observamos que existe una fila con dato en una sola columna, debido a que porcentualmente no se espera una alteracion importante en el analisis, esta fila tambien se decide retirar.

md.pattern(df, plot=TRUE, rotate.names=TRUE)

##      preciom id zona estrato areaconst banios habitaciones tipo barrio longitud
## 4808       1  1    1       1         1      1            1    1      1        1
## 1909       1  1    1       1         1      1            1    1      1        1
## 876        1  1    1       1         1      1            1    1      1        1
## 726        1  1    1       1         1      1            1    1      1        1
## 1          1  0    0       0         0      0            0    0      0        0
##            0  1    1       1         1      1            1    1      1        1
##      latitud parqueaderos piso     
## 4808       1            1    1    0
## 1909       1            1    0    1
## 876        1            0    1    1
## 726        1            0    0    2
## 1          0            0    0   12
##            1         1603 2636 4249
df <- df[-8320,]
md.pattern(df, plot=TRUE, rotate.names=TRUE)

##      id zona estrato preciom areaconst banios habitaciones tipo barrio longitud
## 4808  1    1       1       1         1      1            1    1      1        1
## 1909  1    1       1       1         1      1            1    1      1        1
## 876   1    1       1       1         1      1            1    1      1        1
## 726   1    1       1       1         1      1            1    1      1        1
##       0    0       0       0         0      0            0    0      0        0
##      latitud parqueaderos piso     
## 4808       1            1    1    0
## 1909       1            1    0    1
## 876        1            0    1    1
## 726        1            0    0    2
##            0         1602 2635 4237

Se observa que piso y parqueaderos poseen un alto volumen de datos faltantes, sin embargo posterior a los filtros de búsqueda por tipo de vivienda se definirá cual es el posible tratamiento de datos a seguir.

unique_counts <- sapply(df, function(x) length(unique(x, na.rm = TRUE)))

# Print the results
print(unique_counts)
##           id         zona         piso      estrato      preciom    areaconst 
##         8319            5           13            4          539          652 
## parqueaderos       banios habitaciones         tipo       barrio     longitud 
##           11           11           11            2          436         2928 
##      latitud 
##         3679

Durante la revisión de datos se identifica que los siguientes atributos: zona, piso, estrato, parqueaderos, banios, habitaciones, tipo, barrio toman valores categóricos, y el numero de categorías para cada uno se describe a continuación:

sort(table(df$zona), decreasing = TRUE)
## 
##     Zona Sur   Zona Norte   Zona Oeste Zona Oriente  Zona Centro 
##         4726         1920         1198          351          124
print("Zonas")
## [1] "Zonas"
sort(table(df$piso), decreasing = TRUE)
## 
##   02   03   01   04   05   06   08   07   09   10   11   12 
## 1450 1097  860  607  567  245  211  204  146  130   84   83
print("Piso")
## [1] "Piso"
sort(table(df$estrato), decreasing = TRUE)
## 
##    5    4    6    3 
## 2750 2129 1987 1453
print("Estrato")
## [1] "Estrato"
sort(table(df$parqueaderos), decreasing = TRUE)
## 
##    1    2    3    4    5    6    7    8   10    9 
## 3155 2475  520  384   68   68   18   17    8    4
print("Parqueaderos")
## [1] "Parqueaderos"
sort(table(df$banios), decreasing = TRUE)
## 
##    2    3    4    5    1    6    7    8    0    9   10 
## 2946 1993 1456  890  496  314  107   48   45   15    9
print("Baños")
## [1] "Baños"
sort(table(df$habitaciones), decreasing = TRUE)
## 
##    3    4    2    5    6    7    8    9    0    1   10 
## 4097 1729  926  679  318  173  138   83   66   59   51
print("Habitaciones")
## [1] "Habitaciones"
sort(table(df$tipo), decreasing = TRUE)
## 
## Apartamento        Casa 
##        5100        3219
print("Tipos de vivienda")
## [1] "Tipos de vivienda"

3.1 Vivienda tipo 1

Paso 1: filtro de base de datos

Enunciado: 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. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?)

base1=df[df$zona=="Zona Norte" & df$tipo=="Casa",]
head(base1,3)

A continuación se realiza una tabla de información descriptiva de este filtro para reconocer la información de manera preliminar y confirmando que el filtro fue funcional y solo posee datos de casas ubicadas en la zona norte.

require(table1)
table1(~ estrato + zona + preciom + areaconst + parqueaderos + banios + habitaciones | tipo, data=base1)
Casa
(N=722)
Overall
(N=722)
estrato
Mean (SD) 4.20 (0.983) 4.20 (0.983)
Median [Min, Max] 4.00 [3.00, 6.00] 4.00 [3.00, 6.00]
zona
Zona Norte 722 (100%) 722 (100%)
preciom
Mean (SD) 446 (268) 446 (268)
Median [Min, Max] 390 [89.0, 1940] 390 [89.0, 1940]
areaconst
Mean (SD) 265 (167) 265 (167)
Median [Min, Max] 240 [30.0, 1440] 240 [30.0, 1440]
parqueaderos
Mean (SD) 2.18 (1.40) 2.18 (1.40)
Median [Min, Max] 2.00 [1.00, 10.0] 2.00 [1.00, 10.0]
Missing 287 (39.8%) 287 (39.8%)
banios
Mean (SD) 3.56 (1.52) 3.56 (1.52)
Median [Min, Max] 3.00 [0, 10.0] 3.00 [0, 10.0]
habitaciones
Mean (SD) 4.51 (1.83) 4.51 (1.83)
Median [Min, Max] 4.00 [0, 10.0] 4.00 [0, 10.0]

A continuación se realiza construcción del mapa de viviendas filtradas.

# install.packages("leaflet")
library(leaflet)

mapa <- leaflet(base1) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud, radius = 4)

# Mostrar el mapa
mapa

Se observa en el mapa viviendas tipo casa que la mayoría de puntos se encuentran al norte de Cali, sin embargo los puntos ubicados en otras zonas de la ciudad pueden deberse a una incorrecta clasificación de las zonas en la base de datos o digitación errada de la latitud y/o longitud. Debido a que se desconoce la causal, no se decide modificar o eliminar registros, y trabajar con la totalidad de ellos.

Paso 2: Análisis exploratorio

Enunciado: 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.

Se realiza una revisión rápida de los estadísticos descriptivos de los datos de la tabla filtrada. En la cual se observa que posee 722 registros, y se confirma la existencia de NAs en parqueaderos, y por ende se debe realizar tratamiento de estos valores nulos.

summary(base1)
##        id             zona               piso              estrato     
##  Min.   :  58.0   Length:722         Length:722         Min.   :3.000  
##  1st Qu.: 766.2   Class :character   Class :character   1st Qu.:3.000  
##  Median :2257.0   Mode  :character   Mode  :character   Median :4.000  
##  Mean   :2574.6                                         Mean   :4.202  
##  3rd Qu.:4225.0                                         3rd Qu.:5.000  
##  Max.   :8319.0                                         Max.   :6.000  
##                                                                        
##     preciom         areaconst       parqueaderos        banios      
##  Min.   :  89.0   Min.   :  30.0   Min.   : 1.000   Min.   : 0.000  
##  1st Qu.: 261.2   1st Qu.: 140.0   1st Qu.: 1.000   1st Qu.: 2.000  
##  Median : 390.0   Median : 240.0   Median : 2.000   Median : 3.000  
##  Mean   : 445.9   Mean   : 264.9   Mean   : 2.182   Mean   : 3.555  
##  3rd Qu.: 550.0   3rd Qu.: 336.8   3rd Qu.: 3.000   3rd Qu.: 4.000  
##  Max.   :1940.0   Max.   :1440.0   Max.   :10.000   Max.   :10.000  
##                                    NA's   :287                      
##   habitaciones        tipo              barrio             longitud     
##  Min.   : 0.000   Length:722         Length:722         Min.   :-76.59  
##  1st Qu.: 3.000   Class :character   Class :character   1st Qu.:-76.53  
##  Median : 4.000   Mode  :character   Mode  :character   Median :-76.52  
##  Mean   : 4.507                                         Mean   :-76.52  
##  3rd Qu.: 5.000                                         3rd Qu.:-76.50  
##  Max.   :10.000                                         Max.   :-76.47  
##                                                                         
##     latitud     
##  Min.   :3.333  
##  1st Qu.:3.452  
##  Median :3.468  
##  Mean   :3.460  
##  3rd Qu.:3.482  
##  Max.   :3.496  
## 
require(naniar)
vis_miss(base1)

Previamente se identifico que tanto parqueaderos como pisos tenian varios datos faltantes y identifico de manera porcentual cuantos valores nulos cada columna del base1 posee, encontrando que parqueaderos posee 40% y piso un 52% de NAs.

Para el tratamiento de parqueaderos debido a que en la consulta inicial de todo el dataframe se identifico que esta variable solo tmoa valores de 1 a 10, de decide trabjar estos nulos como que no poseen parqueaderos y asignar un valor de 0 (cero).

Para la variable piso, debido a que es un atributo que no posee logica para el tipo de vivienda “Casa”, es decir una casa no es una propiedad horizontal, por ende no sera utilizada para este caso de analisis.

Para el objetivo de este analisis el barrio es una categoria no a ser empleada, por lo cual se elimina al igual que piso.

require(dplyr)
#install.packages("require")
require(psych)

base1[, "parqueaderos"] <- replace(base1[, "parqueaderos"], is.na(base1[, "parqueaderos"]), 0)


base1 <- select(base1, -piso)
base1 <- select(base1, -barrio)

base1factores = base1

describe(base1factores)

Posterior a este procesamiento de datos, se obtiene nuevamente la estadística descriptiva de las categorías para comprender cuales son los valores máximo, mínimo, media, mediana y desviación estándar de cada una.

#install.packages("plotly")
#install.packages("GGally")
library(plotly)
library(GGally)
require(ggpubr)

fig <- ggplotly(ggpairs(base1factores[3:8]))

fig

A partir de la matriz de correlación se observa que el precio de la vivienda muestra una tendencia positiva con todas las variables evaluadas, se observa también que presenta una mayor correlación con el área y el estrato. El número de baños, habitaciones y parqueaderos presentan una menor correlación que los primeros 2. A continuación unos gráficos para evaluar estas correlaciones:

Para el caso del área y el precio, se observa una correlación lineal bastante clara, donde el estrato también logra mostrar cierta tendencia a aumentar el precio conforme este crece.

fig1<-plot_ly(base1factores, x=~areaconst, y=~preciom, color=~estrato, type="scatter", mode="markers", marker=list(size=~estrato), symbol =~estrato)
fig1 

Como se menciono previamente, el estrato muestra una correlación positiva relativamente alta, observándose que la media y respectivo rango intercuartil del precio para cada estrato aumenta conforme esta variable incremente

base1factores$estrato <- as.factor(base1factores$estrato)
fig2<-plot_ly(base1factores, y=~preciom, color=~estrato)%>%add_boxplot(x=~estrato)
fig2

Para los baños, sigue una tendencia similar a excepción de los casos de 0 baños, lo cual puede deberse a un reporte inadecuado pudiendo generar una incorrecta interpretación de la información, y el caso de 9 baños que no no hay una muestra suficiente para el calculo de los diagramas de bigotes.

base1factores$banios <- as.factor(base1factores$banios)
fig3<-plot_ly(base1factores, y=~preciom, color=~banios)%>%add_boxplot(x=~banios)
fig3

Para el caso de los parqueaderos, la tendencia sigue ese mismo patrón antes descrito para baños y estrato, sin embargo para los estratos 8-9-10 la tendencia parece cambiar a negativa sin embargo la información es escasa, por lo cual no es correcto concluir o generalizar para estos casos.

base1factores$parqueaderos <- as.factor(base1factores$parqueaderos)
fig4<-plot_ly(base1factores, y=~preciom, color=~parqueaderos)%>%add_boxplot(x=~parqueaderos)
fig4

Para el caso de habitaciones, se observa esa misma tendencia positiva, sin embargo también se puede definir que para el rango de 5 a 9 habitaciones, parece no ser un factor determinante de precio, y solo hasta que llega a las 10 se pueden encontrar rangos de precio mas altos

base1factores$habitaciones <- as.factor(base1factores$habitaciones)
fig5<-plot_ly(base1factores, y=~preciom, color=~habitaciones)%>%add_boxplot(x=~habitaciones)
fig5

Paso 3: Estimación del modelo

Enunciado: 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).

Se realiza la estimación del modelo con las características de interés: área, baño, habitaciones, estrato, parqueaderos. El coeficiente de determinación ajustado es 0.6484, indicando que el modelo explica el 64.84% de la variación en los precios de las viviendas, una vez que se ha tenido en cuenta el número de variables incluidas en el modelo. Por otro lado, se puede intentar mejorar la estimación del modelo mediante el uso de metodológica de estimación de manera gradual, con procesos de paso a paso o Steppwise, para este informe se realiza forward y backward, los cuales dieron como resultado que realizar un ajuste solo con el area, el estrato y el número de baños mejora el coeficiente de determinación ajustado a 0,6492, indicando que el modelo explica el 64,92% de la variación de precios sin hacer uso del número de parqueaderos y habitaciones.

# modelo  con  y= b0
modelo_b0<- lm(preciom ~ 1, data=base1)

modelo1 = lm(preciom ~ areaconst + parqueaderos + banios + habitaciones + estrato, data=base1)

summary(modelo1)
## 
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + banios + habitaciones + 
##     estrato, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -964.04  -80.10  -17.08   50.06 1069.45 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -236.47551   30.36582  -7.788 2.40e-14 ***
## areaconst       0.82677    0.04368  18.926  < 2e-16 ***
## parqueaderos   -1.67672    4.31505  -0.389    0.698    
## banios         26.97978    5.34384   5.049 5.65e-07 ***
## habitaciones    1.44443    4.16411   0.347    0.729    
## estrato        86.42579    7.39747  11.683  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 159.1 on 716 degrees of freedom
## Multiple R-squared:  0.6508, Adjusted R-squared:  0.6484 
## F-statistic: 266.9 on 5 and 716 DF,  p-value: < 2.2e-16

Con el objetivo de interpretar el coeficiente para todas las variables se explicara el primer modelo “modelo1” que tuvo un R2 ajustado de 0.6484, a continuación :

areaconst: Esta variable presenta un alto nivel de significancia según los resultados del modelo “modelo1”, por otro lado, el modelo arroja un coeficiente β1 de aproximadamente 0.83, lo que se traduce que por cada metro cuadrado en que aumenta el area, el valor de la misma también incrementa en 0,83 millones aproximadamente.

parqueaderos: Esta variable presenta un bajo nivel de significancia según los resultados del modelo, por otro lado, tiene un coeficiente β2 de aproximadamente -1.68, lo que se traduce que por cada parqueadero que tenga el apartamento, se reduce el valor del mismo en 1.68 millones aproximadamente. Este no tiene coherencia en la realidad donde deberia aumentar, lo cual explicaría el bajo valor de significancia y porque cuando se emplea el proceso paso a paso de optimización esta es eliminada y mejora el R2.

banios: Esta variable presenta un alto nivel de significancia según los resultados del modelo, ademas este arroja un coeficiente β3 de aproximadamente 26.98, lo que se traduce que por cada baño que tenga la propiedad, esta aumenta el valor de la misma en 26.98 millones aproximadamente.

habitaciones: Esta variable presenta el bajo nivel de significancia según los resultados del modelo, y toma un coeficiente β4 de aproximadamente 1.44, lo que se traduce que por cada habitación el precio aumenta 1.44 millones. Este valor es relativamente bajo, lo cual explicaria el valor bajo de sgnificancia y que posterior al proceso Steppwise, esta variable sea optimizada mejorando por ende el R2.

estrato: Esta variale presenta un nivel alto de significancia según los resultados del modelo, arrojando un coeficiente β5 de 86.43 lo que se traduce que por el aumento de cada estrato en donde se encuentre la construcción, el valor de la misma también incrementa en 86.4 millones.

En general gracias al valor de R2 se sabe que el modelo permite explicar en un 64% la relación de las variables con la respuesta.

Para mejorar el modelo se puede pensar en realizar cambios en la escala como aplicar logaritmo a las columnas/variables evaluadas o tambien se puede aplicar un proceso Stepwise. A continuación se ejecuta el algoritmo Stepwise backward, llegando a la conclusión de optimizar el modelo a trabajar solo con tres variables las cuales fueron Area, estrato y baños. Lo cual da como resultado un coeficiente de determinación ajustado de 0.6492.

modelobackward1=step(modelo1,direction = "backward")
## Start:  AIC=7326.73
## preciom ~ areaconst + parqueaderos + banios + habitaciones + 
##     estrato
## 
##                Df Sum of Sq      RSS    AIC
## - habitaciones  1      3047 18135860 7324.9
## - parqueaderos  1      3824 18136636 7324.9
## <none>                      18132812 7326.7
## - banios        1    645538 18778350 7350.0
## - estrato       1   3456785 21589597 7450.7
## - areaconst     1   9071260 27204072 7617.6
## 
## Step:  AIC=7324.85
## preciom ~ areaconst + parqueaderos + banios + estrato
## 
##                Df Sum of Sq      RSS    AIC
## - parqueaderos  1      3034 18138894 7323.0
## <none>                      18135860 7324.9
## - banios        1    936599 19072458 7359.2
## - estrato       1   3647246 21783106 7455.2
## - areaconst     1   9551271 27687131 7628.3
## 
## Step:  AIC=7322.97
## preciom ~ areaconst + banios + estrato
## 
##             Df Sum of Sq      RSS    AIC
## <none>                   18138894 7323.0
## - banios     1    944488 19083382 7357.6
## - estrato    1   3755401 21894295 7456.8
## - areaconst  1   9661498 27800392 7629.3
summary(modelobackward1)
## 
## Call:
## lm(formula = preciom ~ areaconst + banios + estrato, data = base1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -958.78  -79.28  -18.28   49.58 1075.72 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -230.09209   26.57191  -8.659  < 2e-16 ***
## areaconst      0.82806    0.04234  19.556  < 2e-16 ***
## banios        27.66782    4.52501   6.114 1.59e-09 ***
## estrato       85.26855    6.99365  12.192  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 158.9 on 718 degrees of freedom
## Multiple R-squared:  0.6507, Adjusted R-squared:  0.6492 
## F-statistic: 445.8 on 3 and 718 DF,  p-value: < 2.2e-16

La segunda técnica es trabajar el modelo y cambiar todas las variables a factores a excepción del area, estas fueron parqueaderos, baños, habitaciones y estrato como factores. obteniendo un coeficiente R2 ajustado de 0.6722, con una mejora de 0.0238, uns mayor mejora que solo ejecutar el algoritmo Stepwise.

modelo1factores = lm(preciom ~ areaconst + parqueaderos + banios + habitaciones + estrato, data=base1factores)

summary(modelo1factores)
## 
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + banios + habitaciones + 
##     estrato, data = base1factores)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1043.05   -71.22   -15.19    52.95  1064.69 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    175.22628   52.78390   3.320 0.000949 ***
## areaconst        0.75609    0.04654  16.247  < 2e-16 ***
## parqueaderos1  -47.39681   16.02724  -2.957 0.003210 ** 
## parqueaderos2  -28.95221   17.15706  -1.687 0.091965 .  
## parqueaderos3  -29.50192   25.41427  -1.161 0.246110    
## parqueaderos4   -9.31703   27.97930  -0.333 0.739238    
## parqueaderos5  -42.71911   49.98894  -0.855 0.393086    
## parqueaderos6  111.06965   57.34231   1.937 0.053160 .  
## parqueaderos7   43.10887   80.49676   0.536 0.592453    
## parqueaderos8  264.95112  155.36081   1.705 0.088573 .  
## parqueaderos9   40.70161  163.26420   0.249 0.803204    
## parqueaderos10 -34.56829  154.90173  -0.223 0.823475    
## banios1        -71.50420   73.27659  -0.976 0.329501    
## banios2        -54.77634   61.37622  -0.892 0.372454    
## banios3        -37.29668   60.53774  -0.616 0.538039    
## banios4        -13.26991   60.34778  -0.220 0.826022    
## banios5         -1.38831   61.47122  -0.023 0.981988    
## banios6         31.78224   63.18849   0.503 0.615143    
## banios7        105.90455   77.79913   1.361 0.173879    
## banios8         93.07481   76.71637   1.213 0.225458    
## banios9        347.83374  189.96685   1.831 0.067530 .  
## banios10       155.19794  135.49254   1.145 0.252428    
## habitaciones1  -27.41177  123.90668  -0.221 0.824980    
## habitaciones2   -3.73001   62.54871  -0.060 0.952465    
## habitaciones3  -10.90290   44.81315  -0.243 0.807848    
## habitaciones4   -0.51217   44.01599  -0.012 0.990719    
## habitaciones5    9.88822   45.05400   0.219 0.826345    
## habitaciones6  -35.79749   47.28935  -0.757 0.449316    
## habitaciones7   13.28229   49.04082   0.271 0.786594    
## habitaciones8   13.02998   51.78791   0.252 0.801423    
## habitaciones9  -27.42496   61.78196  -0.444 0.657255    
## habitaciones10 209.72723   66.87099   3.136 0.001784 ** 
## estrato4       101.37694   18.32379   5.533 4.49e-08 ***
## estrato5       161.08345   18.86667   8.538  < 2e-16 ***
## estrato6       343.89593   27.11628  12.682  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 153.6 on 687 degrees of freedom
## Multiple R-squared:  0.6877, Adjusted R-squared:  0.6722 
## F-statistic:  44.5 on 34 and 687 DF,  p-value: < 2.2e-16

Paso 4: validación de supuestos

Enunciado: 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).

Para la validación de supuestos se evaluara el modelo “modelobackward1” el cual correlaciona solo 3 variables con el precio.

Ya que cumple con los supuestos de multicolinealidad y varianza constante,pero no cumple los de normalidad e independencia, se recomienda realizar transformaciones en las variables numéricas por ejemplo de tipo log o raiz cuadrada con el fin de mejorar los indicadores y cumplimiento de los supuestos.

Normalidad

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

El valor p es menor que 0.05 se rechaza la Ho y se visualiza que los residuos se comportan de forma normal. Se requiere aplicar técnicas de transformación como log y raiz cuadrada, posterior re evaluación.

Independencia

library(lmtest)
dwtest(modelobackward1)
## 
##  Durbin-Watson test
## 
## data:  modelobackward1
## DW = 1.6297, p-value = 2.65e-07
## alternative hypothesis: true autocorrelation is greater than 0

El valor p es menor que 0.05 por lo que no se acepta la hipótesis Ho, por lo cual los residuos no son independientes. Se requiere incluir variables adicionales que expliquen la auto correlación en los residuos, o emplear un o varios modelos diferentes que no requieren probar independencia.

Varianza constante

gqtest(modelobackward1)
## 
##  Goldfeld-Quandt test
## 
## data:  modelobackward1
## GQ = 1.1287, df1 = 357, df2 = 357, p-value = 0.1265
## alternative hypothesis: variance increases from segment 1 to 2

En la prueba de chi-cuadrado de Goodman y Kruskal (G-test), un valor p mayor que 0.05 indica que no hay evidencia suficiente para rechazar la hipótesis nula de que las variables son independientes, no hay relación entre ellas.

Multicolinealidad

library(car)
vif(modelobackward1)
## areaconst    banios   estrato 
##  1.429914  1.357008  1.348428

El VIF se calcula para cada variable independiente en el modelo, un valor de VIF cercano a 1 indica que no hay una multicolinealidad importante. Por lo tanto, se puede indicar que el modelo no tiene problemas significativos de multicolinealidad.

Paso 5: Predicción

Enunciado: Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.

Se hara uso del modelo “modelobackward1” y “modelo1factores” para la predicción del precio de vivienda para las caracteristicas solicitadas.

predict(modelobackward1,list(areaconst=200,parqueaderos=1,banios=2,estrato=4))
##        1 
## 331.9288
predict(modelobackward1,list(areaconst=200,parqueaderos=1,banios=2,estrato=5))
##        1 
## 417.1974
predict(modelo1factores,list(areaconst=200,parqueaderos="1",banios="2",estrato="4", habitaciones="4"))
##        1 
## 325.1353
predict(modelo1factores,list(areaconst=200,parqueaderos="1",banios="2",estrato="5", habitaciones="4"))
##        1 
## 384.8418

La predicción del preció del modelo para las condiciones requeridas, area=200, parqueaderos = 1, baños=2,estrato=4 o 5, habitaciones=4, según las características indicadas por el cliente usando ambos modelos, serian para un estrato 4 de 332 o 325 millones y 417 o 384 millones para un estrato 5, modelos modelobackward1 y modelo1factores respectivamente.

Se concluye que solo las viviendas en el estrato 4 cumplirian el presupuesto suminsitrado por la compañia de 350 millones.

Paso 6: Reporte ofertas

Enunciado: Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

La predicción del indica que una vivienda de las especificaciones requeridas debe tener un costo cercano a 332-325 millones. La busqueda preliminar para los estratos 4 y 5 da como resultado 34 casas que tienen un area, numero de parqueaderos, baños y habitaciones iguales o un mayor numero de las requeridas. Debido a este alto numero de viviendas que pueden cumplir las expectativas de compra, se decide generar una nueva columna donde se puede observar el precio por metro cuadrado y filtrar las pr

en este caso la oferta está por 360 millones, pero tenemos que considerar que ofrece 16 metros cuadrados más que los utilizados para realizar la predicción, esto puede suponer el aumento en el precio de la casa. Esta podría ser una buena opción si la persona interesada puede ampliar su presupuesto 10 millones más.

viviendasoferta1=subset(base1, areaconst>=200 & preciom <=350 & habitaciones>=4 & banios>=2 & estrato>=4 & estrato<=5 & parqueaderos>=1)

viviendasoferta1
viviendasoferta1['precio_metro2'] = viviendasoferta1['preciom'] / viviendasoferta1['areaconst']

viviendasoferta1 <- arrange(viviendasoferta1, precio_metro2)

head(viviendasoferta1,5)
ofertafinal1=subset(viviendasoferta1, precio_metro2<=1.02)
ofertafinal1

A continuación se grafican en el mapa de Cali, las posibles ofertas para la vivienda tipo 1 solicitada. La casa de id=7432 debidoa que en el mapa se encuentra alejada del norte de Cali se recomienda observar de ultimo y confirmar la unbicación real de esta. La mejor oferta encontrada es la de id= 230 debido a que se encuentra al precio obtenido con el modelo de predicción, lo cual infiere es una vivienda por debajo de la tendencia de pferta de las viviendas de estratos 4 y 5 del norte de Cali. Adicionalmente es la oferta con menor precio de las 5 opciones y aunque posee la menor area de la oferta, cumple con el minimo requerido de 200 m2. Esta opción podria generar un ahorro frente al credito preparobado de 120 millones para la compañia

leaflet() %>% addTiles() %>% 
  addCircleMarkers(lng = ofertafinal1$longitud,
                   lat = ofertafinal1$latitud)

3.2 Vivienda tipo 2

Paso 1: filtro de base de datos

Enunciado: 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. (Adicional un mapa con los puntos de las bases. Discutir si todos los puntos se ubican en la zona correspondiente o se presentan valores en otras zonas, por que?)

base2=df[df$zona=="Zona Sur" & df$tipo=="Apartamento",]
head(base2, 3)

A continuación se realiza una tabla de información descriptiva de este filtro para reconocer la información de manera preliminar y confirmando que el filtro fue funcional y solo posee datos de casas ubicadas en la zona Sur.

table1(~ estrato + zona + preciom + areaconst + parqueaderos + banios + habitaciones | tipo, data=base2)
Apartamento
(N=2787)
Overall
(N=2787)
estrato
Mean (SD) 4.63 (0.842) 4.63 (0.842)
Median [Min, Max] 5.00 [3.00, 6.00] 5.00 [3.00, 6.00]
zona
Zona Sur 2787 (100%) 2787 (100%)
preciom
Mean (SD) 297 (192) 297 (192)
Median [Min, Max] 245 [75.0, 1750] 245 [75.0, 1750]
areaconst
Mean (SD) 97.5 (52.6) 97.5 (52.6)
Median [Min, Max] 85.0 [40.0, 932] 85.0 [40.0, 932]
parqueaderos
Mean (SD) 1.41 (0.669) 1.41 (0.669)
Median [Min, Max] 1.00 [1.00, 10.0] 1.00 [1.00, 10.0]
Missing 406 (14.6%) 406 (14.6%)
banios
Mean (SD) 2.49 (0.934) 2.49 (0.934)
Median [Min, Max] 2.00 [0, 8.00] 2.00 [0, 8.00]
habitaciones
Mean (SD) 2.97 (0.633) 2.97 (0.633)
Median [Min, Max] 3.00 [0, 6.00] 3.00 [0, 6.00]

A continuación se realiza construcción del mapa de viviendas filtradas.

mapa <- leaflet(base2) %>%
  addTiles() %>%
  addCircleMarkers(lng = ~longitud, lat = ~latitud, radius = 4)

# Mostrar el mapa
mapa

Se observa en el mapa viviendas tipo casa que la mayoría de puntos se encuentran al Sur de Cali, sin embargo los puntos ubicados en otras zonas de la ciudad pueden deberse a una incorrecta clasificación de las zonas en la base de datos o digitación errada de la latitud y/o longitud. Debido a que se desconoce la causal, no se decide modificar o eliminar registros, y trabajar con la totalidad de ellos.

Paso 2: Analisis exploratorio

Enunciado: 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.

Se realiza una revisión rápida de los estadísticos descriptivos de los datos de la tabla filtrada. En la cual se observa que posee 2787 registros, y se confirma la existencia de NAs en parqueaderos, y por ende se debe realizar tratamiento de estos valores nulos.

summary(base2)
##        id           zona               piso              estrato    
##  Min.   :   3   Length:2787        Length:2787        Min.   :3.00  
##  1st Qu.:2292   Class :character   Class :character   1st Qu.:4.00  
##  Median :4004   Mode  :character   Mode  :character   Median :5.00  
##  Mean   :4131                                         Mean   :4.63  
##  3rd Qu.:5876                                         3rd Qu.:5.00  
##  Max.   :8302                                         Max.   :6.00  
##                                                                     
##     preciom         areaconst       parqueaderos        banios     
##  Min.   :  75.0   Min.   : 40.00   Min.   : 1.000   Min.   :0.000  
##  1st Qu.: 175.0   1st Qu.: 65.00   1st Qu.: 1.000   1st Qu.:2.000  
##  Median : 245.0   Median : 85.00   Median : 1.000   Median :2.000  
##  Mean   : 297.3   Mean   : 97.47   Mean   : 1.415   Mean   :2.488  
##  3rd Qu.: 335.0   3rd Qu.:110.00   3rd Qu.: 2.000   3rd Qu.:3.000  
##  Max.   :1750.0   Max.   :932.00   Max.   :10.000   Max.   :8.000  
##                                    NA's   :406                     
##   habitaciones       tipo              barrio             longitud     
##  Min.   :0.000   Length:2787        Length:2787        Min.   :-76.57  
##  1st Qu.:3.000   Class :character   Class :character   1st Qu.:-76.54  
##  Median :3.000   Mode  :character   Mode  :character   Median :-76.53  
##  Mean   :2.966                                         Mean   :-76.53  
##  3rd Qu.:3.000                                         3rd Qu.:-76.52  
##  Max.   :6.000                                         Max.   :-76.46  
##                                                                        
##     latitud     
##  Min.   :3.334  
##  1st Qu.:3.370  
##  Median :3.383  
##  Mean   :3.390  
##  3rd Qu.:3.406  
##  Max.   :3.497  
## 
vis_miss(base2)

Previamente se identifico que tanto parqueaderos como pisos tenían varios datos faltantes e identifico de manera porcentual cuantos valores nulos cada columna del base2 posee, encontrando que parqueaderos posee 15% y piso un 22% de NAs.

Para el tratamiento de parqueaderos debido a que en la consulta inicial de todo el dataframe se identifico que esta variable solo toma valores de 1 a 10, de decide trabajar estos nulos como que no poseen parqueaderos y asignar un valor de 0 (cero).

Para la variable piso, debido a que es un atributo que no es solicitado en el análisis no sera empleada para este caso.

Para el objetivo de este análisis el barrio es una categoría no a ser empleada, por lo cual se elimina al igual que piso.

base2[, "parqueaderos"] <- replace(base2[, "parqueaderos"], is.na(base2[, "parqueaderos"]), 0)


base2 <- select(base2, -piso)
base2 <- select(base2, -barrio)

base2factores = base2

describe(base2factores)

Posterior a este procesamiento de datos, se obtiene nuevamente la estadística descriptiva de las categorías para comprender cuales son los valores máximo, mínimo, media, mediana y desviación estándar de cada una.

fig <- ggplotly(ggpairs(base2factores[3:8]))

fig

A partir de la matriz de correlación se observa que el precio de la vivienda muestra una tendencia positiva con todas las variables evaluadas, se observa también que presenta una mayor correlación con el area, el estrato el número de parquEaderos y el número de baños. El número de habitaciones presentan una menor correlación que el resto de variables. A continuación unos gráficos para evaluar estas correlaciones:

Para el caso del área y el precio, se observa una correlación lineal bastante clara, donde el estrato también logra mostrar cierta tendencia a aumentar el precio conforme este crece.

fig2<-plot_ly(base2factores, x=~areaconst, y=~preciom, color=~estrato, type="scatter", mode="markers", marker=list(size=~estrato), symbol =~estrato)
fig2 

Como se menciono previamente, el estrato muestra una correlación positiva relativamente alta, observándose que la media y respectivo rango intercuartil del precio para cada estrato aumenta conforme esta variable incrementa.

base2factores$estrato <- as.factor(base2factores$estrato)
fig3<-plot_ly(base2factores, y=~preciom, color=~estrato)%>%add_boxplot(x=~estrato)
fig3

Para los baños, sigue una tendencia similar a excepción de los casos de 0 baños, lo cual puede deberse a un reporte inadecuado pudiendo generar una incorrecta interpretación de la información. Para los casos de 7 y 8 baños posterior al filtro hay muy poca información para generar el diagrama de bigotes, por lo cual esta interpretación debe ser manejada con cuidado para estos casos.

base2factores$banios <- as.factor(base2factores$banios)
fig3<-plot_ly(base2factores, y=~preciom, color=~banios)%>%add_boxplot(x=~banios)
fig3

Para el caso de los parqueaderos, la tendencia sigue ese mismo patrón antes descrito para baños y estrato, sin embargo para el estrato 10 la tendencia parece cambiar a negativa pero puede deberse a otras variables que coinciden para estos casos.

base2factores$parqueaderos <- as.factor(base2factores$parqueaderos)
fig4<-plot_ly(base2factores, y=~preciom, color=~parqueaderos)%>%add_boxplot(x=~parqueaderos)
fig4

Para el caso de habitaciones, se observa esa misma tendencia positiva, sin embargo los casos de 0 baños presentan un comportamiento fuera de la tendencia con viviendas con precios por encima de incluso de los hogares de 3 y 4 baños.

base2factores$habitaciones <- as.factor(base2factores$habitaciones)
fig5<-plot_ly(base2factores, y=~preciom, color=~habitaciones)%>%add_boxplot(x=~habitaciones)
fig5

Paso 3: Estimación del modelo

Enunciado: 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).

Se realiza la estimación del modelo con las características de interés: área, baño, habitaciones, estrato, parqueaderos. El coeficiente de determinación ajustado es 0.7531, indicando que el modelo explica el 75.31% de la variación en los precios de las viviendas, una vez que se ha tenido en cuenta el número de variables incluidas en el modelo. Por otro lado, se puede intentar mejorar la estimación del modelo mediante el uso de metodológica de estimación de manera gradual, con procesos de paso a paso o Stepwise, para este informe se realiza backward, el cual dio como resultado que eliminar variables no mejora el R2 ajustado, y el mejor modelo es el ya calculado.

# modelo  con  y= b0
modelo_b02<- lm(preciom ~ 1, data=base2)

modelo2 = lm(preciom ~ areaconst + parqueaderos + banios + habitaciones + estrato, data=base2)

summary(modelo2)
## 
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + banios + habitaciones + 
##     estrato, data = base2)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1252.31   -42.15    -2.06    36.32   934.06 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -221.04614   13.47771 -16.401  < 2e-16 ***
## areaconst       1.46061    0.04876  29.956  < 2e-16 ***
## parqueaderos   48.36353    3.02343  15.996  < 2e-16 ***
## banios         48.60871    3.04050  15.987  < 2e-16 ***
## habitaciones  -22.71789    3.39549  -6.691 2.68e-11 ***
## estrato        57.00608    2.79648  20.385  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 95.17 on 2781 degrees of freedom
## Multiple R-squared:  0.7536, Adjusted R-squared:  0.7531 
## F-statistic:  1701 on 5 and 2781 DF,  p-value: < 2.2e-16
modelobackward2=step(modelo2,direction = "backward")
## Start:  AIC=25399.49
## preciom ~ areaconst + parqueaderos + banios + habitaciones + 
##     estrato
## 
##                Df Sum of Sq      RSS   AIC
## <none>                      25190458 25400
## - habitaciones  1    405478 25595936 25442
## - banios        1   2315123 27505581 25643
## - parqueaderos  1   2317780 27508239 25643
## - estrato       1   3764041 28954499 25786
## - areaconst     1   8128381 33318839 26177
summary(modelobackward2)
## 
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + banios + habitaciones + 
##     estrato, data = base2)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1252.31   -42.15    -2.06    36.32   934.06 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  -221.04614   13.47771 -16.401  < 2e-16 ***
## areaconst       1.46061    0.04876  29.956  < 2e-16 ***
## parqueaderos   48.36353    3.02343  15.996  < 2e-16 ***
## banios         48.60871    3.04050  15.987  < 2e-16 ***
## habitaciones  -22.71789    3.39549  -6.691 2.68e-11 ***
## estrato        57.00608    2.79648  20.385  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 95.17 on 2781 degrees of freedom
## Multiple R-squared:  0.7536, Adjusted R-squared:  0.7531 
## F-statistic:  1701 on 5 and 2781 DF,  p-value: < 2.2e-16

Con el objetivo de interpretar el coeficiente para todas las variables se explicara el primer modelo “modelo2” que tuvo un R2 ajustado de 0.7531, a continuación:

areaconst: Esta variable presenta un alto nivel de significancia según los resultados del modelo “modelo1”, por otro lado, el modelo arroja un coeficiente β1 de aproximadamente 1.46, lo que se traduce que por cada metro cuadrado en que aumenta el area, el valor de la misma también incrementa en 1.46 millones aproximadamente.

parqueaderos: Esta variable presenta un alto nivel de significancia según los resultados del modelo, tiene un coeficiente β2 de aproximadamente 48.36, lo que se traduce que por cada parqueadero que tenga el apartamento, se incrementa el valor del mismo en 48.36 millones aproximadamente.

banios: Esta variable presenta un alto nivel de significancia según los resultados del modelo, ademas este arroja un coeficiente β3 de aproximadamente 48.61, lo que se traduce que por cada baño que tenga la propiedad, esta aumenta el valor de la misma en 48.61 millones aproximadamente.

habitaciones: Esta variable presenta un alto nivel de significancia según los resultados del modelo, y toma un coeficiente β4 de aproximadamente -22.72, lo que se traduce que por cada habitación el precio disminuye 1.44 millones. Este no tiene coherencia en la realidad donde deberia aumentar, sin embargo puede deberse a una posible intercorrelación con una o varias variables.

estrato: Esta variable presenta un nivel alto de significancia según los resultados del modelo, arrojando un coeficiente β5 de 57.00 lo que se traduce que por el aumento de cada estrato en donde se encuentre la construcción, el valor de la misma también incrementa en 57 millones.

En general gracias al valor de R2 se sabe que el modelo permite explicar en un 75% la relación de las variables con la respuesta.

Para mejorar el modelo se puede pensar en realizar cambios en la escala como aplicar logaritmo a las columnas/variables evaluadas ya que aplicar un proceso Stepwise previamente se observo no permite mejorar el R2 ajustado

Una segunda técnica es trabajar el modelo y cambiar todas las variables a factores a excepción del área, estas fueron parqueaderos, baños, habitaciones y estrato como factores. obteniendo un coeficiente R2 ajustado de 0.8158, con una mejora de 0.0627, una mayor mejora que solo ejecutar el algoritmo Stepwise.

modelo2factores = lm(preciom ~ areaconst + parqueaderos + banios + habitaciones + estrato, data=base2factores)

summary(modelo2factores)
## 
## Call:
## lm(formula = preciom ~ areaconst + parqueaderos + banios + habitaciones + 
##     estrato, data = base2factores)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1066.28   -34.55    -2.38    31.33   812.31 
## 
## Coefficients:
##                  Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     114.60164   38.52812   2.974 0.002960 ** 
## areaconst         1.30147    0.04731  27.510  < 2e-16 ***
## parqueaderos1    18.00558    4.90335   3.672 0.000245 ***
## parqueaderos2    62.94904    6.41987   9.805  < 2e-16 ***
## parqueaderos3   222.24820   12.21337  18.197  < 2e-16 ***
## parqueaderos4   232.69577   17.94326  12.968  < 2e-16 ***
## parqueaderos10  234.73167   61.27840   3.831 0.000131 ***
## banios1        -113.74794   43.34110  -2.624 0.008726 ** 
## banios2         -92.71020   42.69102  -2.172 0.029966 *  
## banios3         -77.74536   42.73388  -1.819 0.068975 .  
## banios4         -11.31448   42.78138  -0.264 0.791436    
## banios5          64.97551   43.30282   1.500 0.133601    
## banios6         244.33395   50.57847   4.831 1.43e-06 ***
## banios7         102.49071   94.09876   1.089 0.276168    
## banios8        -290.54318   94.77502  -3.066 0.002193 ** 
## habitaciones1    22.81376   41.16746   0.554 0.579508    
## habitaciones2    19.79639   36.24636   0.546 0.584999    
## habitaciones3    28.83745   36.05133   0.800 0.423838    
## habitaciones4    -1.04681   36.29320  -0.029 0.976992    
## habitaciones5  -130.66086   40.08061  -3.260 0.001128 ** 
## habitaciones6    -1.39218   52.46775  -0.027 0.978833    
## estrato4         36.99363    7.15429   5.171 2.50e-07 ***
## estrato5         68.61134    7.59048   9.039  < 2e-16 ***
## estrato6        205.89095    9.02221  22.820  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 82.21 on 2763 degrees of freedom
## Multiple R-squared:  0.8173, Adjusted R-squared:  0.8158 
## F-statistic: 537.5 on 23 and 2763 DF,  p-value: < 2.2e-16

Paso 4: validación de supuestos

Enunciado: 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).

Para la validación de supuestos se evaluara el modelo “modelo2” el cual correlaciona las 5 variables con el precio.

Ya que cumple con los supuestos de multicolinealidad y varianza constante, pero no cumple los de normalidad e independencia, se recomienda realizar transformaciones en las variables numéricas por ejemplo de tipo log o raiz cuadrada con el fin de mejorar los indicadores y cumplimiento de los supuestos.

Normalidad

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

El valor p es menor que 0.05 se rechaza la Ho y se visualiza que los residuos se comportan de forma normal. Se requiere aplicar técnicas de transformación como log y raiz cuadrada, posterior re evaluación.

Independencia

dwtest(modelo2)
## 
##  Durbin-Watson test
## 
## data:  modelo2
## DW = 1.5041, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0

El valor p es menor que 0.05 por lo que no se acepta la hipótesis Ho, por lo cual los residuos no son independientes. Se requiere incluir variables adicionales que expliquen la auto correlación en los residuos, o emplear un o varios modelos diferentes que no requieren probar independencia.

Varianza constante

gqtest(modelo2)
## 
##  Goldfeld-Quandt test
## 
## data:  modelo2
## GQ = 0.93375, df1 = 1388, df2 = 1387, p-value = 0.8991
## alternative hypothesis: variance increases from segment 1 to 2

En la prueba de chi-cuadrado de Goodman y Kruskal (G-test), un valor p mayor que 0.05 indica que no hay evidencia suficiente para rechazar la hipótesis nula de que las variables son independientes, no hay relación entre ellas.

Multicolinealidad

vif(modelo2)
##    areaconst parqueaderos       banios habitaciones      estrato 
##     2.020543     1.776016     2.482470     1.418810     1.705639

El VIF se calcula para cada variable independiente en el modelo, un valor de VIF cercano a 1 y por debajo de 5 indica que no hay una multicolinealidad importante. Por lo tanto, se puede indicar que el modelo no tiene problemas significativos de multicolinealidad.

Paso 5: Predicción

Enunciado: Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.

Se hará uso del modelo “modelo2” y “modelo2factores” para la predicción del precio de vivienda para las características solicitadas.

predict(modelo2,list(areaconst=300,parqueaderos=3,banios=3,estrato=5, habitaciones=5))
##        1 
## 679.4951
predict(modelo2,list(areaconst=300,parqueaderos=3,banios=3,estrato=6, habitaciones=5))
##        1 
## 736.5012
predict(modelo2factores,list(areaconst=300,parqueaderos="3",banios="3",estrato="5", habitaciones="5"))
##        1 
## 587.4963
predict(modelo2factores,list(areaconst=300,parqueaderos="3",banios="3",estrato="6", habitaciones="5"))
##        1 
## 724.7759

La predicción del preció del modelo para las condiciones requeridas, area=300, parqueaderos = 3, baños=3, estrato=5 o 6, habitaciones=5, según las características indicadas por el cliente usando ambos modelos, serian para un estrato 5 de 679 o 587 millones y 736 o 724 millones para un estrato 6, modelos “modelo2” y “modelo2factores” respectivamente.

Se concluye que con el crédito pre aprobado de 850 Millones seria posible adquirir viviendas con las características deseadas en ambos estratos.

Paso 6: Reporte ofertas

Enunciado: Con las predicciones del modelo sugiera potenciales ofertas que responda a la solicitud de la vivienda 1. Tenga encuentra que la empresa tiene crédito pre-aprobado de máximo 350 millones de pesos. Realice un análisis y presente en un mapa al menos 5 ofertas potenciales que debe discutir.

La predicción de los dos modelos indica que una vivienda de las especificaciones requeridas debe tener un costo entre 587 y 736 millones en función del estrato donde sea adquirida. La búsqueda preliminar para los estratos 5 y 6 da como resultado 2 apartamentos que tienen un área, numero de parqueaderos, baños y habitaciones iguales o un mayor numero de las requeridas. Adicionalmente se decide generar una nueva columna donde se puede observar el precio por metro cuadrado y observar cual puede ser una mejor opción de compra.

Se corren ambos modelos para estas dos ofertas, encontrando que la segunda vivienda la cual posee un costo de 670 Millones, para ambos se espera un precio superior a los 1200 millones, por lo cual puede ser una oferta a considerar. Mientras que la primera opción de compra presenta el precio por metro cuadrado mas bajo de los dos de 1.3 Millones/metro2 y la segunda de 2.2 millones/metro2

viviendasoferta2=subset(base2, areaconst>=300 & preciom <=850 & habitaciones>=5 & banios>=3 & estrato>=5 & estrato<=6 & parqueaderos>=3)

viviendasoferta2
predict(modelo2,list(areaconst=573,parqueaderos=3,banios=8,estrato=5, habitaciones=5))
##        1 
## 1321.286
predict(modelo2factores,list(areaconst=573,parqueaderos="3",banios="8",estrato="5", habitaciones="5"))
##   1 
## 730
predict(modelo2,list(areaconst=670,parqueaderos=3,banios=5,estrato=5, habitaciones=6))
##        1 
## 1294.421
predict(modelo2factores,list(areaconst=670,parqueaderos="3",banios="5",estrato="5", habitaciones="6"))
##       1 
## 1341.03
viviendasoferta2['precio_metro2'] = viviendasoferta2['preciom'] / viviendasoferta2['areaconst']

viviendasoferta2 <- arrange(viviendasoferta2, precio_metro2)

head(viviendasoferta2,5)

A continuación se grafican en el mapa de Cali, las posibles ofertas para la vivienda tipo 2 solicitada. Ambos apartamentos se encuentran cercanos entre ellos, cumplen los criterios definidos y ambos casos generan un ahorro en la posible compra al tener un precio en el mercado inferior al del credito.

leaflet() %>% addTiles() %>% 
  addCircleMarkers(lng = viviendasoferta2$longitud,
                   lat = viviendasoferta2$latitud)