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: 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 de modelación que usted conoce. Ella requiere que se le envíe un informe ejecutivo en el que se analicen los dos casos y se presenten las recomendaciones correspondientes (Informe). Como soporte del informe, se deben anexar las estimaciones, validaciones y comparación de modelos requeridos (Anexos).
library(devtools)
library(mice)
library(tidyverse)
library(factoextra)
library(cluster)
library(dplyr)
library(FactoMineR)
library(gridExtra)
library(tcltk2)
devtools::install_github("centromagis/paqueteMODELOS", force = TRUE)
##
## ── R CMD build ─────────────────────────────────────────────────────────────────
## During startup - Warning messages:
## 1: Setting LC_TIME failed, using "C"
## 2: Setting LC_MESSAGES failed, using "C"
## 3: Setting LC_MONETARY failed, using "C"
## checking for file ‘/private/var/folders/f7/fh96nvx97hz525c07nbtj01r0000gn/T/RtmpR04dYJ/remotes16cb71a509bb/Centromagis-paqueteMODELOS-3b06257/DESCRIPTION’ ... ✔ checking for file ‘/private/var/folders/f7/fh96nvx97hz525c07nbtj01r0000gn/T/RtmpR04dYJ/remotes16cb71a509bb/Centromagis-paqueteMODELOS-3b06257/DESCRIPTION’
## ─ preparing ‘paqueteMODELOS’:
## checking DESCRIPTION meta-information ... ✔ checking DESCRIPTION meta-information
## ─ checking for LF line-endings in source and make files and shell scripts
## ─ checking for empty or unneeded directories
## ─ building ‘paqueteMODELOS_0.1.0.tar.gz’
##
##
library(paqueteMODELOS)
library(psych)
library(ggplot2)
library(patchwork)
library(VIM)
library(leaflet)
library(corrplot)
library (plotly)
library(lmtest)
data("vivienda")
Extracion de datos relevantes para la solicitud
#Filtro por interes de la primera solicitud
base1 <- vivienda %>%
filter(tipo == "Casa", zona == "Zona Norte")
# Primeros 3 registros
head(base1, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4057 Zona N… 02 6 750 445 NA 7 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Comprobacion
table(vivienda$tipo, vivienda$zona)
##
## Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
## Apartamento 24 1198 1029 62 2787
## Casa 100 722 169 289 1939
table(base1$tipo)
##
## Casa
## 722
table(base1$zona)
##
## Zona Norte
## 722
Mapeo de registros
# Crea un mapa
map <- leaflet(base1) %>%
addTiles() %>%
addMarkers(
lng = ~longitud,
lat = ~latitud,
popup = ~as.character(latitud)
)
map
El mapa permite visualizar la distribución geográfica de las casas clasificadas en la zona norte. Sin embargo, se observa que algunos puntos aparecen fuera del límite geográfico esperado. Esto puede deberse a que la variable zona corresponde a una clasificación comercial utilizada por el mercado inmobiliario y no necesariamente a una delimitación geográfica estricta.
Analisis de correlacion
Var_cor <- data.frame(base1$preciom, base1$areaconst, base1$estrato, base1$banios, base1$habitaciones, base1$latitud, base1$longitud)
cor_matrix <- cor(Var_cor, use = "complete.obs")
plot_ly(
x = colnames(cor_matrix),
y = rownames(cor_matrix),
z = cor_matrix,
type = "heatmap",
colorscale = "RdBu"
)
El precio de la casa en zona norte se relaciona fuerte y positivamente con el area construida, estrato y numero de baños. El numero de habitaciones se relacion debilmente con el precio de la vivienda. La latitud presena una relacion muy debil con el precio y la longitud una relacion debil con el precio.
Modelo de regresio lineal multiple
modelo_1 <- lm(preciom ~ areaconst + estrato + banios, data=base1)
summary(modelo_1)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios, 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 ***
## estrato 85.26855 6.99365 12.192 < 2e-16 ***
## banios 27.66782 4.52501 6.114 1.59e-09 ***
## ---
## 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
El valor base del modelo cuando las demás variables son cero es de -139.34 millones. Por cada metro cuadrado adicional de área construida, el precio de la vivienda aumenta en promedio 0.92 millones de pesos, manteniendo constantes las demás variables. Un aumento de una unidad en el estrato socioeconómico incrementa el precio de la vivienda en promedio 57.1 millones de pesos, manteniendo constantes las demás variables. Por cada baño adicional incrementa el precio de la vivienda en aproximadamente 23.2 millones de pesos. Todos los coeficientes presentan valores p menores a 0.001, indicando que son estadísticamente significativos. El coeficiente de determinacion de 0.7028, es decir, el 70.28 % de la variabilidad del precio de las viviendas puede ser explicada por las variables incluidas en el modelo (área construida, estrato y número de baños). Este valor indica que el modelo tiene un buen nivel de ajuste, aunque todavía existe cerca del 30% de la variabilidad del precio que no está siendo explicada por el modelo. El modelo explica el 70% de la variabilidad del precio de a vivienda cuando se ajusta por el número de predictores incluidos.
Prediccion usando set de prueba
set.seed(2024)
train_index <- sample(1:nrow(base1), 0.8*nrow(base1))
train <- base1[train_index, ]
test <- base1[-train_index, ]
modelo1 <- lm(preciom ~ areaconst + estrato + banios, data = train)
pred <- predict(modelo1, newdata = test)
RMSE <- sqrt(mean((test$preciom - pred)^2))
MAE <- mean(abs(test$preciom - pred))
RMSE
## [1] 125.3125
MAE
## [1] 91.70191
El modelo tiene un error proedio aproximado de 125,31 millones de pesos en la prediccion del precio de la vivienda. Adicionalmente, las predicciones del modelo difieren del valor real en aproximadamente 91,70 millones.
Validacion de supuestos
residuos <- residuals(modelo_1)
MSE <- summary(modelo_1)$sigma^2
residuales_estandarizados <- residuos / sqrt(MSE)
Normalidad
shapiro.test(residuales_estandarizados)
##
## Shapiro-Wilk normality test
##
## data: residuales_estandarizados
## W = 0.83689, p-value < 2.2e-16
Los residuales del modelo no cumplen con el supuesto de normalidad. Homocedasticidad
gqtest(modelo_1)
##
## Goldfeld-Quandt test
##
## data: modelo_1
## GQ = 1.1287, df1 = 357, df2 = 357, p-value = 0.1265
## alternative hypothesis: variance increases from segment 1 to 2
En los residuales del modelo existe homocedasticidad, es decir, se cumple con el supuesto de homogeneidad de varianzas.
Independencia
dwtest(modelo_1)
##
## Durbin-Watson test
##
## data: modelo_1
## DW = 1.6297, p-value = 2.65e-07
## alternative hypothesis: true autocorrelation is greater than 0
Existe autocorrelacion positiva entre los residuos del modelo.
Los supuestos del modelo de regresión no se cumplen, las inferencias estadísticas pueden ser incorrectas. Es decir, los coeficientes pueden estimarse, pero las pruebas, intervalos de confianza y predicciones pueden ser poco confiables.
Prediccion
nueva_viv1 <- data.frame(
areaconst = 200,
estrato = 4.5,
habitaciones = 4,
parqueaderos = 1,
banios = 2
)
predict(modelo_1, newdata = nueva_viv1, interval = "prediction")
## fit lwr upr
## 1 374.5631 61.93098 687.1952
El valor predicho por el modelo es de 348 millones con precio minimo de 164 millones y maximo 532 millones.
Ofertas sugeridas
ofertas_v1 <- base1 %>%
filter(
estrato %in% c("4", "5"),
habitaciones >= 4,
banios >= 2,
parqueaderos >= 1,
preciom <= 350,
areaconst >=200)
ofertas_v1
## # A tibble: 34 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4210 Zona … 01 5 350 200 3 3 4
## 2 4267 Zona … 01 5 335 202 1 4 5
## 3 4800 Zona … 01 5 340 250 2 4 4
## 4 4209 Zona … 02 5 350 300 3 5 6
## 5 4422 Zona … 02 5 350 240 2 3 6
## 6 4458 Zona … 02 4 315 270 2 4 4
## 7 4483 Zona … 02 5 342 250 1 4 6
## 8 1009 Zona … <NA> 5 250 243 1 4 5
## 9 1270 Zona … <NA> 5 350 203 2 2 5
## 10 3352 Zona … <NA> 4 335 300 3 4 4
## # ℹ 24 more rows
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Mapeo de registros que cumplen los requisitos
# Crea un mapa
map <- leaflet(ofertas_v1) %>%
addTiles() %>%
addMarkers(
lng = ~longitud,
lat = ~latitud,
popup = ~as.character(latitud)
)
map
De un total de 2566 casas en la zona norte, se obtienen 28 opciones de inmuebles que cumplen con los requisitos del cliente.
Extracion de datos relevantes para la solicitud
#Filtro por interes de la primera solicitud
base2 <- vivienda %>%
filter(tipo == "Apartamento", zona == "Zona Sur")
# Primeros 3 registros
head(base1, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1209 Zona N… 02 5 320 150 2 4 6
## 2 1592 Zona N… 02 5 780 380 2 3 3
## 3 4057 Zona N… 02 6 750 445 NA 7 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Comprobacion
table(vivienda$tipo, vivienda$zona)
##
## Zona Centro Zona Norte Zona Oeste Zona Oriente Zona Sur
## Apartamento 24 1198 1029 62 2787
## Casa 100 722 169 289 1939
table(base1$tipo)
##
## Casa
## 722
table(base1$zona)
##
## Zona Norte
## 722
Mapeo de registros
# Crea un mapa
map <- leaflet(base2) %>%
addTiles() %>%
addMarkers(
lng = ~longitud,
lat = ~latitud,
popup = ~as.character(latitud)
)
map
El mapa permite visualizar la distribución geográfica de las casas clasificadas en la zona norte. Sin embargo, se observa que algunos puntos aparecen fuera del límite geográfico esperado. Esto puede deberse a que la variable zona corresponde a una clasificación comercial utilizada por el mercado inmobiliario y no necesariamente a una delimitación geográfica estricta.
Analisis de correlacion
Var_cor <- data.frame(base2$preciom, base2$areaconst, base2$estrato, base2$banios, base2$habitaciones, base2$latitud, base2$longitud)
cor_matrix <- cor(Var_cor, use = "complete.obs")
plot_ly(
x = colnames(cor_matrix),
y = rownames(cor_matrix),
z = cor_matrix,
type = "heatmap",
colorscale = "RdBu"
)
El precio del apartamento en zona sur se relaciona fuerte y positivamente con el area construida, estrato y numero de baños. El numero de habitaciones se relacion debilmente con el precio de la vivienda. La latitud presena una relacion muy debil con el precio y la longitud una relacion debil con el precio.
Modelo de regresio lineal multiple
modelo_2 <- lm(preciom ~ areaconst + estrato + banios, data=base2)
summary(modelo_2)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios, data = base2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1392.66 -40.28 -4.91 38.08 967.21
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -322.37292 10.74722 -30.00 <2e-16 ***
## areaconst 1.60767 0.04888 32.89 <2e-16 ***
## estrato 72.96656 2.78093 26.24 <2e-16 ***
## banios 50.28422 2.93000 17.16 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 100.2 on 2783 degrees of freedom
## Multiple R-squared: 0.7267, Adjusted R-squared: 0.7264
## F-statistic: 2467 on 3 and 2783 DF, p-value: < 2.2e-16
El valor base del modelo cuando las demás variables son cero es de -286.05 millones. Por cada metro cuadrado adicional de área construida, el precio de la vivienda aumenta en promedio 1.90 millones de pesos, manteniendo constantes las demás variables. Un aumento de una unidad en el estrato socioeconómico incrementa el precio de la vivienda en promedio 66.77 millones de pesos, manteniendo constantes las demás variables. Por cada baño adicional incrementa el precio de la vivienda en aproximadamente 33.95 millones de pesos. Todos los coeficientes presentan valores p menores a 0.001, indicando que son estadísticamente significativos. El coeficiente de determinacion de 0.7714, es decir, el 77,14 % de la variabilidad del precio de las viviendas puede ser explicada por las variables incluidas en el modelo (área construida, estrato y número de baños). Este valor indica que el modelo tiene un buen nivel de ajuste, aunque todavía existe cerca del 23% de la variabilidad del precio que no está siendo explicada por el modelo. El modelo explica el 77% de la variabilidad del precio de la vivienda cuando se ajusta por el número de predictores incluidos.
Prediccion usando set de prueba
set.seed(2024)
train_index <- sample(1:nrow(base2), 0.8*nrow(base2))
train <- base2[train_index, ]
test <- base2[-train_index, ]
modelo2 <- lm(preciom ~ areaconst + estrato + banios, data = train)
pred <- predict(modelo2, newdata = test)
RMSE <- sqrt(mean((test$preciom - pred)^2))
MAE <- mean(abs(test$preciom - pred))
RMSE
## [1] 129.7196
MAE
## [1] 59.63868
El modelo tiene un error proedio aproximado de 129 millones de pesos en la prediccion del precio de la vivienda. Adicionalmente, las predicciones del modelo difieren del valor real en aproximadamente 59 millones.
Validacion de supuestos
residuos <- residuals(modelo_2)
MSE <- summary(modelo_2)$sigma^2
residuales_estandarizados <- residuos / sqrt(MSE)
Normalidad
shapiro.test(residuales_estandarizados)
##
## Shapiro-Wilk normality test
##
## data: residuales_estandarizados
## W = 0.77598, p-value < 2.2e-16
Los residuales del modelo no cumplen con el supuesto de normalidad. Homocedasticidad
gqtest(modelo_2)
##
## Goldfeld-Quandt test
##
## data: modelo_2
## GQ = 0.91786, df1 = 1390, df2 = 1389, p-value = 0.9449
## alternative hypothesis: variance increases from segment 1 to 2
En los residuales del modelo existe homocedasticidad, es decir, se cumple con el supuesto de homogeneidad de varianzas.
Independencia
dwtest(modelo_2)
##
## Durbin-Watson test
##
## data: modelo_2
## DW = 1.4924, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
Existe autocorrelacion positiva entre los residuos del modelo.
Los supuestos del modelo de regresión no se cumplen, las inferencias estadísticas pueden ser incorrectas. Es decir, los coeficientes pueden estimarse, pero las pruebas, intervalos de confianza y predicciones pueden ser poco confiables.
Prediccion
nueva_viv2 <- data.frame(
areaconst = 300,
estrato = 5.5,
habitaciones = 5,
parqueaderos = 3,
banios = 3
)
predict(modelo_2, newdata = nueva_viv2, interval = "prediction")
## fit lwr upr
## 1 712.0976 514.8402 909.3551
El valor predicho por el modelo es de 754 millones con precio minimo de 606 millones y maximo 902 millones.
Ofertas sugeridas
ofertas_v2 <- base2 %>%
filter(
estrato %in% c(5,6),
habitaciones >= 5,
banios >= 3,
parqueaderos >= 3,
preciom <= 850,
areaconst >=300)
ofertas_v2
## # A tibble: 2 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7182 Zona S… <NA> 5 730 573 3 8 5
## 2 7512 Zona S… <NA> 5 670 300 3 5 6
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Para la solicitud exacta recibida no hay ofertas que cumplan los requisitos, se sigiere flexibilizar el area construida.
ofertas_v2 <- base2 %>%
filter(
estrato %in% c(5,6),
habitaciones >= 5,
banios >= 3,
parqueaderos >= 3,
preciom <= 850,
areaconst >=200)
ofertas_v2
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7182 Zona S… <NA> 5 730 573 3 8 5
## 2 7512 Zona S… <NA> 5 670 300 3 5 6
## 3 8036 Zona S… <NA> 5 530 256 3 5 5
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
Mapeo de registros que cumplen los requisitos
# Crea un mapa
map <- leaflet(ofertas_v2) %>%
addTiles() %>%
addMarkers(
lng = ~longitud,
lat = ~latitud,
popup = ~as.character(latitud)
)
map
De un total de 2566 apartamentos en la zona Sur, se obtienen 3 opciones de inmuebles que cumplen con los requisitos del cliente.
Anexo A - Version de R y sistema operativo R version
4.5.2 (2025-10-31)
Sistema Operativo: macOS Tahoe 26.2
Anexo B - Paquetes devtools mice tidyverse factoextra cluster dplyr FactoMineR gridExtra paqueteMODELOS tcltk2 psych ggplot2 patchwork VIM leaflet corrplot plotly
Anexo C - Analisis exploratorio y limpieza de datos Dimensiones del dataset
dim(vivienda)
## [1] 8322 13
Se cuenta con un dataset de 8322 registros descritos por 13 variables.
Reconocimiento de la base de datos, en la cual se identificaron 8 variables cuantitativas (4 discretas y 4 continuas) y 4 variables cuantitativas (nominales principalmente). Sin embargo se identifica a su vez que la variable piso tiene datos faltantes y realmente es una variable cuantitativa discreta.
Identificacion correcta de piso
par(cex = 0.8)
md.pattern(vivienda)
## 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
par(cex = 1)
Se observa que 4808 registros tienen los datos completos para cada atributo, 1909 registros les falta el dato de piso, 876 les falta eel dato de parqueaderos, 726 les faltan ambos datos, existe un registro con un unido dato de precio y dos registros sin datos.
sum(duplicated(vivienda))
## [1] 1
Se identifica un registro duplicado.
summary(vivienda[c("piso", "estrato", "preciom", "areaconst", "parqueaderos", "banios","habitaciones", "latitud", "longitud")])
## piso estrato preciom areaconst
## Min. : 1.000 Min. :3.000 Min. : 58.0 Min. : 30.0
## 1st Qu.: 2.000 1st Qu.:4.000 1st Qu.: 220.0 1st Qu.: 80.0
## Median : 3.000 Median :5.000 Median : 330.0 Median : 123.0
## Mean : 3.771 Mean :4.634 Mean : 433.9 Mean : 174.9
## 3rd Qu.: 5.000 3rd Qu.:5.000 3rd Qu.: 540.0 3rd Qu.: 229.0
## Max. :12.000 Max. :6.000 Max. :1999.0 Max. :1745.0
## NA's :2638 NA's :3 NA's :2 NA's :3
## parqueaderos banios habitaciones latitud
## Min. : 1.000 Min. : 0.000 Min. : 0.000 Min. :3.333
## 1st Qu.: 1.000 1st Qu.: 2.000 1st Qu.: 3.000 1st Qu.:3.381
## Median : 2.000 Median : 3.000 Median : 3.000 Median :3.416
## Mean : 1.835 Mean : 3.111 Mean : 3.605 Mean :3.418
## 3rd Qu.: 2.000 3rd Qu.: 4.000 3rd Qu.: 4.000 3rd Qu.:3.452
## Max. :10.000 Max. :10.000 Max. :10.000 Max. :3.498
## NA's :1605 NA's :3 NA's :3 NA's :3
## longitud
## Min. :-76.59
## 1st Qu.:-76.54
## Median :-76.53
## Mean :-76.53
## 3rd Qu.:-76.52
## Max. :-76.46
## NA's :3
describe(vivienda[c("piso", "estrato", "preciom", "areaconst", "parqueaderos", "banios","habitaciones", "latitud", "longitud")])
## vars n mean sd median trimmed mad min max
## piso 1 5684 3.77 2.61 3.00 3.37 1.48 1.00 12.00
## estrato 2 8319 4.63 1.03 5.00 4.67 1.48 3.00 6.00
## preciom 3 8320 433.89 328.65 330.00 374.43 207.56 58.00 1999.00
## areaconst 4 8319 174.93 142.96 123.00 149.15 84.51 30.00 1745.00
## parqueaderos 5 6717 1.84 1.12 2.00 1.62 1.48 1.00 10.00
## banios 6 8319 3.11 1.43 3.00 2.99 1.48 0.00 10.00
## habitaciones 7 8319 3.61 1.46 3.00 3.41 1.48 0.00 10.00
## latitud 8 8319 3.42 0.04 3.42 3.42 0.05 3.33 3.50
## longitud 9 8319 -76.53 0.02 -76.53 -76.53 0.02 -76.59 -76.46
## range skew kurtosis se
## piso 11.00 1.28 1.05 0.03
## estrato 3.00 -0.18 -1.11 0.01
## preciom 1941.00 1.85 3.67 3.60
## areaconst 1715.00 2.69 12.91 1.57
## parqueaderos 9.00 2.33 8.31 0.01
## banios 10.00 0.93 1.13 0.02
## habitaciones 10.00 1.63 3.98 0.02
## latitud 0.16 0.03 -1.15 0.00
## longitud 0.13 0.65 0.58 0.00
Se identifica que el estrato promedio es 4.63 con un costo promedio de 433, en un tercer piso con area construida 174, 1.84 parquederos, 3.11 baños, 3.61 habitaciones.
p1 <- ggplot(vivienda, aes(y = estrato)) +
geom_boxplot(fill="lightblue",
outlier.color = "red",
outlier.size = 1.5) +
ggtitle("Estrato")+
theme(
plot.title = element_text(size = 10,hjust = 0.5))
p2 <- ggplot(vivienda, aes(y = preciom)) +
geom_boxplot(fill="lightblue",
outlier.color = "red",
outlier.size = 1.5) +
ggtitle("Precio")+
theme(
plot.title = element_text(size = 10,hjust = 0.5))
p3 <- ggplot(vivienda, aes(y = areaconst)) +
geom_boxplot(fill="lightblue",
outlier.color = "red",
outlier.size = 1.5) +
ggtitle("Área Construida")+
theme(
plot.title = element_text(size = 10,hjust = 0.5))
p4 <- ggplot(vivienda, aes(y = parqueaderos)) +
geom_boxplot(fill="lightblue",
outlier.color = "red",
outlier.size = 1.5) +
ggtitle("Numero de parqueaderos")+
theme(
plot.title = element_text(size = 10,hjust = 0.5))
p5 <- ggplot(vivienda, aes(y = banios)) +
geom_boxplot(fill="lightblue",
outlier.color = "red",
outlier.size = 1.5) +
ggtitle("Numero de baños")+
theme(
plot.title = element_text(size = 10,hjust = 0.5))
p6 <- ggplot(vivienda, aes(y = habitaciones)) +
geom_boxplot(fill="lightblue",
outlier.color = "red",
outlier.size = 1.5) +
ggtitle("Numero de habitaciones")+
theme(
plot.title = element_text(size = 10,hjust = 0.5))
p7 <- ggplot(vivienda, aes(y = longitud)) +
geom_boxplot(fill="lightblue",
outlier.color = "red",
outlier.size = 1.5) +
ggtitle("Longitud")+
theme(
plot.title = element_text(size = 10,hjust = 0.5))
p8 <- ggplot(vivienda, aes(y = latitud)) +
geom_boxplot(fill="lightblue",
outlier.color = "red",
outlier.size = 1.5) +
ggtitle("Latitud")+
theme(
plot.title = element_text(size = 10,hjust = 0.5))
(p1 | p2 | p3 | p4) /
(p5 | p6 | p7 | p8)
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Warning: Removed 2 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Warning: Removed 1605 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
## Removed 3 rows containing non-finite outside the scale range
## (`stat_boxplot()`).
Se identifican outliers en las variables cuantitativas: precio, area construida, numero de parqueaderos, numero de habitaciones y longitud.
lapply(vivienda[c("zona", "tipo", "barrio")], function(x) {
sort(table(x), decreasing = TRUE)[1]
})
## $zona
## Zona Sur
## 4726
##
## $tipo
## Apartamento
## 5100
##
## $barrio
## valle del lili
## 1008
Se identifica que las viviendas disponibles comercialmente se encuentran en la zona zur, tipo apartamento en el Valle de Lili.
p1<-ggplot(vivienda, aes(x = zona)) +
geom_bar(fill = "lightblue") +
theme_minimal() +
theme(axis.text.x = element_text(size=8, angle = 90, hjust = 1)) +
labs(title = "Distribución por Zona",
x = "Zona",
y = "Frecuencia")
p2<-ggplot(vivienda, aes(x = tipo)) +
geom_bar(fill = "lightblue") +
theme_minimal() +
theme(axis.text.x = element_text(size=8, angle = 90, hjust = 1)) +
labs(title = "Distribución por tipo de vivienda",
x = "Vivienda",
y = "Frecuencia")
p3<-ggplot(vivienda, aes(x = barrio)) +
geom_bar(fill = "lightblue") +
theme_minimal() +
theme(axis.text.x = element_text(size=1, angle = 90, hjust = 1)) +
labs(title = "Distribución por barrio",
x = "Barrio",
y = "Frecuencia")
(p1 | p2 ) /
(p3)
Se identifica que la zona y el tipo de vivenda tienen datos faltantes, la zona centro tiene baja frecuencia y podria considerarse dato atipico.
Preprocesamiento de datos 1. Eliminacion de duplicados
vivienda <- vivienda[!duplicated(vivienda), ]
sum(duplicated(vivienda))
## [1] 0
2. Manejo de datos faltantes 2.1 Eliminar registros con mas de dos datos faltantes
na_fila <- rowSums(is.na(vivienda))
vivienda <- vivienda[na_fila < 2, ]
2.3 Imputacion de datos a registros con 1 a 2 datos faltantes
vivienda <- kNN(vivienda, variable = c("piso", "parqueaderos"), k = 10)
par(cex = 0.8)
md.pattern(vivienda)
## /\ /\
## { `---' }
## { O O }
## ==> V <== No need for mice. This data set is completely observed.
## \ \|/ /
## `-----'
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## 7593 1 1 1 1 1 1 1 1 1
## 0 0 0 0 0 0 0 0 0
## tipo barrio longitud latitud piso_imp parqueaderos_imp
## 7593 1 1 1 1 1 1 0
## 0 0 0 0 0 0 0
par(cex = 1)
3. Manejo de datos atipicos 3.1 Eliminacion de datos atipicos en variables cualitativas
vivienda <- vivienda[vivienda$zona != "Zona Centro", ]
3.2 Eliminacion de outliers en variables cuantitativas
variables_cuantitativas <- c("piso", "estrato", "preciom", "areaconst", "parqueaderos", "banios","habitaciones", "latitud", "longitud")
limites <- t(sapply(variables_cuantitativas, function(v) {
x <- vivienda[[v]]
Primer_cuartil<- quantile(x, 0.25)
Tercer_cuartil <- quantile(x, 0.75)
RIC <- IQR(x)
c(lim_inf = Primer_cuartil - 1.5*RIC, lim_sup = Tercer_cuartil + 1.5*RIC)
}))
vivienda<- vivienda[
vivienda$estrato >= limites["estrato","lim_inf.25%"] &
vivienda$estrato <= limites["estrato","lim_sup.75%"] &
vivienda$preciom >= limites["preciom","lim_inf.25%"] &
vivienda$preciom <= limites["preciom","lim_sup.75%"] &
vivienda$areaconst >= limites["areaconst","lim_inf.25%"] &
vivienda$areaconst <= limites["areaconst","lim_sup.75%"] &
vivienda$parqueaderos >= limites["parqueaderos","lim_inf.25%"] &
vivienda$parqueaderos <= limites["parqueaderos","lim_sup.75%"] &
vivienda$banios >= limites["banios","lim_inf.25%"] &
vivienda$banios <= limites["banios","lim_sup.75%"] &
vivienda$habitaciones >= limites["habitaciones","lim_inf.25%"] &
vivienda$habitaciones <= limites["habitaciones","lim_sup.75%"] &
vivienda$latitud >= limites["latitud","lim_inf.25%"] &
vivienda$latitud <= limites["latitud","lim_sup.75%"] &
vivienda$longitud >= limites["longitud","lim_inf.25%"] &
vivienda$longitud <= limites["longitud","lim_sup.75%"],
]
dim(vivienda)
## [1] 5944 15
vivienda <- vivienda[, !(names(vivienda) %in% c("piso_imp", "parqueaderos_imp"))]
Posterior al pretratamiento de los datos se obtiene un dataset con 5944 registros y 15 atributos.