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.
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).
library(dplyr)
##
## Attaching package: 'dplyr'
## The following object is masked from 'package:gridExtra':
##
## combine
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(plotly)
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
library(ggplot2)
library(leaflet)
library(sf)
## Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1; sf_use_s2() is TRUE
library(sp)
library(corrplot)
## corrplot 0.95 loaded
# Cargar y revisar el dataset "vivienda"
data("vivienda")
# attach(vivienda) - evitado para estabilidad
str(vivienda)
## spc_tbl_ [8,322 × 13] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:8322] 1147 1169 1350 5992 1212 ...
## $ zona : chr [1:8322] "Zona Oriente" "Zona Oriente" "Zona Oriente" "Zona Sur" ...
## $ piso : chr [1:8322] NA NA NA "02" ...
## $ estrato : num [1:8322] 3 3 3 4 5 5 4 5 5 5 ...
## $ preciom : num [1:8322] 250 320 350 400 260 240 220 310 320 780 ...
## $ areaconst : num [1:8322] 70 120 220 280 90 87 52 137 150 380 ...
## $ parqueaderos: num [1:8322] 1 1 2 3 1 1 2 2 2 2 ...
## $ banios : num [1:8322] 3 2 2 5 2 3 2 3 4 3 ...
## $ habitaciones: num [1:8322] 6 3 4 3 3 3 3 4 6 3 ...
## $ tipo : chr [1:8322] "Casa" "Casa" "Casa" "Casa" ...
## $ barrio : chr [1:8322] "20 de julio" "20 de julio" "20 de julio" "3 de julio" ...
## $ longitud : num [1:8322] -76.5 -76.5 -76.5 -76.5 -76.5 ...
## $ latitud : num [1:8322] 3.43 3.43 3.44 3.44 3.46 ...
## - attr(*, "spec")=List of 3
## ..$ cols :List of 13
## .. ..$ id : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ zona : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ piso : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ estrato : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ preciom : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ areaconst : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ parqueaderos: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ banios : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ habitaciones: list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ tipo : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ barrio : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_character" "collector"
## .. ..$ longitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## .. ..$ latitud : list()
## .. .. ..- attr(*, "class")= chr [1:2] "collector_double" "collector"
## ..$ default: list()
## .. ..- attr(*, "class")= chr [1:2] "collector_guess" "collector"
## ..$ delim : chr ";"
## ..- attr(*, "class")= chr "col_spec"
## - attr(*, "problems")=<externalptr>
head(vivienda)
## # A tibble: 6 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1147 Zona O… <NA> 3 250 70 1 3 6
## 2 1169 Zona O… <NA> 3 320 120 1 2 3
## 3 1350 Zona O… <NA> 3 350 220 2 2 4
## 4 5992 Zona S… 02 4 400 280 3 5 3
## 5 1212 Zona N… 01 5 260 90 1 2 3
## 6 1724 Zona N… 01 5 240 87 1 3 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
summary(vivienda)
## id zona piso estrato
## Min. : 1 Length:8322 Length:8322 Min. :3.000
## 1st Qu.:2080 Class :character Class :character 1st Qu.:4.000
## Median :4160 Mode :character Mode :character Median :5.000
## Mean :4160 Mean :4.634
## 3rd Qu.:6240 3rd Qu.:5.000
## Max. :8319 Max. :6.000
## NA's :3 NA's :3
## preciom areaconst parqueaderos banios
## Min. : 58.0 Min. : 30.0 Min. : 1.000 Min. : 0.000
## 1st Qu.: 220.0 1st Qu.: 80.0 1st Qu.: 1.000 1st Qu.: 2.000
## Median : 330.0 Median : 123.0 Median : 2.000 Median : 3.000
## Mean : 433.9 Mean : 174.9 Mean : 1.835 Mean : 3.111
## 3rd Qu.: 540.0 3rd Qu.: 229.0 3rd Qu.: 2.000 3rd Qu.: 4.000
## Max. :1999.0 Max. :1745.0 Max. :10.000 Max. :10.000
## NA's :2 NA's :3 NA's :1605 NA's :3
## habitaciones tipo barrio longitud
## Min. : 0.000 Length:8322 Length:8322 Min. :-76.59
## 1st Qu.: 3.000 Class :character Class :character 1st Qu.:-76.54
## Median : 3.000 Mode :character Mode :character Median :-76.53
## Mean : 3.605 Mean :-76.53
## 3rd Qu.: 4.000 3rd Qu.:-76.52
## Max. :10.000 Max. :-76.46
## NA's :3 NA's :3
## latitud
## Min. :3.333
## 1st Qu.:3.381
## Median :3.416
## Mean :3.418
## 3rd Qu.:3.452
## Max. :3.498
## NA's :3
table(vivienda$zona,vivienda$tipo)
##
## Apartamento Casa
## Zona Centro 24 100
## Zona Norte 1198 722
## Zona Oeste 1029 169
## Zona Oriente 62 289
## Zona Sur 2787 1939
# Filtrar solo casas en diferentes zonas
base1 <- vivienda %>% filter(tipo == "Casa" & zona == "Zona Norte")
base2 <- vivienda %>% filter(tipo == "Casa" & zona == "Zona Centro")
base3 <- vivienda %>% filter(tipo == "Casa" & zona == "Zona Oeste")
base4 <- vivienda %>% filter(tipo == "Casa" & zona == "Zona Oriente")
base5 <- vivienda %>% filter(tipo == "Casa" & zona == "Zona Sur")
# Verificar la cantidad de registros en cada base
nrow(base1); nrow(base2); nrow(base3); nrow(base4); nrow(base5)
## [1] 722
## [1] 100
## [1] 169
## [1] 289
## [1] 1939
Se muestran los 3 primeros registros de cada base
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>
head(base2, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 5298 Zona C… 01 3 650 240 2 4 4
## 2 5107 Zona C… 02 4 400 460 NA 5 7
## 3 5117 Zona C… 02 3 380 290 NA 4 8
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
head(base3, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 6928 Zona O… 03 6 1850 302 4 4 3
## 2 7510 Zona O… 03 6 1950 400 4 5 3
## 3 7586 Zona O… 03 6 870 275 3 5 4
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
head(base4, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1147 Zona O… <NA> 3 250 70 1 3 6
## 2 1169 Zona O… <NA> 3 320 120 1 2 3
## 3 1350 Zona O… <NA> 3 350 220 2 2 4
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
head(base5, 3)
## # A tibble: 3 × 13
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 5992 Zona S… 02 4 400 280 3 5 3
## 2 5157 Zona S… 02 3 500 354 1 2 4
## 3 5501 Zona S… 02 3 175 102 NA 2 4
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Crear una lista con los primeros 3 registros de cada base
bases_lista <- list(
"Zona Norte" = head(base1, 3),
"Zona Centro" = head(base2, 3),
"Zona Oeste" = head(base3, 3),
"Zona Oriente" = head(base4, 3),
"Zona Sur" = head(base5, 3)
)
# Unir todas las bases en un solo dataframe
resultados <- bind_rows(bases_lista, .id = "Zona")
# Crear una tabla interactiva con Plotly
tabla_interactiva <- plot_ly(
type = "table",
header = list(values = colnames(resultados), align = "center"),
cells = list(values = t(as.matrix(resultados)), align = "center")
)
# Mostrar la tabla interactiva con los 3 primeros registros
tabla_interactiva
# Unir todas las bases en un solo dataframe
map_data <- bind_rows(
base1 %>% mutate(Zona = "Zona Norte"),
base2 %>% mutate(Zona = "Zona Centro"),
base3 %>% mutate(Zona = "Zona Oeste"),
base4 %>% mutate(Zona = "Zona Oriente"),
base5 %>% mutate(Zona = "Zona Sur")
)
# Verificar si existen coordenadas en la base
head(map_data)
## # A tibble: 6 × 14
## 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 4460 Zona N… 02 4 625 355 3 5 5
## 5 6081 Zona N… 02 5 750 237 2 6 6
## 6 7824 Zona N… 02 4 600 160 1 4 5
## # ℹ 5 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>,
## # Zona <chr>
# Si no hay columnas de latitud y longitud, agregar manualmente algunas coordenadas ficticias
# (esto debe reemplazarse con datos reales)
if (!("latitud" %in% colnames(map_data) & "longitud" %in% colnames(map_data))) {
set.seed(123) # Para reproducibilidad
map_data <- map_data %>%
mutate(
latitud = runif(n(), min = 3.35, max = 3.45), # Rango aproximado de Cali
longitud = runif(n(), min = -76.55, max = -76.45)
)
}
# Definir colores para cada zona
colores <- colorFactor(
palette = c("red", "blue", "green", "purple", "orange"),
domain = map_data$Zona
)
# Crear el mapa interactivo
mapa <- leaflet(map_data) %>%
addTiles() %>% # Agregar mapa base
addCircleMarkers(
~longitud, ~latitud,
color = ~colores(Zona),
popup = ~paste("Zona:", Zona, "<br>Precio:", preciom),
radius = 5,
stroke = FALSE,
fillOpacity = 0.8
) %>%
addLegend(
"bottomright",
pal = colores,
values = ~Zona,
title = "Zonas de Cali",
opacity = 1
)
# Mostrar el mapa
mapa
# Filtrar datos relevantes (para evitar valores faltantes o anomalías)
vivienda_clean <- vivienda %>%
filter(!is.na(preciom) & !is.na(areaconst) & !is.na(estrato) &
!is.na(banios) & !is.na(habitaciones) & !is.na(zona))
# 1. Correlación entre variables numéricas
correlation_matrix <- cor(vivienda_clean[, c("preciom", "areaconst", "banios", "habitaciones")])
# Graficamos la matriz de correlación
corrplot(correlation_matrix, method = "circle", type = "upper",
order = "hclust", col = colorRampPalette(c("blue", "white", "red"))(200))
# 2. Visualización interactiva de la relación entre el precio y el área construida
grafico_area_precio <- plot_ly(vivienda_clean, x = ~areaconst, y = ~preciom,
type = 'scatter', mode = 'markers',
marker = list(color = 'blue')) %>%
layout(title = 'Precio vs Área Construida',
xaxis = list(title = 'Área Construida (m²)'),
yaxis = list(title = 'Precio de la Casa'))
grafico_area_precio
# 3. Visualización de la relación entre el precio y el número de baños
grafico_baños_precio <- plot_ly(vivienda_clean, x = ~banios, y = ~preciom,
type = 'scatter', mode = 'markers',
marker = list(color = 'green')) %>%
layout(title = 'Precio vs Número de Baños',
xaxis = list(title = 'Número de Baños'),
yaxis = list(title = 'Precio de la Casa'))
grafico_baños_precio
# 4. Visualización de la relación entre el precio y el número de habitaciones
grafico_habitaciones_precio <- plot_ly(vivienda_clean, x = ~habitaciones, y = ~preciom,
type = 'scatter', mode = 'markers',
marker = list(color = 'red')) %>%
layout(title = 'Precio vs Número de Habitaciones',
xaxis = list(title = 'Número de Habitaciones'),
yaxis = list(title = 'Precio de la Casa'))
grafico_habitaciones_precio
# 5. Visualización de la relación entre el precio y la zona
grafico_zona_precio <- plot_ly(vivienda_clean, x = ~zona, y = ~preciom,
type = 'box',
boxmean = TRUE) %>%
layout(title = 'Precio por Zona',
xaxis = list(title = 'Zona'),
yaxis = list(title = 'Precio de la Casa'))
grafico_zona_precio
# 1. Visualización de la relación entre el precio y el estrato
grafico_estrato_precio <- plot_ly(vivienda_clean, x = ~estrato, y = ~preciom,
type = 'box',
boxmean = TRUE) %>%
layout(title = 'Precio por Estrato',
xaxis = list(title = 'Estrato'),
yaxis = list(title = 'Precio de la Casa'))
# Mostrar gráfico
grafico_estrato_precio
La matriz de correlación muestra que tan fuerte se relacionan las variables entre sí. Por ejemplo, si la correlación entre Precio y Área Construida es alta, significa que a medida que aumenta el área, también lo hace el precio de la casa. De igual forma, otras variables como NroBaños y NroHabitaciones pueden tener una correlación significativa con el precio.
Gráfico de Precio vs Área Construida: Este gráfico puede mostrar una tendencia clara de que el precio de la casa aumenta con el área construida. Una relación lineal o no lineal podría ser visible.
Gráfico de Precio vs Número de Baños: Aquí se puede observar que, aunque tener más baños generalmente podría implicar un precio más alto, el efecto podría ser menor comparado con el área construida.
Gráfico de Precio vs Número de Habitaciones: Similar al gráfico de baños, pero puede haber una relación más directa con el tipo de vivienda.
Gráfico de Precio por Zona: Un gráfico de caja permite ver cómo varía el precio dentro de cada zona. Por ejemplo, las casas en zonas más exclusivas pueden tener precios mucho más altos que en zonas menos centrales.
De igual forma gráfico de caja muestra cómo se distribuye el precio de las viviendas en función del estrato. Si existe una relación entre estrato y precio, se espera ver una tendencia en la que los estratos más altos tengan precios más elevados, mientras que los estratos más bajos presenten precios más bajos. Además, el gráfico permite identificar la mediana del precio para cada estrato, la dispersión de los precios dentro de cada grupo y posibles valores atípicos (precios extremadamente altos o bajos). Esto sugiere que el estrato puede ser un factor clave para determinar el precio de la vivienda.
Este análisis exploratorio permite obtener una visión inicial de las relaciones entre las variables, lo cual es útil para determinar qué variables podrían ser más relevantes en un modelo predictivo o de regresión para estimar el precio de una casa.
# Ajustar el modelo de regresión lineal múltiple
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios, data = vivienda)
# Ver resumen del modelo
summary(modelo)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + habitaciones + parqueaderos +
## banios, data = vivienda)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1412.57 -88.36 -17.55 56.24 1101.38
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -380.7629 14.3638 -26.51 <2e-16 ***
## areaconst 0.8510 0.0222 38.33 <2e-16 ***
## estrato 97.9107 2.8342 34.55 <2e-16 ***
## habitaciones -31.2744 2.2613 -13.83 <2e-16 ***
## parqueaderos 74.4922 2.5900 28.76 <2e-16 ***
## banios 61.0554 2.6271 23.24 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 177.2 on 6711 degrees of freedom
## (1605 observations deleted due to missingness)
## Multiple R-squared: 0.7206, Adjusted R-squared: 0.7204
## F-statistic: 3462 on 5 and 6711 DF, p-value: < 2.2e-16
# Cargar librerías necesarias
library(ggplot2) # Para gráficos
library(car) # Para la prueba de multicolinealidad (VIF)
## Loading required package: carData
##
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
## The following object is masked from 'package:boot':
##
## logit
# 1. Graficar los residuos vs. los valores ajustados (verificación de linealidad y homoscedasticidad)
plot(modelo$fitted.values, modelo$residuals,
main = "Residuos vs. Valores Ajustados",
xlab = "Valores Ajustados",
ylab = "Residuos",
pch = 19, col = "blue")
abline(h = 0, col = "red")
# 2. Graficar el histograma de los residuos (verificación de normalidad)
hist(modelo$residuals,
main = "Histograma de los Residuos",
xlab = "Residuos",
col = "blue",
border = "black",
breaks = 20)
# 3. Graficar el Q-Q plot (verificación de normalidad)
qqnorm(modelo$residuals, main = "Q-Q Plot de los Residuos")
qqline(modelo$residuals, col = "red")
# 4. Prueba de independencia de los errores (Durbin-Watson Test)
library(lmtest)
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
dwtest(modelo)
##
## Durbin-Watson test
##
## data: modelo
## DW = 1.6081, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
# 5. Prueba de multicolinealidad (VIF)
vif(modelo)
## areaconst estrato habitaciones parqueaderos banios
## 2.190532 1.549549 2.036909 1.816620 2.813537
# Suponiendo que ya tienes el modelo entrenado:
modelo <- lm(preciom ~ areaconst + estrato + habitaciones + parqueaderos + banios,
data = vivienda_clean)
# Crear un data frame para la(s) nueva(s) casa(s)
nuevas_casas <- data.frame(
areaconst = c(200, 200),
estrato = c(4, 5), # Se incluyen las dos opciones en filas separadas
habitaciones = c(4, 4),
parqueaderos = c(1, 1), # Suponiendo 1 parqueadero si no se especifica
banios = c(2, 2)
)
# Predecir el precio para cada fila de 'nuevas_casas'
predicciones <- predict(modelo, newdata = nuevas_casas)
# Ver resultados
names(predicciones) <- c("Estrato 4", "Estrato 5")
predicciones
## Estrato 4 Estrato 5
## 252.5860 350.4967
# Cargar librerías necesarias
library(ggplot2)
library(leaflet)
# Generar 5 viviendas en la zona norte de Cali
set.seed(123) # Fijar semilla para reproducibilidad
nuevas_casas <- data.frame(
areaconst = rep(200, 5), # Área construida fija
estrato = sample(4:5, 5, replace = TRUE), # Estrato 4 o 5 aleatorio
habitaciones = rep(4, 5),
parqueaderos = rep(1, 5),
banios = rep(2, 5)
)
# Predecir el precio de estas viviendas
predicciones <- predict(modelo, newdata = nuevas_casas)
# Filtrar solo viviendas con precio < 350
ofertas <- nuevas_casas[predicciones < 350, ]
precios_filtrados <- predicciones[predicciones < 350]
# Generar coordenadas aleatorias dentro de la Zona Norte de Cali
# Coordenadas aproximadas de la zona norte de Cali
lat_norte <- runif(nrow(ofertas), min = 3.470, max = 3.490)
lon_norte <- runif(nrow(ofertas), min = -76.530, max = -76.500)
# Crear un data frame final con coordenadas y precios
mapa_ofertas <- data.frame(
lat = lat_norte,
lon = lon_norte,
precio = precios_filtrados
)
# Graficar en un mapa interactivo con etiquetas de precio
leaflet(mapa_ofertas) %>%
addTiles() %>%
addMarkers(~lon, ~lat,
label = ~paste("Precio: $", round(precio, 2), "M"),
popup = ~paste("Estrato:", ofertas$estrato, "<br>",
"Área:", ofertas$areaconst, "m²", "<br>",
"Baños:", ofertas$banios, "<br>",
"Habitaciones:", ofertas$habitaciones)
)
# Filtrar solo Apartamentos en diferentes zonas
base1 <- vivienda %>% filter(tipo == "Apartamento" & zona == "Zona Norte")
base2 <- vivienda %>% filter(tipo == "Apartamento" & zona == "Zona Centro")
base3 <- vivienda %>% filter(tipo == "Apartamento" & zona == "Zona Oeste")
base4 <- vivienda %>% filter(tipo == "Apartamento" & zona == "Zona Oriente")
base5 <- vivienda %>% filter(tipo == "Apartamento" & zona == "Zona Sur")
# Crear una lista con los primeros 3 registros de cada base
bases_lista <- list(
"Zona Norte" = head(base1, 3),
"Zona Centro" = head(base2, 3),
"Zona Oeste" = head(base3, 3),
"Zona Oriente" = head(base4, 3),
"Zona Sur" = head(base5, 3)
)
# Unir todas las bases en un solo dataframe
resultados <- bind_rows(bases_lista, .id = "Zona")
# Crear una tabla interactiva con Plotly
tabla_interactiva <- plot_ly(
type = "table",
header = list(values = colnames(resultados), align = "center"),
cells = list(values = t(as.matrix(resultados)), align = "center")
)
# Mostrar la tabla interactiva con los 3 primeros registros
tabla_interactiva
# Con el objetivo de hacer que los datos sean más fáciles de entender, creamos un histograma. Esto nos permite ver la distribución de los datos de manera más clara y efectiva."
# Creamos un vector con las zonas de interés
zonas <- c("Zona Centro", "Zona Norte", "Zona Sur", "Zona Oriente", "Zona Oeste")
# Filtramos la base de datos para que solo contenga apartamentos de las zonas indicadas
base_1 <- subset(vivienda, zona %in% zonas & tipo == "Apartamento")
# Cuenta el número de apartamentos por zona
n_apartamentos_por_zona <- base_1 %>%
group_by(zona) %>%
summarise(n = n())
# Crea un vector con los colores
colores <- c("blue", "red", "green", "yellow", "orange")
# Crea el gráfico de barras
ggplot(n_apartamentos_por_zona, aes(x = zona, y = n)) +
geom_bar(stat = "identity", fill = colores) +
theme_light() +
xlab("Zona") +
ylab("Número de apartamentos")
# CREAMOS BOXPLOT
# Filtramos la base de datos para que solo contenga apartamentos de las zonas indicadas
base_1 <- subset(vivienda, zona %in% zonas & tipo == "Apartamento")
# Crea un vector con los colores
colores <- c("blue", "red", "green", "yellow", "orange")
# Crea el gráfico de boxplot
ggplot(base_1, aes(x = zona, y = preciom)) +
geom_boxplot(fill = colores) +
theme_light() +
xlab("Zona") +
ylab("Precio de venta")
# Filtra los apartamentos
df_apartamentos <- vivienda %>%
filter(tipo == "Apartamento")
# Agrupa los apartamentos por zona
df_apartamentos_por_zona <- df_apartamentos %>%
group_by(zona)
# Cuenta el número de apartamentos por zona
n_apartamentos_por_zona <- df_apartamentos_por_zona %>%
summarise(n = n())
# Genera una tabla con los 3 primeros registros de cada grupo
tabla_apartamentos <- df_apartamentos_por_zona %>%
do(head(., 3))
# Muestra la tabla
tabla_apartamentos
## # A tibble: 15 × 13
## # Groups: zona [5]
## id zona piso estrato preciom areaconst parqueaderos banios habitaciones
## <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 4654 Zona … 03 3 100 70 NA 2 3
## 2 4408 Zona … 05 3 120 84 1 2 3
## 3 4395 Zona … 04 3 125 66.8 NA 2 3
## 4 1212 Zona … 01 5 260 90 1 2 3
## 5 1724 Zona … 01 5 240 87 1 3 3
## 6 2326 Zona … 01 4 220 52 2 2 3
## 7 6999 Zona … 01 6 870 200 2 5 3
## 8 8037 Zona … 01 4 130 50 NA 1 3
## 9 8055 Zona … 01 4 165 61 1 2 3
## 10 82 Zona … 01 3 115 111 1 2 4
## 11 78 Zona … 02 3 58 50 1 1 2
## 12 999 Zona … 02 3 135 120 NA 2 4
## 13 5098 Zona … 05 4 290 96 1 2 3
## 14 698 Zona … 02 3 78 40 1 1 2
## 15 8199 Zona … <NA> 6 875 194 2 5 3
## # ℹ 4 more variables: tipo <chr>, barrio <chr>, longitud <dbl>, latitud <dbl>
# Creamos un mapa con los puntos de las bases
suppressMessages(library(ggplot2))
suppressMessages(library(shiny))
suppressMessages(library(tidyverse))
zonas <- c("Zona Centro", "Zona Norte", "Zona Sur", "Zona Oriente", "Zona Oeste")
colores <- c("blue", "red", "green", "yellow", "orange")
ggplot(vivienda, aes(x = longitud, y = latitud, color = zona)) +
geom_point(alpha = 0.3) +
scale_color_manual(values = colores)
## Warning: Removed 3 rows containing missing values or values outside the scale range
## (`geom_point()`).
# Calculamos la matriz de correlación para las variables de interés
correlaciones <- cor(base2[,c( 'preciom','areaconst', 'estrato', 'banios', 'habitaciones')], use = "complete.obs")
# Visualización de la matriz de correlación
plot_ly(z = correlaciones, x = colnames(correlaciones), y = colnames(correlaciones), type = "heatmap")
suppressMessages(library(paqueteMODELOS))
suppressMessages(data("vivienda"))
# Filtrar apartamentos
df_apartamentos <- vivienda %>%
filter(tipo == "Apartamento")
# Seleccionar variables de interés
variables <- c("preciom", "areaconst", "estrato", "banios", "habitaciones")
# Crear una matriz de correlación para apartamentos
matriz_correlacion_apartamentos <- round(cor(df_apartamentos[variables]), 2)
# Gráfico de dispersión Precio vs. Área Construida para apartamentos
ggplot(df_apartamentos, aes(x = areaconst, y = preciom)) +
geom_point(aes(color = areaconst), alpha = 0.7) +
labs(title = "Precio vs. Área Construida (Apartamentos)", x = "Área Construida", y = "Precio") +
theme_minimal()
# Gráfico de dispersión Precio vs. Estrato para apartamentos
ggplot(df_apartamentos, aes(x = estrato, y = preciom)) +
geom_point(aes(color = estrato), alpha = 0.7) +
labs(title = "Precio vs. Estrato (Apartamentos)", x = "Estrato", y = "Precio") +
theme_minimal()
# Gráfico de dispersión Precio vs. Estrato para apartamentos
ggplot(df_apartamentos, aes(x = estrato, y = preciom)) +
geom_point(aes(color = estrato), alpha = 0.7) +
labs(title = "Precio vs. Estrato (Apartamentos)", x = "Estrato", y = "Precio") +
theme_minimal()
# Gráfico de dispersión Precio vs. Número de Habitaciones para apartamentos
ggplot(df_apartamentos, aes(x = habitaciones, y = preciom)) +
geom_point(aes(color = habitaciones), alpha = 0.7) +
labs(title = "Precio vs. Número de Habitaciones (Apartamentos)", x = "Número de Habitaciones", y = "Precio") +
theme_minimal()
x#### # Imprimir la matriz de correlación para apartamentos matriz_correlacion_apartamentos/(dimensiones)
# Imprimir la matriz de correlación para apartamentos
matriz_correlacion_apartamentos
## preciom areaconst estrato banios habitaciones
## preciom 1.00 0.83 0.67 0.74 0.30
## areaconst 0.83 1.00 0.55 0.73 0.41
## estrato 0.67 0.55 1.00 0.62 0.18
## banios 0.74 0.73 0.62 1.00 0.50
## habitaciones 0.30 0.41 0.18 0.50 1.00
# Estimar un modelo de regresión lineal múltiple con las variables del punto anterior
df_apartamentos_por_zona<- lm(preciom ~ areaconst + estrato + banios + habitaciones, data = vivienda)
# Resumen del modelo
summary(df_apartamentos_por_zona)
##
## Call:
## lm(formula = preciom ~ areaconst + estrato + banios + habitaciones,
## data = vivienda)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1713.69 -92.48 -20.01 58.45 1154.29
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -379.5673 11.7870 -32.20 <2e-16 ***
## areaconst 1.0697 0.0188 56.89 <2e-16 ***
## estrato 111.6148 2.3759 46.98 <2e-16 ***
## banios 67.7328 2.2695 29.84 <2e-16 ***
## habitaciones -28.1710 1.9294 -14.60 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 181 on 8314 degrees of freedom
## (3 observations deleted due to missingness)
## Multiple R-squared: 0.6969, Adjusted R-squared: 0.6967
## F-statistic: 4778 on 4 and 8314 DF, p-value: < 2.2e-16
#Gráfico de residuos vs. valores ajustados
plot(df_apartamentos_por_zona$residuals ~ df_apartamentos_por_zona$fitted.values)
#Gráfico Q-Q de los residuos
qqnorm(df_apartamentos_por_zona$residuals)
# Prueba de Durbin-Watson para autocorrelación de primer orden
suppressMessages(library(lmtest))
dwtest(df_apartamentos_por_zona)
##
## Durbin-Watson test
##
## data: df_apartamentos_por_zona
## DW = 1.5964, p-value < 2.2e-16
## alternative hypothesis: true autocorrelation is greater than 0
predict(df_apartamentos_por_zona,list(areaconst = 300,parqueaderos = 3, banios = 3,
habitaciones = 5, estrato = 5)) # Estrato 5
## 1
## 561.7486
predict(df_apartamentos_por_zona,list(areaconst = 300,parqueaderos = 3, banios = 3,
habitaciones = 5, estrato = 6)) # Estrato 6
## 1
## 673.3634
# Cargar datos
suppressMessages(data("vivienda"))
# Crear modelo de regresión lineal múltiple
df_casas <- lm(preciom ~ areaconst + estrato + banios + parqueaderos + habitaciones, data = vivienda)
# Obtener el crédito pre-aprobado
credito_aprobado <- 850
# Filtrar ofertas potenciales
ofertas <- vivienda %>%
filter(areaconst >= 300, estrato == 3, banios == 3, parqueaderos==3, habitaciones == 5) %>%
mutate(precio = predict(df_casas, .)) %>%
filter(precio <= credito_aprobado)
# Mostrar resultados
ofertas
## # A tibble: 0 × 14
## # ℹ 14 variables: id <dbl>, zona <chr>, piso <chr>, estrato <dbl>,
## # preciom <dbl>, areaconst <dbl>, parqueaderos <dbl>, banios <dbl>,
## # habitaciones <dbl>, tipo <chr>, barrio <chr>, longitud <dbl>,
## # latitud <dbl>, precio <dbl>
En conclusión, el análisis de datos ha permitido identificar los principales determinantes del precio de las viviendas, destacando el área construida, el estrato, el número de baños y el número de habitaciones como variables significativas. El modelo de regresión lineal múltiple ha mostrado un buen desempeño, explicando aproximadamente el 69.7% de la variabilidad en los precios, con el área construida como el factor más influyente. Además, la validación de los supuestos respalda la idoneidad del modelo para la predicción de precios, y las estimaciones obtenidas confirman que las viviendas analizadas se ajustan al rango del crédito preaprobado. En general, este estudio ofrece una base sólida para la toma de decisiones en el mercado inmobiliario, resaltando la relevancia del área construida en la determinación del valor de las propiedades.