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.
Hace dos días, María recibió una carta solicitando asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad. Las solicitudes incluyen las siguientes condiciones:
| Características | Vivienda 1 | Vivienda 2 |
|---|---|---|
| Tipo | Casa | Apartamento |
| Área construida | 200 | 300 |
| Parqueaderos | 1 | 3 |
| Baños | 2 | 3 |
| Habitaciones | 4 | 5 |
| Estrato | 4 o 5 | 5 o 6 |
| Zona | Norte | Sur |
| Crédito preaprobado | 350 millones | 850 millones |
Ayude a María a responder la solicitud, mediante técnicas modelación que usted conoce. Ella requiere le envíe un informe ejecutivo donde analice los dos casos y sus recomendaciones (Informe). Como soporte del informe debe anexar las estimaciones, validaciones y comparación de modelos requeridos (Anexos).
Los datos son obtenidos de la librería paqueteMETODOS de R y, analizados a través de la misma herramienta haciendo uso de diferentes paquetes que permiten realizar un análisis estadístico de acuerdo a la siguiente metodología.
faltantes <- colSums(is.na(vivienda)) %>% as.data.frame()
faltantes
## .
## id 3
## zona 3
## piso 2638
## estrato 3
## preciom 2
## areaconst 3
## parqueaderos 1605
## banios 3
## habitaciones 3
## tipo 3
## barrio 3
## longitud 3
## latitud 3
vivienda$parqueaderos[is.na(vivienda$parqueaderos)] <- 0
moda_piso <- Mode(vivienda$piso, na.rm = TRUE)
vivienda$piso[is.na(vivienda$piso)] <- moda_piso
vivienda <- na.omit(vivienda)
vivienda$tipo <- ifelse(vivienda$tipo=="Casa","CASA",ifelse(vivienda$tipo=="casa","CASA",vivienda$tipo))
vivienda$tipo <- ifelse(vivienda$tipo=="apto","APARTAMENTO",ifelse(vivienda$tipo=="Apartamento","APARTAMENTO",vivienda$tipo))
vivienda$barrio <- trimws(chartr("ÁÉÍÓÚ", "AEIOU", toupper(vivienda$barrio)))
vivienda$longitud <- ifelse(vivienda$longitud<=-90,vivienda$longitud/1000,vivienda$longitud)
vivienda$latitud <- ifelse(vivienda$latitud>=270,vivienda$latitud/1000,vivienda$latitud)
vivienda$estrato <- as.character(vivienda$estrato)
vivienda$piso <- as.character(vivienda$piso)
faltantes <- colSums(is.na(vivienda)) %>% as.data.frame()
faltantes
## .
## id 0
## zona 0
## piso 0
## estrato 0
## preciom 0
## areaconst 0
## parqueaderos 0
## banios 0
## habitaciones 0
## tipo 0
## barrio 0
## longitud 0
## latitud 0
Una vez realizada la imputación y estandarización de datos, se tiene la base que hará parte del análisis.
vivienda <- data.frame(vivienda)
head(vivienda,3)
## id zona piso estrato preciom areaconst parqueaderos banios
## 1 1147 Zona Oriente 02 3 250 70 1 3
## 2 1169 Zona Oriente 02 3 320 120 1 2
## 3 1350 Zona Oriente 02 3 350 220 2 2
## habitaciones tipo barrio longitud latitud
## 1 6 CASA 20 DE JULIO -76.51168 3.43382
## 2 3 CASA 20 DE JULIO -76.51237 3.43369
## 3 4 CASA 20 DE JULIO -76.51537 3.43566
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. (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?).
Inicialmente se realizan filtros sobre las variables “tipo” (CASA) y “zona” (Zona Norte). Obteniendo 722 viviendas.
vivienda1 <- dplyr::filter(vivienda, tipo=="CASA" & zona=="Zona Norte")
nrow(vivienda1)
## [1] 722
Sin embargo, al generar un mapa preliminar se evidencian viviendas en otras zonas, por lo que se procede a delimitar una latitud y una longitud con puntos estratégicos de la ciudad de Cali, y se adiciona al filtro inicial. Así pues, se seleccionan las viviendas que tienen latitud superior a la del Acuaparque de la caña (3.4556) y longitud mayor a la de Cuchilla La Estaca (-76.5403). Adicionalmente se omiten aquellas viviendas que no registran baños ni habitaciones. Obteniendo 522 viviendas, es decir, 200 viviendas menos.
Se crea la base de datos “vivienda1”.
vivienda1 <- dplyr::filter(vivienda, tipo=="CASA" & zona=="Zona Norte" & banios>0 & habitaciones>0
& latitud>=3.4556 & longitud>=-76.5403)
library(DT)
datatable(vivienda1, list(pageLength=3))
knitr::kable (summary(vivienda1))
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Min. : 88.0 | Length:522 | Length:522 | Length:522 | Min. : 110.0 | Min. : 30.0 | Min. : 0.000 | Min. : 1.000 | Min. : 2.000 | Length:522 | Length:522 | Min. :-76.54 | Min. :3.456 | |
| 1st Qu.: 598.8 | Class :character | Class :character | Class :character | 1st Qu.: 236.2 | 1st Qu.: 132.2 | 1st Qu.: 0.000 | 1st Qu.: 2.000 | 1st Qu.: 3.000 | Class :character | Class :character | 1st Qu.:-76.52 | 1st Qu.:3.468 | |
| Median :1348.0 | Mode :character | Mode :character | Mode :character | Median : 370.0 | Median : 230.0 | Median : 1.000 | Median : 3.000 | Median : 4.000 | Mode :character | Mode :character | Median :-76.52 | Median :3.476 | |
| Mean :1984.9 | NA | NA | NA | Mean : 416.7 | Mean : 252.5 | Mean : 1.506 | Mean : 3.515 | Mean : 4.615 | NA | NA | Mean :-76.51 | Mean :3.476 | |
| 3rd Qu.:3167.5 | NA | NA | NA | 3rd Qu.: 528.8 | 3rd Qu.: 330.0 | 3rd Qu.: 2.000 | 3rd Qu.: 4.000 | 3rd Qu.: 5.000 | NA | NA | 3rd Qu.:-76.50 | 3rd Qu.:3.484 | |
| Max. :5821.0 | NA | NA | NA | Max. :1800.0 | Max. :1440.0 | Max. :10.000 | Max. :10.000 | Max. :10.000 | NA | NA | Max. :-76.48 | Max. :3.496 |
Se crea el mapa con las viviendas seleccionadas según la base “vivienda1”.
# install.packages("leaflet")
library(leaflet)
vivienda1.coord <- data.frame(
lat = c(vivienda1$latitud),
long = c(vivienda1$longitud)
)
# Crea un mapa
map <- leaflet(vivienda1.coord) %>%
addTiles() %>%
addMarkers(
lng = ~long,
lat = ~lat,
layerId = 1,
popup = ~as.character(lat)
) %>%
addRectangles(
lng1=-76.5403, lat1=3.4556,
lng2=max(vivienda1$longitud), lat2=max(vivienda1$latitud),
fillColor = "transparent",color="red"
)
# Muestra el mapa
map
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.
Al analizar la correlación entre el precio de las viviendas y el estrato mediante un gráfico de cajas y alambres se evidencia claramente que a mayor estrato mayor precio promedio de las casas de la zona norte.
plot_ly(vivienda1, x = ~estrato, y = ~preciom, type = 'box')
kruskal.test(preciom ~ estrato, data = vivienda1)
##
## Kruskal-Wallis rank sum test
##
## data: preciom by estrato
## Kruskal-Wallis chi-squared = 278.2, df = 3, p-value < 2.2e-16
Ahora se analiza el precio de las viviendas frente al área construida mediante un gráfico de dispersión, evidenciando que a mayor área contruida mayor es el precio, con un coeficiente de correlación de \(0.7419\).
plot1 <- ggplot(vivienda1, aes(x = areaconst, y = preciom)) +
geom_point(aes(color = estrato)) +
labs(x = "Área Construida (m2)",
y = "Precio (millones)") +
theme_minimal()
ggplotly(plot1)
round(cor(vivienda1$areaconst, vivienda1$preciom),4)
## [1] 0.7419
A simple vista no se observa una correlación del precio de las viviendas frente al número de baños, parqueaderos y habitaciones, con coeficientes de correlación de \(0.555\), \(0.4616\) y \(0.421\), respectivamente
plot3 <- ggplot(vivienda1, aes(x = banios, y = preciom)) +
geom_point(aes(color = estrato)) +
labs(x = "# baños",
y = "Precio (millones)") +
theme_minimal()
ggplotly(plot3)
round(cor(vivienda1$banios, vivienda1$preciom),4)
## [1] 0.555
plot4 <- ggplot(vivienda1, aes(x = parqueaderos, y = preciom)) +
geom_point(aes(color = estrato)) +
labs(x = "# parqueaderos",
y = "Precio (millones)") +
theme_minimal()
ggplotly(plot4)
round(cor(vivienda1$parqueaderos, vivienda1$preciom),4)
## [1] 0.4616
plot2 <- ggplot(vivienda1, aes(x = habitaciones, y = preciom)) +
geom_point(aes(color = estrato)) +
labs(x = "# habitaciones",
y = "Precio (millones)") +
theme_minimal()
ggplotly(plot2)
round(cor(vivienda1$habitaciones, vivienda1$preciom),4)
## [1] 0.421
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).
Se estima un modelo de regresión lineal múltiple para casas de zona norte, teniendo en cuenta que la variable “estrato” es ordinal.
ModeloRLM = lm(data=vivienda1, preciom~areaconst+habitaciones+banios+parqueaderos+estrato)
summary(ModeloRLM)
##
## Call:
## lm(formula = preciom ~ areaconst + habitaciones + banios + parqueaderos +
## estrato, data = vivienda1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -886.52 -63.40 -13.09 34.15 1105.27
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 33.37412 20.28759 1.645 0.10057
## areaconst 0.74076 0.05195 14.258 < 2e-16 ***
## habitaciones 7.91285 5.13864 1.540 0.12421
## banios 15.66939 6.49960 2.411 0.01627 *
## parqueaderos 14.64259 4.68507 3.125 0.00188 **
## estrato4 85.73019 19.27868 4.447 1.07e-05 ***
## estrato5 126.34566 18.75614 6.736 4.37e-11 ***
## estrato6 267.78089 34.63721 7.731 5.66e-14 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 144.2 on 514 degrees of freedom
## Multiple R-squared: 0.6571, Adjusted R-squared: 0.6524
## F-statistic: 140.7 on 7 and 514 DF, p-value: < 2.2e-16
#COEFICIENTES
coef(ModeloRLM)
## (Intercept) areaconst habitaciones banios parqueaderos estrato4
## 33.3741159 0.7407591 7.9128491 15.6693901 14.6425928 85.7301878
## estrato5 estrato6
## 126.3456615 267.7808927
#R2
print(summary(ModeloRLM)$r.squared)
## [1] 0.6571137
Al analizar el modelo para estimar los precios de las casas de la zona norte de Cali, se observa que el coeficiente de determinación, \(R^2\), es igual a \(0.6524\), es decir que, aproximadamente el \(65.24%\) de las variaciones de dichos precios pueden explicarse utilizando las variables incluidas en el modelo.
Las variables área construida, el estrato, el número de baños y parqueaderos del modelo son estadísticamente significativas, es decir que tienen un impacto importante y medible en el precio de las casas de la zona norte de Cali.
El modelo resultante es: \[ Preciom = 33.37 + 0.74 * (areaconst) + 7.91 * (habitaciones) + 15.67 * (banios) + 14.64 * (parqueaderos) + 85.73 * (estrato4) + 126.35 * (estrato5) + 267.78 * (estrato6) \] La ecuación del modelo muestra cómo impactan las variables en los precios de las viviendas, por ejemplo, un aumento de una unidad en el área construida se relaciona con un aumento de aproximadamente \(0.74\) unidades en el precio.
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).
Se realiza análisis gráfico para realizar la validación de los supuestos del modelo, con el proposito de evaluar la idoneidad del mismo. A continuación se tienen los gráficos utilizados habitualmente.
par(mfrow = c(2, 2))
plot(ModeloRLM)
Procediendo con su interpretación:
| Supuesto | Análisis | Cumplimiento |
|---|---|---|
| Normalidad | En el Gráfico Q - Q Residuals se aprecia que los puntos no siguen una tendencia lineal con respecto a la diagonal que representa la concordancia entre los residuales estandarizados y los cuantiles teóricos, lo que evidencia que no sigue una distribución normal. | No |
| Homocedasticidad | En el Gráfico Residuals Vs. Fitted, se evidencia que los residuales se alejan de cero a medida que se incrementan los valores ajustados, es decir que no se tiene una dispersión constante de los residuales, concluyendo que el modelo tiene heterocedasticidad. | No |
| Linealidad | En el Gráfico Residuals Vs. Fitted, se observa que los residuos no se distribuyen alrededor de la línea horizontal en cero, evidenciando que la relación entre las variables no es estrictamente lineal. | No |
| Outliers | En la Gráfica Residuals Vs. Leverage se observa que los residuos estandarizados se encuentran cerca a \(0\) para valores de levarage pequeños lo que puede indica que las observaciones están ajustadas correctamente por el modelo, sin embargo hay algunos valore atípicos representados por valores de leverage alto. | No |
Para sustentar los análisis previos dados a partir de las gráficas, se realizan las pruebas correspondientes a los supuestos de normalidad, homocedasticidad y no autocorrelación. De acuerdo con los \(p-value\) obtenidos se tiene que son cercanos a cero, es decir que se rechazan las hipótesis nulas de cada supuesto.
Normalidad <- shapiro.test(ModeloRLM$residuals)
homocedasticidad <- lmtest::bptest(ModeloRLM)
autocorrelacion <- lmtest::dwtest(ModeloRLM)
resultados <- rbind(
c("Normalidad", Normalidad$method, format(Normalidad$p.value,
scientific = TRUE)),
c("Homocedasticidad", homocedasticidad$method, format(homocedasticidad$p.value,
scientific = TRUE)),
c("No Autocorrelación", autocorrelacion$method, format(autocorrelacion$p.value,
scientific = TRUE)))
colnames(resultados) <- c("Prueba", "Método", "Valor p")
kable(resultados)
| Prueba | Método | Valor p |
|---|---|---|
| Normalidad | Shapiro-Wilk normality test | 5.493929e-26 |
| Homocedasticidad | studentized Breusch-Pagan test | 1.372001e-19 |
| No Autocorrelación | Durbin-Watson test | 2.166482e-02 |
5. Con el modelo identificado debe predecir el precio de la vivienda con las características de la primera solicitud.
Se definen los datos de predicción de la vivienda 1, encontrando que el precio de la vivienda de estrato 4 es de \(\$344.89\) millones de pesos, y para estrato 5 es de \(\$385.50\).
Vivienda_1 = data.frame( areaconst=c(200,200),
habitaciones=c(4,4),
banios=c(2,2),
parqueaderos=c(1,1),
estrato=c("4","5")
)
knitr::kable(Vivienda_1)
| areaconst | habitaciones | banios | parqueaderos | estrato |
|---|---|---|---|---|
| 200 | 4 | 2 | 1 | 4 |
| 200 | 4 | 2 | 1 | 5 |
predict(ModeloRLM, newdata = Vivienda_1)
## 1 2
## 344.8889 385.5044
6. 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.
Teniendo en cuenta que se tiene un crédito pre-aprobado de máximo \(\$350\) millones de pesos, y se requiere una casa en la zona norte en estrato 4 o 5, con un área contruida de mínimo 200 metros cuadrados, un parqueadero, 2 baños y 4 habitaciones.
parametros_vivienda_1 <- which((vivienda1$estrato=="4" | vivienda1$estrato=="5") & vivienda1$areaconst>=200 & vivienda1$parqueaderos>=1 & vivienda1$banios>=2 & vivienda1$habitaciones>=4 & vivienda1$preciom<=350)
Se filtran las viviendas ofertadas que cumplen con los parámetros.
oferta <- vivienda1[parametros_vivienda_1,]
Se seleccionan 5 Ofertas que cumple las caracteristicas, ordenadas por área construida de mayor a menor.
oferta_5 = oferta[order(oferta$areaconst, decreasing = TRUE), ]
knitr::kable(head(oferta_5, 5))
| id | zona | piso | estrato | preciom | areaconst | parqueaderos | banios | habitaciones | tipo | barrio | longitud | latitud | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 326 | 3101 | Zona Norte | 02 | 5 | 340 | 355 | 2 | 5 | 8 | CASA | SAN VICENTE | -76.52377 | 3.46384 |
| 503 | 1943 | Zona Norte | 02 | 5 | 350 | 346 | 1 | 2 | 4 | CASA | VIPASA | -76.51847 | 3.47503 |
| 75 | 4209 | Zona Norte | 02 | 5 | 350 | 300 | 3 | 5 | 6 | CASA | EL BOSQUE | -76.53010 | 3.48577 |
| 500 | 1822 | Zona Norte | 02 | 4 | 340 | 295 | 2 | 2 | 4 | CASA | VIPASA | -76.51777 | 3.48060 |
| 203 | 937 | Zona Norte | 02 | 4 | 350 | 280 | 2 | 3 | 4 | CASA | LA MERCED | -76.50603 | 3.46643 |
Se crea el mapa con las viviendas seleccionadas según la base “vivienda1”.
# install.packages("leaflet")
library(leaflet)
oferta_5 <- head(oferta_5, 5)
oferta_5.coord <- data.frame(
lat = c(oferta_5$latitud),
long = c(oferta_5$longitud)
)
# Crea un mapa
map_oferta <- leaflet(oferta_5.coord) %>%
addTiles() %>%
addMarkers(
lng = ~long,
lat = ~lat,
layerId = 1,
popup = ~as.character(lat)
) %>%
addRectangles(
lng1=-76.5403, lat1=3.4556,
lng2=max(oferta_5$longitud), lat2=max(oferta_5$latitud),
fillColor = "transparent",color="red"
)
# Muestra el mapa
map_oferta