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:
library(dplyr)
library(knitr)
library(kableExtra)
solicitudes <- tibble(
Característica = c("Tipo", "Área construida (m²)", "Parqueaderos", "Baños",
"Habitaciones", "Estrato", "Zona", "Crédito preaprobado"),
`Vivienda 1` = c("Casa", "200", "1", "2", "4", "4 o 5", "Norte", "$350 millones"),
`Vivienda 2` = c("Apartamento", "300", "3", "3", "5", "5 o 6", "Sur", "$850 millones")
)
solicitudes %>%
kable(align = c("l", "c", "c"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
column_spec(1, bold = TRUE) %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Característica | Vivienda 1 | Vivienda 2 |
|---|---|---|
| Tipo | Casa | Apartamento |
| Área construida (m²) | 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 |
Tabla 1. Condiciones de las dos solicitudes de compra
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).
A continuación se describen los pasos requeridos para la obtención de los resultados:
Realizar un filtro a la base de datos e incluir 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. (Adicionar 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?).
Realizar 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.
Estimar un modelo de regresión lineal múltiple con las variables del punto anterior \[ \text{Precio} = f(\text{Área construida}, \text{Estrato}, \text{Número de cuartos}, \text{Número de parqueaderos}, \\{Número de baños}) \] e interpretar 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).
Realizar la validación de supuestos del modelo e interpretar los resultados (no es necesario corregir en caso de presentar problemas, solo realizar sugerencias de que se podría hacer).
Con el modelo identificado se debe predecir el precio de la vivienda con las características de la primera solicitud.
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.
Realizar los pasos del 1 al 6. Para la segunda solicitud que tiene un crédito pre-aprobado por valor de $850 millones.
El ejercicio parte de la base de datos “limpia” del ejercicio anterior, donde los ceros imposibles para baños ya fueron convertidos a NA y los parqueaderos ausentes fueron recodificados como 0. Adicionalmente se eliminaros tres registros que no tenian valores.
vivienda_limpia <- vivienda %>%
filter(rowSums(!is.na(across(everything()))) > 3) %>%
mutate(
parqueaderos = ifelse(is.na(parqueaderos), 0, parqueaderos),
banios = ifelse(banios == 0, NA, banios)
)
cat("Originales:", nrow(vivienda),
"| Eliminados:", nrow(vivienda) - nrow(vivienda_limpia),
"| Restantes:", nrow(vivienda_limpia))#> Originales: 8322 | Eliminados: 3 | Restantes: 8319
De acuerdo al enunciado del ejercicio se filtra la basa de datos para analizar únicamente las casas ubicadas en la zona norte.
#> [1] 722 13
Una vez aplicado el filtro quedamos con 722 casas.
Con el fin de rectificar que la distribución de las casas sea efectivamente en la zona norte, se ubica cada oferta en un mapa de la ciudad de Cali.
library(leaflet)
pal <- colorFactor("viridis", domain = base1$estrato)
leaflet(base1) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(
lng = ~longitud, lat = ~latitud,
radius = 4, color = ~pal(estrato),
stroke = FALSE, fillOpacity = 0.7,
popup = ~paste0("<b>", barrio, "</b><br>",
"Precio: $", preciom, " millones<br>",
"Área: ", areaconst, " m²<br>",
"Estrato: ", estrato)
) %>%
addLegend("bottomright", pal = pal, values = ~estrato, title = "Estrato")Mapa 1. Ubicación Espacial de las Casas filtradas como Zona norte en Cali.
En el Mapa 1 se hace evidente que la distribución de las casas abarca practicamente todo el territorio de la ciudad, no solamente la zona norte. Esto puede ocurrir por dos motivos: el primero es que la zona la declara quien publica el anuncio y suele usarse con criterio comercial más que estrictamente geográfico; el segundo, es que las coordenadas no corresponden a la zona declarada de la ciudad.
library(dplyr)
vivienda_limpia %>%
filter(tipo == "Casa") %>%
group_by(zona) %>%
summarise(n = n(),
lat_q1 = quantile(latitud, .25, na.rm = TRUE),
lat_med = median(latitud, na.rm = TRUE),
lat_q3 = quantile(latitud, .75, na.rm = TRUE),
lon_med = median(longitud, na.rm = TRUE))Para evitar que estas ofertas mal ubicadas distorsionen el análisis, se procede a depurar la base de datos conservando únicamente las casas efectivamente situadas en el norte de la ciudad. Para esto, se optó como parámetro considerar zona norte a los anuncios que se encuentren por encima de la latitud 3.45, correspondiente al primer cuartil de la latitud de la Zona Norte.
library(dplyr)
library(knitr)
library(kableExtra)
base1_norte <- base1 %>% filter(latitud >= 3.45)
recorte <- tibble(
Criterio = c("Anuncios de la zona norte (Datos originales)",
"Anuncios conservadas tras el filtro geográfico",
"Anuncios excluidos por ubicación inconsistente"),
Registros = c(nrow(base1),
nrow(base1_norte),
nrow(base1) - nrow(base1_norte))
) %>%
mutate(`% del total` = round(100 * Registros / nrow(base1), 1))
recorte %>%
kable(align = c("l", "c", "c"),
caption = "",
caption.position = "bottom") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
column_spec(1, bold = TRUE) %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Criterio | Registros | % del total |
|---|---|---|
| Anuncios de la zona norte (Datos originales) | 722 | 100.0 |
| Anuncios conservadas tras el filtro geográfico | 569 | 78.8 |
| Anuncios excluidos por ubicación inconsistente | 153 | 21.2 |
Tabla 2. Efecto del filtro geográfico sobre la base de Anuncios de la Zona Norte
pal <- colorFactor("viridis", domain = base1_norte$estrato)
leaflet(base1_norte) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(
lng = ~longitud, lat = ~latitud,
radius = 4, color = ~pal(estrato),
stroke = FALSE, fillOpacity = 0.7,
popup = ~paste0("<b>", barrio, "</b><br>",
"Precio: $", preciom, " millones<br>",
"Área: ", areaconst, " m²<br>",
"Estrato: ", estrato)
) %>%
addLegend("bottomright", pal = pal, values = ~estrato, title = "Estrato")Mapa 2 Ubicación Espacial de las Casas en la Zona norte en Cali, tras la depuración
De los 722 anuncios de casas publicadas como Zona Norte, 569 están correctamente ubicadas. Los 153 anuncios restantes, algo más del 20%, aparecen en otros sectores de la ciudad. Estas ofertas se dejaron por fuera del análisis, ya que la ubicación es determinante para la decisión de compra y trabajar con direcciones no confiables llevaría a recomendar inmuebles que no están donde se requiere. El set de datos definitivo contiene 569 anuncios casas, sigue siendo amplio y representativo del mercado del norte de la ciudad.
library(dplyr)
library(knitr)
library(kableExtra)
resumen <- base1_norte %>%
summarise(
`Número de ofertas` = as.character(n()),
`Precio mediano (millones)` = as.character(median(preciom, na.rm = TRUE)),
`Área mediana (m²)` = as.character(median(areaconst, na.rm = TRUE)),
`Estratos presentes` = paste(sort(unique(estrato)), collapse = ", "),
`Barrios distintos` = as.character(n_distinct(barrio))
) %>%
t() %>%
as.data.frame() %>%
tibble::rownames_to_column("Indicador") %>%
rename(Valor = V1)
resumen %>%
kable(align = c("l", "c"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
column_spec(1, bold = TRUE) %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Indicador | Valor |
|---|---|
| Número de ofertas | 569 |
| Precio mediano (millones) | 370 |
| Área mediana (m²) | 235 |
| Estratos presentes | 3, 4, 5, 6 |
| Barrios distintos | 82 |
Tabla 3. Caracterización del segmento de anuncios de casas de la Zona Norte
La Tabla 3 muestra que, una vez depurada la Zona Norte, se aprecia que el mercado de casas del norte de Cali está compuesto por 569 ofertas distribuidas en 82 barrios y en estratos del 3 al 6. La casa típica de la zona tiene un valor de 370 millones de pesos y tiene 235 m² construidos. Estas dos cifras marcan el punto de partida del análisis. Por el lado del tamaño, la solicitud juega a favor: los 200 m² pedidos están por debajo de lo habitual en el sector, así que no es un requerimiento difícil de satisfacer, en principio. Por el lado del precio, en cambio, el crédito de 350 millones queda justo por debajo del valor típico, lo que significa que aproximadamente la mitad de las casas disponibles supera el presupuesto. La búsqueda debe concentrarse entonces en la franja media-baja del mercado, donde la combinación de estrato y barrio permita alcanzar las características solicitadas sin exceder el monto aprobado.
Antes de calcular las correlaciones se evaluó el supuesto de normalidad de las variables mediante la prueba de Shapiro-Wilk, con el fin de decidir entre el coeficiente de Pearson y el de Spearman.La prueba rechazó la normalidad en las seis variables consideradas, con p-valores inferiores a 0,0001 en todos los casos.
De acuerdo a estos resultados, se optó por el coeficiente de correlación de Spearman para el análisis bivariado, decisión que además resulta apropiada para el estrato, variable de naturaleza ordinal en la que las distancias entre categorías no son comparables y que por tanto no admite el tratamiento continuo que supone el coeficiente de Pearson.
plot_ly(x = colnames(m), y = rownames(m), z = m,
type = "heatmap", colors = "RdBu", zmin = -1, zmax = 1,
text = m, texttemplate = "%{text}", hoverinfo = "x+y+z") %>%
layout(title = "")Cuadro 1. Matriz de Correlación de Spearman entre las variables del modelo.
El Cuadro 1 muestra qué tanto se relaciona cada característica con el precio de la vivienda. El área construida es la más determinante por amplio margen, seguida del estrato, el número de baños y la disponibilidad de parqueaderos. El número de habitaciones queda en último lugar, con la asociación más débil de todas, lo que confirma que repartir una misma superficie en más cuartos no encarece la vivienda: pareciera indicar que lo que se paga es el espacio total y no cómo esté dividido.
La matriz también muestra cómo se relacionan las características entre sí, destacando dos puntos. El primero es que las casas más grandes tienden a tener más baños, más habitaciones y más parqueaderos, algo esperable y que significa que estas características no son del todo independientes al momento de buscar. La segunda es que el estrato prácticamente no se relaciona con el número de habitaciones, señal de que el estrato refleja la calidad del entorno y no el tamaño del inmueble. Para la búsqueda de vivienda del caso, es una buena señal, porque implica que se puede encontrar una casa con las habitaciones requeridas en distintos niveles de estrato y, por tanto, en distintos rangos de precio.
library(plotly)
plot_ly(base1_norte, x = ~areaconst, y = ~preciom,
color = ~factor(estrato), colors = "viridis",
type = "scatter", mode = "markers",
marker = list(size = 6, opacity = 0.6),
hoverinfo = "text",
text = ~paste0("Barrio: ", barrio,
"<br>Área: ", areaconst, " m²",
"<br>Precio: $", preciom, " M",
"<br>Estrato: ", estrato)) %>%
layout(title = "",
xaxis = list(title = "Área construida (m²)"),
yaxis = list(title = "Precio (millones)"),
legend = list(title = list(text = "Estrato")))Gráfico 1. Precio de la vivienda vs. Área construida
El Gráfico 1 muestra que la relación entre el precio y el área construida es positiva y clara. El tamaño es el factor que más pesa en el precio de una casa, pues entre más grande, más cara. Pero la relación no es proporcional. En viviendas pequeñas y medianas los precios son bastante predecibles, mientras que a partir de cierto tamaño dos casas con la misma área pueden diferir bastante en el valor, según dónde estén ubicadas y en qué estrato. Esto significa que el metro cuadrado adicional no siempre encarece la vivienda en la misma medida y, que a partir de cierto punto lo que define el precio ya no es el tamaño sino la ubicación.
plot_ly(base1_norte, x = ~factor(estrato), y = ~preciom, type = "box",
color = ~factor(estrato), colors = "viridis") %>%
layout(title = "",
xaxis = list(title = "Estrato"),
yaxis = list(title = "Precio (millones)"),
showlegend = FALSE)Gráfico 2. Boxplot distribución del precio de la vivienda por estrato
El Gráfico 2 muestra que el estrato marca una “escalera de precios” bastante definida en la zona norte de la ciudad. Una casa de estrato 3 cuesta típicamente unos 250 millones, en estrato 4 sube a cerca de 380, en estrato 5 ronda los 480 y en estrato 6 alcanza los 750 millones. Es decir que subir un solo nivel de estrato encarece la vivienda en un orden de 100 a 270 millones.
Por otro lado, dentro de cada estrato hay bastante variación, y los rangos de los estratos 4 y 5 se traslapan de manera apreciable, existen casas de estrato 5 más económicas que algunas de estrato 4. Esto abre una posibilidad concreta para la solicitud, que pide estrato 4 o 5. Buscar en la parte baja del estrato 5 puede resultar tan viable como buscar en estrato 4, y con mejor entorno. También se observa que el estrato 4 concentra la mayor parte de su oferta entre 300 y 520 millones, de modo que existe un tramo real de opciones dentro del crédito aprobado, aunque en la mitad inferior de ese rango.
plot_ly(base1_norte, x = ~factor(banios), y = ~preciom, type = "box",
color = ~factor(banios), colors = "viridis") %>%
layout(title = "",
xaxis = list(title = "Número de Baños"),
yaxis = list(title = "Precio (millones)"),
showlegend = FALSE)Gráfico 3. Boxplot distribución del precio de la vivienda por número de baños
El Gráfico 3 ofrece un análisis similar al caso anterior, mostrando una relación positiva entre el número de baños y el precio de la vivienda en forma de escalera, mostrando una mayor valoración del mercado inmobiliarios por la disponibilidad de este servicio. El Gráfico 4 muestra una perspectiva de análisis similar, aunque no necesarimente es creciente. Después de cinco baños, los precios parecen estabilizarse y el precio de la vivienda no se incrementa de manera considerable, al aumentar este servicio.
plot_ly(base1_norte, x = ~factor(habitaciones), y = ~preciom, type = "box",
color = ~factor(habitaciones), colors = "viridis") %>%
layout(title = "",
xaxis = list(title = "Número de Habitaciones"),
yaxis = list(title = "Precio (millones)"),
showlegend = FALSE)Gráfico 4. Boxplot distribución del precio de la vivienda por número de habitaciones
Se busca estimar un modelo del tipo:
\[ Precio_i = \beta_0 + \beta_1 X_{1i} + \beta_2 X_{2i} + \cdots + \beta_k X_{ki} + \varepsilon_i \] Donde cada parámetro beta se estima por MCO y epsilon corresponde a los errores del modelo (Modelo estocástico). Para hacer una adecuada estimación del MRL por MCO primero debemos tratar la variable estrato como una variable categórica. Siendo el estrato=3, el estrato de referencia o de base, entonces, e este caso corresponde estimar el siguiente modelo: \[ \begin{aligned} Precio_i =\ & \beta_0 + \beta_1 \, areaconst_i + \beta_2 \, parqueaderos_i + \beta_3 \, banios_i \\ &+ \beta_4 \, habitaciones_i + \delta_4 \, D_{\text{Estrato 4},i} + \delta_5 \, D_{\text{Estrato 5},i} \\ &+ \delta_6 \, D_{\text{Estrato 6},i} + \varepsilon_i \end{aligned} \]
# Modelo 2: estrato como variable categórica
modelo2 <- lm(preciom ~ areaconst + factor(estrato) + habitaciones + parqueaderos + banios,
data = base1_norte)
summary(modelo2)#>
#> Call:
#> lm(formula = preciom ~ areaconst + factor(estrato) + habitaciones +
#> parqueaderos + banios, data = base1_norte)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -938.8 -70.0 -16.7 37.2 1085.1
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 9.6179 20.3288 0.47 0.6363
#> areaconst 0.7743 0.0513 15.11 < 0.0000000000000002 ***
#> factor(estrato)4 73.9097 19.7678 3.74 0.0002 ***
#> factor(estrato)5 127.4689 19.0734 6.68 0.0000000000568801 ***
#> factor(estrato)6 266.7258 33.4573 7.97 0.0000000000000089 ***
#> habitaciones 7.1977 4.9257 1.46 0.1445
#> parqueaderos 8.4405 4.8600 1.74 0.0830 .
#> banios 25.9375 6.2993 4.12 0.0000440958303972 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 155 on 557 degrees of freedom
#> (4 observations deleted due to missingness)
#> Multiple R-squared: 0.652, Adjusted R-squared: 0.647
#> F-statistic: 149 on 7 and 557 DF, p-value: <0.0000000000000002
Cuadro 2. Estimación del Modelo MRL por MCO
El Cuadro 2 muestra los resultados de la estimación del modelo donde el precio de una casa en el norte de Cali se explica a partir de cinco características: área construida, estrato (variables dicótomas, estrato4, estrato5 y estrato6), número de habitaciones, parqueaderos y baños. Esta estimación se puede representar en forma de ecuación como:
\[ \begin{aligned} \widehat{Preciom}_i =\ & 9.6179 + 0.7743 \, areaconst_i + 7.1977 \, habitaciones_i \\ &+ 8.4405 \, parqueaderos_i + 25.9375 \, banios_i \\ &+ 73.9097 \, D_{\text{Estrato 4},i} + 127.4689 \, D_{\text{Estrato 5},i} \\ &+ 266.7258 \, D_{\text{Estrato 6},i} \end{aligned} \] El modelo fue globalmente significativo (𝐹(7,557)=149,𝑝<0,001 y explicó el 65,2% de la variación del precio (𝑅2=0,652; R2 ajustado = 0,647). Manteniendo constantes las demás variables, un metro cuadrado adicional de área construida incrementa el precio esperado en 0,774 millones de pesos y un baño adicional lo incrementa en 25,938 millones. Frente al estrato 3, los inmuebles de estrato 4, 5 y 6 presentan incrementos estimados de 73,910, 127,469 y 266,726 millones de pesos, respectivamente. Las variables habitaciones y parqueaderos no fueron significativas al nivel del 5%; aunque parqueaderos presentó significancia marginal al 10%. El error estándar residual de 155 millones indica que aún existe una variabilidad relevante del precio no explicada por las características incluidas en el modelo.
Cuadro 3. Salida ANOVA - Modelo de Casas, Zona Norte
Estos resultados del Cuadro 4 se interpretan de la forma como se presenta a continuación:
| Variable | gl | Suma de cuadrados | Estadístico F | Valor p | Interpretación |
|---|---|---|---|---|---|
| Área construida | 1 | 21.101.371 | 876,88 | < 0,001 | Es la variable que más reduce la variabilidad residual en el orden definido. Antes de incluir los demás predictores, el área construida explica una proporción muy importante de la variación del precio. |
| Estrato | 3 | 2.939.416 | 40,72 | < 0,001 | Una vez controlada el área construida, incorporar el estrato —mediante tres dummies para estratos 4, 5 y 6 frente al 3— mejora significativamente la capacidad explicativa del modelo. |
| Habitaciones | 1 | 494.285 | 20,54 | < 0,001 | Después de área y estrato, añadir habitaciones reduce significativamente el error residual. |
| Parqueaderos | 1 | 116.368 | 4,84 | 0,028 | Después de controlar por área, estrato y habitaciones, los parqueaderos también hacen un aporte estadísticamente significativo al 5% en esta tabla secuencial. |
| Baños | 1 | 407.988 | 16,95 | < 0,001 | Una vez ingresadas las variables anteriores, los baños aportan información adicional y significativa para explicar el precio. |
| Residuos | 557 | 13.403.657 | 24.064 | — | Es la variabilidad del precio que no logra explicar el conjunto de variables incluidas en el modelo. |
Los cuatro supuestos que sostienen el modelo son linealidad, homocedasticidad, independencia y normalidad de los errores.
La validación se realizará combinando el análisis gráfico de los residuales con pruebas de hipótesis formales. Dado que los errores del modelo poblacional no son observables, el diagnóstico se apoya en los residuales, que constituyen su contraparte muestral. Se evaluó la homocedasticidad mediante la prueba de Breusch-Pagan, la normalidad mediante Shapiro-Wilk, la independencia mediante Durbin-Watson y la adecuación de la forma funcional mediante la prueba RESET de Ramsey. Se calcularon adicionalmente los factores de inflación de varianza para descartar multicolinealidad y la distancia de Cook para identificar observaciones influyentes, empleando el criterio convencional de 4/n como umbral.
Gráfico 5. Residuals Vs. Fiited; Q-Q Residuals; Scale Location; Residual vs Leverage
El Gráfico 5 expone los gráficos de diagnóstico y muestran que el modelo estimado presenta inidicios de heterocedasticidad, ya que la dispersión de los residuos aumenta a medida que crecen los valores ajustados; este patrón se evidencia tanto en el gráfico de residuos frente a valores ajustados como en el gráfico Scale–Location. El gráfico Q-Q muestra desviaciones importantes en las colas, por lo que la normalidad de los residuos no se cumple estrictamente y existen valores extremos. Finalmente, el gráfico de residuos frente a leverage identifica observaciones potencialmente influyentes, especialmente el registro 485, que combina alta palanca con un residuo estandarizado negativo elevado y una distancia de Cook cercana o superior a 1.
La linealidad parece razonable como primera aproximación, pues no se aprecia una curvatura sistemática muy marcada en la media de los residuos. Sin embargo, la heterocedasticidad, la no normalidad en las colas y los casos influyentes implican que los errores estándar convencionales y las pruebas de significancia deben interpretarse con cautela. Como alternativas para investigaciones posteriores, se recomienda emplear errores estándar robustos, considerar una transformación logarítmica del precio, revisar las observaciones influyentes y agregar variables relevantes como barrio, antigüedad, estado de conservación, tipo de inmueble, administración, amenidades o localización exacta, variables que puedan mejorar el modelo.
Los resultados de las pruebas formales para la verificación de los supuestos del modelo de regresión lineal múltiiple se pueden interpretar como se muestra a continuación:
| Prueba | Hipótesis nula | Resultado | Conclusión |
|---|---|---|---|
| Breusch–Pagan | Varianza constante de los errores | BP=118, gl=7, p<0,001 | Se rechaza homocedasticidad: existe heterocedasticidad |
| Shapiro–Wilk | Residuos con distribución normal | W=0,79, p<0,001 | Se rechaza normalidad de los residuos |
| Durbin–Watson | Ausencia de autocorrelación de primer orden | DW=1,7, p=0,00002 | Evidencia de autocorrelación positiva |
| RESET de Ramsey | Modelo correctamente especificado en su forma funcional | RESET=14, gl1=8, gl2=549, p<0,001 | Evidencia de posible mala especificación: no linealidad y/o variables omitidas |
Cuadro 4. Resultado de las pruebas formales para verificación de supuestos
Al aplicar la Distancia de Cook para el análisis de observaciones influyentes en los resultados del modelo, encontramos lo siguiente:
| Barrio | Estrato | Área construida | Habitaciones | Baños | Precio | Lectura inicial |
|---|---|---|---|---|---|---|
| El Bosque | 5 | 1.188 m² | 6 | 6 | 650 millones | Área extremadamente alta frente a un precio relativamente bajo para ese tamaño |
| Santa Mónica | 5 | 950 m² | 10 | 5 | 1.270 millones | Vivienda muy grande y con muchas habitaciones; alta palanca |
| Juanambú | 5 | 736 m² | 7 | 4 | 950 millones | Área y número de habitaciones inusuales |
| San Vicente | 4 | 734 m² | 10 | 5 | 1.650 millones | Tamaño y precio muy altos para estrato 4; posible residuo positivo grande |
| Urbanización La Flora | 5 | 500 m² | 4 | 5 | 680 millones | Área elevada y muchos baños |
| La Flora | 5 | 455 m² | 4 | NA | 530 millones | Tiene dato faltante en baños; puede no entrar al mismo modelo si banios es predictor |
| Santa Mónica | 5 | 450 m² | 4 | 5 | 950 millones | Precio elevado para su combinación de características |
| Juanambú | 5 | 400 m² | 5 | 5 | 750 millones | Vivienda grande y con alta dotación de baños |
| Acopi | 6 | 350 m² | 6 | 5 | 460 millones | Estrato alto con precio comparativamente bajo; posible inconsistencia o características omitidas |
| La Flora | 5 | 340 m² | 7 | 5 | 520 millones | Muchas habitaciones y baños respecto al área |
Cuadro 5. Análisis de observaciones influyentes
El análisis de influencia identificó 36 observaciones con distancia de Cook superior al umbral exploratorio establecido. Estas viviendas presentan combinaciones poco frecuentes de área construida, habitaciones, baños, estrato y precio; por ejemplo, se observan inmuebles con áreas entre 340 y 1.188 m², varias habitaciones y precios que, en algunos casos, parecen alejados de lo esperado según sus atributos. Estas observaciones pueden tener alta palanca, residuos elevados o ambas características, por lo que su inclusión puede afectar la estimación de los coeficientes del modelo.
No obstante, las observaciones identificadas no deben eliminarse automáticamente. Primero se recomienda verificar la consistencia de las unidades de área y precio, la clasificación del inmueble, el estrato, la localización y los valores faltantes. Si los registros son válidos, representan viviendas atípicas pero existentes del mercado y deben conservarse; en ese caso, se sugiere complementar el análisis con transformaciones del precio, regresión robusta y un análisis de sensibilidad. Si se detectan errores de captura o inmuebles que no pertenecen al universo de análisis, su corrección o exclusión estaría metodológicamente justificada.
#> GVIF Df GVIF^(1/(2*Df))
#> areaconst 1.711 1 1.308
#> factor(estrato) 1.697 3 1.092
#> habitaciones 1.763 1 1.328
#> parqueaderos 1.346 1 1.160
#> banios 2.031 1 1.425
Cuadro 6. Resultado de la Prueba de Multicolinealidad
El diagnóstico de multicolinealidad no evidenció problemas relevantes en el modelo. Dado que la variable estrato fue incluida como factor con varios niveles, se empleó el Factor Generalizado de Inflación de la Varianza (GVIF) y su medida ajustada 𝐺𝑉𝐼𝐹1/(2⋅𝐷𝑓)1/(2⋅Df) . Los valores ajustados oscilaron entre 1,092 para el estrato y 1,425 para el número de baños. Estos resultados se encuentran por debajo de los umbrales de alerta habituales, por lo que no existe evidencia de relaciones lineales fuertes entre el área construida, estrato, número de habitaciones, parqueaderos y baños. En consecuencia, los coeficientes del modelo pueden interpretarse sin una preocupación importante por inflación de errores estándar o inestabilidad asociada a multicolinealidad.
Con el modelo estimado se procede a predecir el precio esperado para las características de la primera solicitud: 1. Área construida: \(200\text{ m}^2\). 2. Parqueaderos: \(2\). 3. Baños: \(2\). 4. Habitaciones: \(4\). 5. Estrato: \(4\) o \(5\). 6. Zona: Norte.
solicitud1 <- data.frame(
areaconst = c(200, 200),
estrato = c(4, 5),
habitaciones = c(4, 4),
parqueaderos = c(1, 1),
banios = c(2, 2)
)Dado que la condición de estrato admitía dos valores, la predicción se calculará para ambos escenarios (estrato 4 y 5).
Se construyen dos tipos de intervalo al 95% de confianza. Por un lado, el intervalo de confianza limita el precio medio de la población de viviendas que comparten esas características e incorpora únicamente la incertidumbre asociada a la estimación de los coeficientes. Por otro lado, el intervalo de predicción limita el precio de una vivienda individual y añade la variabilidad propia de cada inmueble, cuantificada por el error estándar residual, razón por la cual resulta sistemáticamente más amplio (Ver Cuadro 7).
library(dplyr)
library(knitr)
library(kableExtra)
pred_conf <- predict(modelo2, newdata = solicitud1, interval = "confidence")
pred_pred <- predict(modelo2, newdata = solicitud1, interval = "prediction")
tabla_pred <- data.frame(
Estrato = c(4, 5),
Estimado = round(pred_conf[, "fit"], 1),
IC_inf = round(pred_conf[, "lwr"], 1),
IC_sup = round(pred_conf[, "upr"], 1),
IP_inf = round(pred_pred[, "lwr"], 1),
IP_sup = round(pred_pred[, "upr"], 1)
)
tabla_pred %>%
kable(align = "c",
col.names = c("Estrato", "Precio estimado",
"Límite inferior", "Límite superior",
"Límite inferior", "Límite superior"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
add_header_above(c(" " = 2,
"Intervalo de confianza 95%" = 2,
"Intervalo de predicción 95%" = 2)) %>%
column_spec(1, bold = TRUE) %>%
column_spec(2, bold = TRUE, background = "#EAF2F8") %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Estrato | Precio estimado | Límite inferior | Límite superior | Límite inferior | Límite superior |
|---|---|---|---|---|---|
| 4 | 327.5 | 293.8 | 361.2 | 20.9 | 634.1 |
| 5 | 381.1 | 350.8 | 411.3 | 74.9 | 687.3 |
Cuadro 7. Precio estimado de la Vivienda 1 según estrato (millones de pesos)
Para una vivienda ubicada en la Zona Norte, con 200 m² de área construida, dos parqueaderos, dos baños y cuatro habitaciones, el modelo estimó un precio de 327,5 millones de pesos en estrato 4 y de 381,1 millones en estrato 5. Manteniendo constantes las demás características, la alternativa de estrato 5 presenta un incremento estimado de 53,6 millones de pesos frente a la de estrato 4.
Los intervalos de confianza al 95% indican que el precio promedio esperado se ubicaría entre 293,8 y 361,2 millones para estrato 4, y entre 350,8 y 411,3 millones para estrato 5. Por su parte, los intervalos de predicción son más amplios porque corresponden a una vivienda individual y recogen la variabilidad no explicada por el modelo.
Aunque la predicción puntual de estrato 4 se encuentra dentro del presupuesto, el límite superior de su intervalo de confianza al 95% es de 361,2 millones, cifra superior al crédito disponible. Para estrato 5, incluso el límite inferior del intervalo de confianza, de 350,8 millones, supera levemente el monto preaprobado. En consecuencia, el crédito de 350 millones es compatible principalmente con viviendas de estrato 4 cercanas a las características definidas, mientras que las opciones de estrato 5 requerirían negociación, recursos propios o financiación adicional.
El análisis del mercado disponible arrojó 30 casas que cumplen las condiciones de la solicitud y se encuentran dentro del crédito preaprobado de 350 millones(Ver Cuadro 8). De ellas se seleccionarán seis, tres en estrato 4 y tres en estrato 5, priorizando aquellas cuyo precio de venta resulta más favorable frente a lo que sus características sugieren que deberían costar (Ver Cuadro 9).
library(dplyr)
library(knitr)
library(kableExtra)
resumen_cand <- candidatas %>%
group_by(Estrato = estrato) %>%
summarise(Ofertas = n(),
area_min = min(areaconst),
area_med = median(areaconst),
area_max = max(areaconst),
.groups = "drop") %>%
bind_rows(
candidatas %>%
summarise(Estrato = NA,
Ofertas = n(),
area_min = min(areaconst),
area_med = median(areaconst),
area_max = max(areaconst))
) %>%
mutate(Estrato = ifelse(is.na(Estrato), "Total", as.character(Estrato)),
across(starts_with("area"), ~ round(., 0)))
resumen_cand %>%
kable(align = "c",
col.names = c("Estrato", "Ofertas", "Mínima", "Mediana", "Máxima"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
add_header_above(c(" " = 2, "Área construida" = 3)) %>%
column_spec(1, bold = TRUE) %>%
column_spec(2, bold = TRUE, background = "#EAF2F8") %>%
row_spec(nrow(resumen_cand), bold = TRUE, background = "#D5DBDB") %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Estrato | Ofertas | Mínima | Mediana | Máxima |
|---|---|---|---|---|
| 4 | 8 | 200 | 267 | 295 |
| 5 | 22 | 200 | 240 | 355 |
| Total | 30 | 200 | 248 | 355 |
Cuadro 8. Candidatas dentro del presupuesto según estrato y área construida (m²)
library(dplyr)
library(knitr)
library(kableExtra)
seleccion <- candidatas1 %>%
group_by(estrato) %>%
slice_max(diferencia, n = 3) %>%
ungroup() %>%
arrange(desc(descuento_pct))
seleccion %>%
mutate(barrio = tools::toTitleCase(barrio),
Ficha = paste0(habitaciones, " / ", banios, " / ", parqueaderos),
descuento_pct = paste0(descuento_pct, "%")) %>%
select(barrio, estrato, areaconst, Ficha, preciom, precio_estimado, descuento_pct) %>%
kable(align = c("l", "c", "c", "c", "c", "c", "c"),
col.names = c("Barrio", "Estrato", "Área (m²)",
"Hab. / Baños / Parq.",
"Precio ofertado", "Valor estimado", "Diferencia"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
add_header_above(c(" " = 4, "Valoración" = 3)) %>%
column_spec(1, bold = TRUE) %>%
column_spec(5, bold = TRUE, background = "#EAF2F8") %>%
column_spec(7, bold = TRUE, color = "#1E8449") %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Barrio | Estrato | Área (m²) | Hab. / Baños / Parq. | Precio ofertado | Valor estimado | Diferencia |
|---|---|---|---|---|---|---|
| La Campiña | 5 | 240.0 | 6 / 5 / 2 | 340 | 512.7 | 33.7% |
| La Merced | 5 | 275.0 | 5 / 3 / 2 | 330 | 480.7 | 31.4% |
| Prados Del Norte | 5 | 246.0 | 4 / 4 / 2 | 330 | 477.0 | 30.8% |
| El Bosque | 4 | 270.0 | 4 / 4 / 2 | 315 | 442.0 | 28.7% |
| La Merced | 4 | 275.0 | 5 / 3 / 2 | 330 | 427.1 | 22.7% |
| Vipasa | 4 | 264.5 | 4 / 4 / 2 | 340 | 437.8 | 22.3% |
Cuadro 9. Ofertas recomendadas para la Vivienda 1 (cifras en millones de pesos)
La opción que es más llamativa es una casa de 240 m2 en La Campiña, estrato 5, con seis habitaciones, cinco baños y dos parqueaderos, ofrecida en 340 millones. Tiene un área total un poco mayor que el área solicitada, supera lo pedido en baños y parqueaderos, y deja un margen de 10 millones frente al crédito aprobado. Las demás opciones se ubican en La Merced, Prados del Norte, y Vipasa, con áreas entre 246 y 2750 m2 y precios entre 315 y 340 millones.
library(leaflet)
library(htmltools)
pal <- colorFactor(c("#2E86C1", "#C0392B"), domain = c(4, 5))
etiqueta <- function(d) {
lapply(seq_len(nrow(d)), function(i) {
HTML(paste0(
"<b>", tools::toTitleCase(d$barrio[i]), "</b> — Estrato ", d$estrato[i], "<br>",
"Área: ", d$areaconst[i], " m²<br>",
"Habitaciones: ", d$habitaciones[i], "<br>",
"Baños: ", d$banios[i], "<br>",
"Parqueaderos: ", d$parqueaderos[i], "<br>",
"<b>Precio: $", d$preciom[i], " millones</b>"
))
})
}
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(data = base1_norte,
~longitud, ~latitud,
radius = 2, color = "grey", stroke = FALSE, fillOpacity = 0.2,
group = "Mercado del norte") %>%
addCircleMarkers(data = candidatas1,
~longitud, ~latitud,
radius = 5, color = "#F39C12", stroke = FALSE, fillOpacity = 0.5,
group = "Candidatas viables",
label = etiqueta(candidatas1),
popup = ~paste0("<b>", barrio, "</b><br>$", preciom, " M | ",
areaconst, " m² | Estrato ", estrato)) %>%
addCircleMarkers(data = seleccion,
~longitud, ~latitud,
radius = 10, color = ~pal(estrato),
stroke = TRUE, weight = 2, opacity = 1, fillOpacity = 0.9,
group = "Ofertas recomendadas",
label = etiqueta(seleccion),
labelOptions = labelOptions(
style = list("font-size" = "13px", "padding" = "8px"),
direction = "auto"),
popup = ~paste0("<b>", toupper(barrio), "</b><br>",
"Estrato ", estrato, " | ", areaconst, " m²<br>",
habitaciones, " habitaciones | ", banios, " baños | ",
parqueaderos, " parqueaderos<br><hr>",
"<b>Precio ofertado: $", preciom, " M</b><br>",
"Valor estimado: $", precio_estimado, " M<br>",
"Diferencia a favor: $", diferencia, " M (",
descuento_pct, "%)")) %>%
addLegend("bottomright",
colors = c("#2E86C1", "#C0392B", "#F39C12", "grey"),
labels = c("Recomendada estrato 4", "Recomendada estrato 5",
"Otras candidatas viables", "Mercado del norte"),
title = "Ofertas para la Vivienda 1") %>%
addLayersControl(overlayGroups = c("Ofertas recomendadas", "Candidatas viables",
"Mercado del norte"),
options = layersControlOptions(collapsed = FALSE))Mapa 3. Ubicación espacial de las Casas candidatas en la Zona Norte de la Ciudad
Cabe resaltar que la diferencia entre el precio ofertado y el estimado no equivale por sí sola a una oportunidad de compra. El modelo presenta un error estándar residual de 156 millones y explica el 65% de la variabilidad del precio, de manera que una parte sustancial de esas diferencias corresponde a atributos no observados: estado de conservación, antigüedad, calidad de acabados, orientación y características del entorno inmediato.
El Mapa 3, es una visualización interactiva que muestra las ofertas recomendadas por este análisis estadístico (para los estratos 4 y 5), las ofertas candidatas viables, aquellas que se ajustan a los requerimientos (30 ofertas en total) y todos los anuncios del zona norte de la ciudad de Cali.
En esta sección del informe, hacemos el análisis para la solicitud de la Vivienda 2, consistente en Apartamentos de la Zona Sur de la ciudad.
De acuerdo al enunciado del ejercicio se filtra la basa de datos para analizar únicamente los apartamentos ubicados en la Zona Sur de la ciudad.
#> [1] 2787 13
Una vez aplicado el filtro quedamos con 2787 Apartamentos, todos ubicados en la Zona Sur de la ciudad de Cali.
Con el fin de rectificar que la distribución de los apartamentos sea efectivamente en la Zona Sur, se ubica cada oferta en un mapa de la ciudad de Cali.
library(leaflet)
pal <- colorFactor("viridis", domain = base2$estrato)
leaflet(base2) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(
lng = ~longitud, lat = ~latitud,
radius = 4, color = ~pal(estrato),
stroke = FALSE, fillOpacity = 0.7,
popup = ~paste0("<b>", barrio, "</b><br>",
"Precio: $", preciom, " millones<br>",
"Área: ", areaconst, " m²<br>",
"Estrato: ", estrato)
) %>%
addLegend("bottomright", pal = pal, values = ~estrato, title = "Estrato")Mapa 4. Ubicación Espacial de los Apartamentos filtradas como Zona Sur de Cali.
En el Mapa 4 se hace evidente que la distribución de los apartamentos abarca practicamente todo el territorio de la ciudad, no solamente la zona sur (igual que en el caso anterior). Esto puede ocurrir por dos motivos: el primero es que la zona la declara quien publica el anuncio y suele usarse con criterio comercial más que estrictamente geográfico; el segundo, es que las coordenadas no corresponden a la zona declarada de la ciudad.
Para evitar que estas ofertas mal ubicadas distorsionen el análisis, se procede a depurar la base de datos conservando únicamente los apartamentos efectivamente situadas en el sur de la ciudad. Para esto, se optó como parámetro considerar zona sur a los anuncios que se encuentren por debajo de la latitud 3.4264, correspondiente al barrio San Fernando de la ciudad.
library(dplyr)
library(knitr)
library(kableExtra)
base2_sur <- base2 %>% filter(latitud <= 3.4264)
recorte <- tibble(
Criterio = c("Anuncios de la Zona Sur (Datos originales)",
"Anuncios conservadas tras el filtro geográfico",
"Anuncios excluidos por ubicación inconsistente"),
Registros = c(nrow(base2),
nrow(base2_sur),
nrow(base2) - nrow(base2_sur))
) %>%
mutate(`% del total` = round(100 * Registros / nrow(base2), 1))
recorte %>%
kable(align = c("l", "c", "c"),
caption = "",
caption.position = "bottom") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
column_spec(1, bold = TRUE) %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Criterio | Registros | % del total |
|---|---|---|
| Anuncios de la Zona Sur (Datos originales) | 2787 | 100.0 |
| Anuncios conservadas tras el filtro geográfico | 2472 | 88.7 |
| Anuncios excluidos por ubicación inconsistente | 315 | 11.3 |
Tabla 4. Efecto del filtro geográfico sobre la base de Anuncios de la Zona Norte
pal <- colorFactor("viridis", domain = base2_sur$estrato)
leaflet(base2_sur) %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(
lng = ~longitud, lat = ~latitud,
radius = 4, color = ~pal(estrato),
stroke = FALSE, fillOpacity = 0.7,
popup = ~paste0("<b>", barrio, "</b><br>",
"Precio: $", preciom, " millones<br>",
"Área: ", areaconst, " m²<br>",
"Estrato: ", estrato)
) %>%
addLegend("bottomright", pal = pal, values = ~estrato, title = "Estrato")*Mapa 4. Ubicación Espacial de los Apartamentos de la Zona Sur de Cali, tras la depuración
De los 2787 anuncios de apartamentos publicados como Zona Sur, 2472 están correctamente ubicados. Los 315 anuncios restantes, algo más del 11%, aparecen en otros sectores de la ciudad. Estas ofertas se dejaron por fuera del análisis, ya que la ubicación es determinante para la decisión de compra y trabajar con direcciones no confiables llevaría a recomendar inmuebles que no están donde se requiere. El set de datos definitivo contiene 2472 anuncios apartamentos, es muy amplio y representativo del mercado del sur de la ciudad.
library(dplyr)
library(knitr)
library(kableExtra)
resumen <- base2_sur %>%
summarise(
`Número de ofertas` = as.character(n()),
`Precio mediano (millones)` = as.character(median(preciom, na.rm = TRUE)),
`Área mediana (m²)` = as.character(median(areaconst, na.rm = TRUE)),
`Estratos presentes` = paste(sort(unique(estrato)), collapse = ", "),
`Barrios distintos` = as.character(n_distinct(barrio))
) %>%
t() %>%
as.data.frame() %>%
tibble::rownames_to_column("Indicador") %>%
rename(Valor = V1)
resumen %>%
kable(align = c("l", "c"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
column_spec(1, bold = TRUE) %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Indicador | Valor |
|---|---|
| Número de ofertas | 2472 |
| Precio mediano (millones) | 245 |
| Área mediana (m²) | 85 |
| Estratos presentes | 3, 4, 5, 6 |
| Barrios distintos | 118 |
Tabla 5. Caracterización del segmento de anuncios de casas de la Zona Norte
La Tabla 5 muestra que, una vez depurada la Zona Sur, se aprecia que el mercado de apartamentos del sur de Cali está compuesto por 2472 ofertas distribuidas en 118 barrios y en estratos del 3 al 6. El apartamento típico de la zona tiene un valor de 245 millones de pesos y tiene 85 m² construidos. Estas dos cifras marcan el punto de partida del análisis. Por el lado del tamaño, la solicitud juegaen contra: los 300 m² pedidos están muy por encima de lo habitual en el sector, así que es un requerimiento más difícil de satisfacer, en principio. Por el lado del precio, en cambio, el crédito de 850 millones queda muy por encima del valor típico, lo que significa que aproximadamente la mitad de los apartamentos disponibles supera el presupuesto. La búsqueda debe concentrarse entonces en la franja alta del mercado, donde la combinación de estrato y barrio permita alcanzar las características solicitadas sin exceder el monto aprobado.
Antes de calcular las correlaciones se evaluó el supuesto de normalidad de las variables mediante la prueba de Shapiro-Wilk, con el fin de decidir entre el coeficiente de Pearson y el de Spearman.La prueba rechazó la normalidad en las seis variables consideradas, con p-valores inferiores a 0,0001 en todos los casos.
De acuerdo a estos resultados, se optó por aplicar el coeficiente de correlación de Spearman para el análisis bivariado, decisión que además resulta apropiada para la variable estrato, que es de naturaleza ordinal en la que las distancias entre categorías no son comparables y que por tanto no admite el tratamiento continuo que supone el coeficiente de Pearson.
plot_ly(x = colnames(m), y = rownames(m), z = m,
type = "heatmap", colors = "RdBu", zmin = -1, zmax = 1,
text = m, texttemplate = "%{text}", hoverinfo = "x+y+z") %>%
layout(title = "")Cuadro 11. Matriz de Correlación de Spearman entre las variables del modelo.
El Cuadro 11 indica asociaciones monotónicas positivas entre el precio y todas las características analizadas: en general, las viviendas con mayor área, estrato, número de baños, parqueaderos y habitaciones tienden a ubicarse en rangos de precios más altos. La relación más fuerte con preciom (Precio del inmueble en millones de pesos) es el área construida (𝜌𝑠=0,86); la más débil es el número de habitaciones (𝜌𝑠=0,38). La correlación de Spearman mide asociación monotónica entre rangos, no necesariamente linealidad ni causalidad, y es apropiada cuando hay asimetrías, valores atípicos o variables ordinales como el estrato.
library(plotly)
plot_ly(base2_sur, x = ~areaconst, y = ~preciom,
color = ~factor(estrato), colors = "viridis",
type = "scatter", mode = "markers",
marker = list(size = 6, opacity = 0.6),
hoverinfo = "text",
text = ~paste0("Barrio: ", barrio,
"<br>Área: ", areaconst, " m²",
"<br>Precio: $", preciom, " M",
"<br>Estrato: ", estrato)) %>%
layout(title = "",
xaxis = list(title = "Área construida (m²)"),
yaxis = list(title = "Precio (millones)"),
legend = list(title = list(text = "Estrato")))Gráfico 6. Precio de la vivienda vs. Área construida
El Gráfico 6 muestra una asociación positiva entre el área construida y el precio ofertado de las viviendas (apartamentos): en términos generales, los inmuebles de mayor tamaño presentan precios más elevados. Asimismo, se observan diferencias relevantes por estrato socioeconómico. Para áreas construidas similares, las viviendas de estrato 6 tienden a exhibir precios superiores a los de estratos 3, 4 y 5, lo que respalda la inclusión del estrato como variable categórica en el modelo de regresión.
La dispersión de los precios aumenta para áreas construidas más grandes, lo que sugiere una posible heterocedasticidad. Además, se identifican algunas observaciones atípicas, particularmente viviendas con áreas superiores a 500 m² y precios relativamente bajos o altos frente a la tendencia general. Estos casos deben revisarse para verificar su consistencia y su posible influencia sobre las estimaciones del modelo.
plot_ly(base2_sur, x = ~factor(estrato), y = ~preciom, type = "box",
color = ~factor(estrato), colors = "viridis") %>%
layout(title = "",
xaxis = list(title = "Estrato"),
yaxis = list(title = "Precio (millones)"),
showlegend = FALSE)Gráfico 7. Boxplot distribución del precio del Apartamento por estrato
El Gráfico 7 muestra que el estrato marca una “escalera de precios” bastante definida en la Zona Sur de la ciudad. Un apartamento de estrato 3 cuesta típicamente unos 128 millones, en estrato 4 sube a cerca de 185, en estrato 5 a 280 millones y en estrato 6 a más de 600 millones de pesos.
Por otro lado, dentro de cada estrato hay bastante variación, y los rangos de los estratos 4 y 5 casi se traslapan, existen apartamentos de estrato 5 más económicas que algunas de estrato 4. Esto tiene una implicación para la posibilidad concreta para la solicitud, que pide estrato 5 o 6.
plot_ly(base2_sur, x = ~factor(banios), y = ~preciom, type = "box",
color = ~factor(banios), colors = "viridis") %>%
layout(title = "",
xaxis = list(title = "Número de Baños"),
yaxis = list(title = "Precio (millones)"),
showlegend = FALSE)Gráfico 8. Boxplot distribución del precio de la vivienda por número de baños
El Gráfico 8 ofrece un análisis similar al caso anterior, mostrando una relación positiva entre el número de baños y el precio del apartamento en forma de escalera, mostrando una mayor valoración del mercado inmobiliarios por la disponibilidad de este servicio.Asimismo, la dispersión de los precios crece a medida que aumenta el número de baños, especialmente desde cuatro baños, lo que revela una mayor heterogeneidad en el segmento de viviendas de alta gama.
Se identifican diversos valores atípicos, principalmente en las categorías de tres, cuatro y cinco baños, con precios superiores a 1.000 millones de pesos. Las categorías de siete y ocho baños cuentan aparentemente con muy pocas observaciones, por lo que no permiten inferencias descriptivas robustas. En conjunto, el gráfico respalda una asociación positiva entre baños y precio, aunque esta relación debe interpretarse junto con otras variables relevantes como área construida, estrato, parqueaderos, ubicación y calidad del inmueble.
plot_ly(base2_sur, x = ~factor(habitaciones), y = ~preciom, type = "box",
color = ~factor(habitaciones), colors = "viridis") %>%
layout(title = "",
xaxis = list(title = "Número de Habitaciones"),
yaxis = list(title = "Precio (millones)"),
showlegend = FALSE)Gráfico 9. Boxplot distribución del precio del Apartamento por número de habitaciones
El Gráfico 9 muestra el diagrama de cajas donde el precio de las viviendas (apartamentos) tiende a aumentar con el número de habitaciones, particularmente con mayor dispersión para inmuebles con cuatro, cinco y seis habitaciones. La mediana de precio es mayor en las categorías de cinco y seis habitaciones, lo cual sugiere que estas viviendas pertenecen en promedio a segmentos de mayor valor.
No obstante, el Gráfico 9 también muestra una dispersión considerable de precios dentro de cada categoría y numerosos valores atípicos, especialmente para viviendas con tres o más habitaciones. Esto evidencia que el número de habitaciones, por sí solo, no explica completamente el precio y que intervienen otras características como área construida, estrato, baños, parqueaderos, barrio y calidad del inmueble.
Para el caso de los apartamentos, igual que en el caso anterior, se busca estimar un modelo del tipo:
\[ Precio_i = \beta_0 + \beta_1 X_{1i} + \beta_2 X_{2i} + \cdots + \beta_k X_{ki} + \varepsilon_i \] Donde cada parámetro beta se estima por MCO y epsilon corresponde a los errores del modelo (término estocástico). Para hacer una adecuada estimación del MRL por MCO primero debemos tratar la variable estrato como una variable categórica. Siendo el estrato=3, el estrato de referencia o de base, entonces, e este caso corresponde estimar el siguiente modelo: \[ \begin{aligned} Precio_i =\ & \beta_0 + \beta_1 \, areaconst_i + \beta_2 \, parqueaderos_i + \beta_3 \, banios_i \\ &+ \beta_4 \, habitaciones_i + \delta_4 \, D_{\text{Estrato 4},i} + \delta_5 \, D_{\text{Estrato 5},i} \\ &+ \delta_6 \, D_{\text{Estrato 6},i} + \varepsilon_i \end{aligned} \]
# Modelo 3: estrato como variable categórica
modelo3 <- lm(preciom ~ areaconst + factor(estrato) + habitaciones + parqueaderos + banios,
data = base2_sur)
summary(modelo3)#>
#> Call:
#> lm(formula = preciom ~ areaconst + factor(estrato) + habitaciones +
#> parqueaderos + banios, data = base2_sur)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -1079.3 -37.3 0.7 33.3 905.9
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) -8.2439 11.0672 -0.74 0.456
#> areaconst 1.3057 0.0498 26.22 < 0.0000000000000002 ***
#> factor(estrato)4 17.7659 7.5603 2.35 0.019 *
#> factor(estrato)5 33.6865 7.8916 4.27 0.000020 ***
#> factor(estrato)6 191.4483 9.8973 19.34 < 0.0000000000000002 ***
#> habitaciones -14.5867 3.5111 -4.15 0.000034 ***
#> parqueaderos 51.8708 3.3052 15.69 < 0.0000000000000002 ***
#> banios 42.6083 3.1664 13.46 < 0.0000000000000002 ***
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 89.2 on 2459 degrees of freedom
#> (5 observations deleted due to missingness)
#> Multiple R-squared: 0.785, Adjusted R-squared: 0.784
#> F-statistic: 1.28e+03 on 7 and 2459 DF, p-value: <0.0000000000000002
Cuadro 12. Estimación del Modelo MRL por MCO para el Caso de Apartamentos
El Cuadro 12 muestra que el modelo para las viviendas (apartamentos) de la Zona Sur es globalmente significativo y explica aproximadamente el 78,5% de la variación observada en el precio, medido en millones de pesos. El área construida, el estrato, los baños, los parqueaderos y las habitaciones son estadísticamente significativos; esta última presenta un efecto negativo una vez se controla por las demás características.. Esta estimación se puede representar en forma de ecuación como:
\[ \begin{aligned} \widehat{Preciom}_i =\ & -8.2439 + 1.3057 \, areaconst_i - 14.5867 \, habitaciones_i \\ &+ 51.8708 \, parqueaderos_i + 42.6083 \, banios_i \\ &+ 17.7659 \, D_{\text{Estrato 4},i} + 33.6865 \, D_{\text{Estrato 5},i} \\ &+ 191.4483 \, D_{\text{Estrato 6},i} \end{aligned} \] El modelo fue globalmente significativo (F(7,2459)≈1280, p<0,001) y presentó una capacidad explicativa alta (R2=0,785; R2ajustado = 0,784). Manteniendo constantes las demás características, un metro cuadrado adicional de área construida incrementa el precio esperado en 1,306 millones de pesos; un parqueadero adicional lo incrementa en 51,871 millones y un baño adicional en 42,608 millones. Con respecto al estrato 3, las viviendas de estrato 4, 5 y 6 presentan precios esperados superiores en 17,766, 33,687 y 191,448 millones de pesos, respectivamente. La variable habitaciones presenta un efecto negativo condicional: a igual área construida, estrato, baños y parqueaderos, una habitación adicional se asocia con una reducción estimada de 14,587 millones de pesos en el precio.
Cuadro 13. Salida ANOVA - Modelo de Apartamentos, Zona Sur
El Análisis ANOVA para este modelo se muestra en el Cuadro 13 se interpretan de la forma como se presenta a continuación:
| Variable | gl | Suma de cuadrados | Estadístico F | Valor p | Interpretación secuencial |
|---|---|---|---|---|---|
| Área construida | 1 | 51.552.105 | 6.473,70 | < 0,001 | Es el principal factor explicativo inicial: por sí sola reduce de forma muy importante la variación residual del precio. |
| Estrato | 3 | 15.583.623 | 652,31 | < 0,001 | Una vez incluida el área, las categorías de estrato aportan información adicional muy relevante para explicar el precio. |
| Habitaciones | 1 | 52.793 | 6,63 | 0,010 | Después de controlar por área y estrato, habitaciones aporta una reducción adicional pequeña pero estadísticamente significativa del error. |
| Parqueaderos | 1 | 2.765.252 | 347,25 | < 0,001 | Tras controlar por área, estrato y habitaciones, el número de parqueaderos aporta información adicional fuerte sobre el precio. |
| Baños | 1 | 1.441.976 | 181,08 | < 0,001 | Incluso después de incluir las demás características, el número de baños mejora significativamente el ajuste del modelo. |
| Residuos | 2.459 | 19.581.800 | — | — | Es la variabilidad de los precios que no queda explicada por las variables del modelo. |
En conclusión, la tabla ANOVA muestra que todas las variables incluidas —área construida, estrato, habitaciones, parqueaderos y baños— aportan de manera estadísticamente significativa a explicar el precio de las viviendas de la Zona Sur. El área construida es el factor con mayor aporte secuencial, seguida por el estrato; parqueaderos y baños también tienen contribuciones relevantes, mientras que habitaciones presenta un aporte menor pero significativo.
Los cuatro supuestos que sostienen el modelo son linealidad, homocedasticidad, independencia y normalidad de los errores.
La validación se realiza combinando el análisis gráfico de los residuales con pruebas de hipótesis formales. Dado que los errores del modelo poblacional no son observables, el diagnóstico se apoya en los residuales, que constituyen su contraparte muestral. Se evalúa la homocedasticidad mediante la prueba de Breusch-Pagan, la normalidad mediante Shapiro-Wilk, la independencia mediante Durbin-Watson y la adecuación de la forma funcional mediante la prueba RESET de Ramsey. Se calcularon adicionalmente los factores de inflación de varianza para descartar multicolinealidad y la distancia de Cook para identificar observaciones influyentes, empleando el criterio convencional de 4/n como umbral.
Gráfico 10. Residuals Vs. Fiited; Q-Q Residuals; Scale Location; Residual vs Leverage
El Gráfico 10 expone los gráficos de diagnóstico del MLR y muestran que el modelo estimado presenta inidicios de heterocedasticidad, ya que la dispersión de los residuos aumenta a medida que crecen los valores ajustados; este patrón se evidencia tanto en el gráfico de residuos frente a valores ajustados como en el gráfico Scale–Location.
El gráfico Q-Q muestra desviaciones importantes en las colas, por lo que la normalidad de los residuos no se cumple estrictamente y existen valores extremos. Finalmente, el gráfico de residuos frente a leverage identifica observaciones potencialmente influyentes, especialmente el registro 485, que combina alta palanca con un residuo estandarizado negativo elevado y una distancia de Cook cercana o superior a 1.
La linealidad parece razonable como primera aproximación, pues no se aprecia una curvatura sistemática muy marcada en la media de los residuos. Sin embargo, la heterocedasticidad, la no normalidad en las colas y los casos influyentes implican que los errores estándar convencionales y las pruebas de significancia deben interpretarse con cautela. Como alternativas para investigaciones posteriores, se recomienda emplear errores estándar robustos, considerar una transformación logarítmica del precio, revisar las observaciones influyentes y agregar variables relevantes como barrio, antigüedad, estado de conservación, tipo de inmueble, administración, amenidades o localización exacta, variables que puedan mejorar el modelo.
Los resultados de las pruebas formales para la verificación de los supuestos del modelo de regresión lineal múltiiple se pueden interpretar y resumir como se muestra a continuación:
| Prueba | Hipótesis nula | Resultado | Conclusión |
|---|---|---|---|
| Breusch–Pagan | Varianza constante de los errores | BP=118, gl=7, p<0,001 | Se rechaza homocedasticidad: existe heterocedasticidad |
| Shapiro–Wilk | Residuos con distribución normal | W=0,79, p<0,001 | Se rechaza normalidad de los residuos |
| Durbin–Watson | Ausencia de autocorrelación de primer orden | DW=1,7, p=0,00002 | Evidencia de autocorrelación positiva |
| RESET de Ramsey | Modelo correctamente especificado en su forma funcional | RESET=14, gl1=8, gl2=549, p<0,001 | Evidencia de posible mala especificación: no linealidad y/o variables omitidas |
Cuadro 14. Resultado de las pruebas formales para verificación de supuestos
Al aplicar la Distancia de Cook para el análisis de observaciones influyentes en los resultados del modelo, encontramos 115 observaciones influyentes,se identificó observaciones potencialmente influyentes —aquellas con distancia de Cook superior al umbral exploratorio 4/𝑛 y la Tabla 6 muestra las 10 de mayor área construida entre esos casos. Se trata principalmente de viviendas grandes, ubicadas en sectores de alto valor como Ciudad Jardín y Pance, especialmente de estrato 6; por sus combinaciones inusuales de área, precio y atributos, pueden modificar apreciablemente los coeficientes estimados por el modelo si se retiraran. La distancia de Cook es un diagnóstico de cuánto cambiaría el ajuste al eliminar una observación y combina residuo y palanca (leverage)
#> [1] 115
base2_sur[influyentes, ] %>%
select(barrio, estrato, areaconst, habitaciones, banios, preciom) %>%
arrange(desc(areaconst)) %>%
head(10)Tabla 6. Observaciones potencialmente influyentes
Una forma de resumir estos resultados, podemos mostrarlo en el Cuadro 15:
| Barrio | Estrato | Área m² | Habitaciones | Baños | Precio, millones | Lectura inicial |
|---|---|---|---|---|---|---|
| Ciudad Jardín | 6 | 439 | 4 | 6 | 1.350 | Vivienda grande, alta dotación y alto precio; consistente con segmento de lujo. |
| Ciudad Jardín | 6 | 399 | 3 | 4 | 1.561 | Precio muy alto para el área; posible vivienda premium por ubicación, acabados o amenidades no modeladas. |
| Ciudad Jardín | 6 | 344 | 5 | 5 | 1.150 | Área y atributos elevados; plausible para estrato 6, aunque alejada del centro de la muestra. |
| Ciudad Jardín | 6 | 344 | 4 | 5 | 1.150 | Patrón similar; posible oferta de alta gama. |
| Ciudad Jardín | 6 | 342 | 4 | 5 | 1.750 | Precio particularmente alto; puede generar un residuo positivo grande si el modelo predice un valor menor. |
| Ciudad Jardín | 6 | 330 | 4 | 6 | 950 | Vivienda grande con seis baños; combinación poco frecuente. |
| San Joaquín | 3 | 300 | 5 | 4 | 260 | Área grande y precio muy bajo frente al patrón general; puede generar un residuo negativo importante. |
| Pance | 6 | 290 | 4 | 5 | 1.600 | Segmento de lujo; precio alto que puede no explicarse totalmente con las variables del modelo. |
| Pance | 6 | 290 | 3 | 4 | 1.750 | Precio extremadamente alto para el área declarada; potencial efecto de ubicación, lote, acabados o atributos omitidos. |
| Ciudad Jardín | 6 | 274 | 4 | 4 | 980 | Inmueble grande y de valor alto, pero menos extremo que los anteriores. |
|
Cuadro 15. Análisis de observaciones influyentes
Entre los registros con mayor área se encuentran viviendas de estrato 6 ubicadas principalmente en Ciudad Jardín y Pance, con áreas entre 274 y 439 m², entre cuatro y seis baños y precios entre 950 y 1.750 millones de pesos. Estas ofertas corresponden al segmento de alta gama y pueden ejercer influencia sobre los coeficientes debido a su combinación poco frecuente de atributos y precios.
Asimismo, se identificó una vivienda en San Joaquín, estrato 3, con 300 m², cinco habitaciones, cuatro baños y un precio de 260 millones de pesos, combinación que resulta inusualmente baja frente al patrón general. Estos casos deben revisarse para validar la consistencia de las unidades, precios, tipo de inmueble y características registradas. No se recomienda eliminar observaciones automáticamente, dado que pueden corresponder a inmuebles válidos; en su lugar, se sugiere realizar un análisis de sensibilidad, revisar los casos con mayor distancia de Cook y considerar la inclusión de atributos no observados, como barrio, antigüedad, tamaño del lote, acabados y amenidades.
#> GVIF Df GVIF^(1/(2*Df))
#> areaconst 2.110 1 1.453
#> factor(estrato) 1.897 3 1.113
#> habitaciones 1.429 1 1.195
#> parqueaderos 1.935 1 1.391
#> banios 2.652 1 1.629
Cuadro 16. Resultado de la Prueba de Multicolinealidad
El diagnóstico de multicolinealidad no evidenció problemas relevantes. Debido a que el estrato se incluyó como variable categórica, se utilizó el Factor Generalizado de Inflación de la Varianza (GVIF) y su medida ajustada 𝐺𝑉𝐼𝐹1/(2⋅𝐷𝑓). Los valores ajustados oscilaron entre 1,113 para el estrato y 1,629 para el número de baños. Estos valores son cercanos a 1 y se encuentran por debajo de los umbrales convencionales de alerta. Por tanto, no existe evidencia de relaciones lineales fuertes entre las variables explicativas que inflen de forma importante los errores estándar o afecten la estabilidad de los coeficientes del modelo.
Con el modelo estimado se procede a predecir el precio esperado para las características de la primera solicitud: 1. Área construida: \(300\text{ m}^2\). 2. Parqueaderos: \(3\). 3. Baños: \(3\). 4. Habitaciones: \(5\). 5. Estrato: \(5\) o \(6\). 6. Zona: Sur. 7. Tipo: Apartamentos
solicitud2 <- data.frame(
areaconst = c(300, 300),
estrato = c(5, 6),
habitaciones = c(5, 5),
parqueaderos = c(5, 5),
banios = c(3, 3)
)Dado que la condición de estrato admitía dos valores, la predicción se calculará para ambos escenarios (estrato 4 y 5).
Se construyen dos tipos de intervalo al 95% de confianza. Por un lado, el intervalo de confianza limita el precio medio de la población de viviendas que comparten esas características e incorpora únicamente la incertidumbre asociada a la estimación de los coeficientes. Por otro lados, el intervalo de predicción limita el precio de una vivienda individual y añade la variabilidad propia de cada inmueble, cuantificada por el error estándar residual, razón por la cual resulta sistemáticamente más amplio.
library(dplyr)
library(knitr)
library(kableExtra)
pred_conf <- predict(modelo3, newdata = solicitud2, interval = "confidence")
pred_pred <- predict(modelo3, newdata = solicitud2, interval = "prediction")
tabla_pred <- data.frame(
Estrato = c(5, 6),
Estimado = round(pred_conf[, "fit"], 1),
IC_inf = round(pred_conf[, "lwr"], 1),
IC_sup = round(pred_conf[, "upr"], 1),
IP_inf = round(pred_pred[, "lwr"], 1),
IP_sup = round(pred_pred[, "upr"], 1)
)
tabla_pred %>%
kable(align = "c",
col.names = c("Estrato", "Precio estimado",
"Límite inferior", "Límite superior",
"Límite inferior", "Límite superior"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
add_header_above(c(" " = 2,
"Intervalo de confianza 95%" = 2,
"Intervalo de predicción 95%" = 2)) %>%
column_spec(1, bold = TRUE) %>%
column_spec(2, bold = TRUE, background = "#EAF2F8") %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Estrato | Precio estimado | Límite inferior | Límite superior | Límite inferior | Límite superior |
|---|---|---|---|---|---|
| 5 | 731.4 | 704.0 | 758.8 | 554.3 | 908.5 |
| 6 | 889.2 | 862.4 | 915.9 | 712.1 | 1066.2 |
Cuadro 17. Precio estimado de la Vivienda 2 (Apartamentos) según estrato (en millones de pesos)
Para una vivienda de la Zona Sur con 300 m², 5 habitaciones, 5 parqueaderos y 3 baños, el modelo estima un precio de 731,4 millones si es de estrato 5 y de 889,2 millones si es de estrato 6. La vivienda de estrato 5 se ubica por debajo de un crédito de 850 millones, mientras que la de estrato 6 lo supera en su predicción puntual.
Para el estrato 5 podemos ver que el intervalo de confianza al 95%, entre 704,0 y 758,8 millones, se refiere al precio promedio esperado de todas las viviendas con ese mismo perfil de características en la población analizada.
El intervalo de predicción al 95%, entre 554,3 y 908,5 millones, se refiere al precio de una vivienda individual con esas características. Es más amplio porque, además de la incertidumbre del modelo, incorpora diferencias no explicadas por variables omitidas: barrio específico, tamaño del lote, estado de conservación, edad, acabados, piscina, administración, seguridad, vista, ubicación precisa y amenidades. Los intervalos de predicción son siempre más amplios que los intervalos de confianza para la media.
Para el estrato 6, el intervalo de confianza se encuentra entre 862,4 y 915,9 millones; incluso su límite inferior supera un crédito de 850 millones. Por ello, según el modelo, el valor promedio esperado de una vivienda de estrato 6 con estas características se encuentra por encima de ese presupuesto.
El intervalo de predicción, de 712,1 a 1.066,2 millones, sí contiene valores inferiores a 850 millones. Esto significa que podrían existir algunas viviendas individuales de estrato 6 dentro del crédito, pero serían casos por debajo del precio esperado del perfil y requerirían una búsqueda selectiva, una negociación favorable o características no observadas que reduzcan el precio.
Nos parece muy importante aclarar que las predicciones deben interpretarse con cautela ya que el modelo previamente presentó heterocedasticidad, no normalidad de residuos, observaciones influyentes o posible mala especificación. En particular, los intervalos producidos por predict.lm() se basan en supuestos clásicos del modelo lineal. Por tanto, son útiles como referencia comparativa, pero la decisión final debe verificarse contra ofertas reales y considerar otras variables.
library(dplyr)
library(knitr)
library(kableExtra)
resumen_cand <- candidatas2 %>%
group_by(Estrato = estrato) %>%
summarise(Ofertas = n(),
area_min = min(areaconst),
area_med = median(areaconst),
area_max = max(areaconst),
.groups = "drop") %>%
bind_rows(
candidatas2 %>%
summarise(Estrato = NA,
Ofertas = n(),
area_min = min(areaconst),
area_med = median(areaconst),
area_max = max(areaconst))
) %>%
mutate(Estrato = ifelse(is.na(Estrato), "Total", as.character(Estrato)),
across(starts_with("area"), ~ round(., 0)))
resumen_cand %>%
kable(align = "c",
col.names = c("Estrato", "Ofertas", "Mínima", "Mediana", "Máxima"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
add_header_above(c(" " = 2, "Área construida" = 3)) %>%
column_spec(1, bold = TRUE) %>%
column_spec(2, bold = TRUE, background = "#EAF2F8") %>%
row_spec(nrow(resumen_cand), bold = TRUE, background = "#D5DBDB") %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Estrato | Ofertas | Mínima | Mediana | Máxima |
|---|---|---|---|---|
| 5 | 2 | 300 | 436 | 573 |
| Total | 2 | 300 | 436 | 573 |
Cuadro 18. Candidatas dentro del presupuesto según estrato y área construida (m²)
El Cuadro 18 muestra que se identificó únicamente dos ofertas potenciales, ambas de estrato 5, que cumplen simultáneamente los requerimientos físicos y financieros definidos. No se encontraron viviendas de estrato 6 que cumplieran todos los criterios bajo el tope de 850 millones.
Las dos alternativas cumplen el mínimo de 300 m², pero una de ellas tiene 573 m², es decir, presenta un excedente considerable de área frente al requerimiento.
La ausencia de ofertas de estrato 6 se relaciona con la predicción del modelo: para una vivienda de 300 m², cinco habitaciones, cinco parqueaderos y tres baños, la predicción en estrato 6 fue de aproximadamente 889,2 millones, cifra superior al crédito preaprobado de 850 millones. Por tanto, es consistente que no se encuentren ofertas de estrato 6 con este perfil dentro del presupuesto. En contraste, el precio estimado para estrato 5 fue de 731,4 millones, lo cual se mantiene dentro del crédito.Con respecto a los requerimientos físicos de área, baños, habitaciones y parqueadero hay dos ofertas adicionales, pero su precio supera los 1000 millones de pesos, que está por fuera del crédito preaprobado.
library(dplyr)
library(knitr)
library(kableExtra)
seleccion <- candidatas3 %>%
group_by(estrato) %>%
slice_max(diferencia, n = 3) %>%
ungroup() %>%
arrange(desc(descuento_pct))
seleccion %>%
mutate(barrio = tools::toTitleCase(barrio),
Ficha = paste0(habitaciones, " / ", banios, " / ", parqueaderos),
descuento_pct = paste0(descuento_pct, "%")) %>%
select(barrio, estrato, areaconst, Ficha, preciom, precio_estimado, descuento_pct) %>%
kable(align = c("l", "c", "c", "c", "c", "c", "c"),
col.names = c("Barrio", "Estrato", "Área (m²)",
"Hab. / Baños / Parq.",
"Precio ofertado", "Valor estimado", "Diferencia"),
caption = "") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE, position = "center") %>%
add_header_above(c(" " = 4, "Valoración" = 3)) %>%
column_spec(1, bold = TRUE) %>%
column_spec(5, bold = TRUE, background = "#EAF2F8") %>%
column_spec(7, bold = TRUE, color = "#1E8449") %>%
row_spec(0, bold = TRUE, background = "#2C3E50", color = "white")| Barrio | Estrato | Área (m²) | Hab. / Baños / Parq. | Precio ofertado | Valor estimado | Diferencia |
|---|---|---|---|---|---|---|
| Guadalupe | 5 | 573 | 5 / 8 / 3 | 730 | 849.6 | 14.1% |
| Seminario | 5 | 300 | 6 / 5 / 3 | 670 | 567.6 | -18% |
Cuadro 19. Ofertas recomendadas para la Vivienda 2 - Apartamentos de la Zona Sur (cifras en millones de pesos)
El Cuadro 19 muestra que el filtro final dejó solo dos ofertas potenciales, ambas de estrato 5: una en el Barrio Guadalupe y otra en Seminario. Ambas cumplen los requisitos físicos mínimos y están por debajo del crédito de 850 millones. Sin embargo, su comparación con el valor estimado por el modelo sugiere situaciones distintas. La diferencia entre precio estimado y ofertado sirve como una señal comparativa de valoración, no como prueba definitiva de que una oferta sea barata o cara, porque el modelo no incluye todas las características inmobiliarias que se deben tener en cuenta.
No aparece ninguna alternativa de estrato 6 bajo los filtros establecidos. Esto es consistente con el mayor precio esperado de las viviendas de estrato 6 para este perfil, que tiende a acercarse o superar el límite de crédito.
library(leaflet)
library(htmltools)
pal <- colorFactor(c("#2E86C1", "#C0392B"), domain = c(5, 6))
etiqueta <- function(d) {
lapply(seq_len(nrow(d)), function(i) {
HTML(paste0(
"<b>", tools::toTitleCase(d$barrio[i]), "</b> — Estrato ", d$estrato[i], "<br>",
"Área: ", d$areaconst[i], " m²<br>",
"Habitaciones: ", d$habitaciones[i], "<br>",
"Baños: ", d$banios[i], "<br>",
"Parqueaderos: ", d$parqueaderos[i], "<br>",
"<b>Precio: $", d$preciom[i], " millones</b>"
))
})
}
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
addCircleMarkers(data = base2_sur,
~longitud, ~latitud,
radius = 2, color = "grey", stroke = FALSE, fillOpacity = 0.2,
group = "Mercado del Sur") %>%
addCircleMarkers(data = candidatas3,
~longitud, ~latitud,
radius = 5, color = "#F39C12", stroke = FALSE, fillOpacity = 0.5,
group = "Candidatas viables",
label = etiqueta(candidatas2),
popup = ~paste0("<b>", barrio, "</b><br>$", preciom, " M | ",
areaconst, " m² | Estrato ", estrato)) %>%
addCircleMarkers(data = seleccion,
~longitud, ~latitud,
radius = 10, color = ~pal(estrato),
stroke = TRUE, weight = 2, opacity = 1, fillOpacity = 0.9,
group = "Ofertas recomendadas",
label = etiqueta(seleccion),
labelOptions = labelOptions(
style = list("font-size" = "13px", "padding" = "8px"),
direction = "auto"),
popup = ~paste0("<b>", toupper(barrio), "</b><br>",
"Estrato ", estrato, " | ", areaconst, " m²<br>",
habitaciones, " habitaciones | ", banios, " baños | ",
parqueaderos, " parqueaderos<br><hr>",
"<b>Precio ofertado: $", preciom, " M</b><br>",
"Valor estimado: $", precio_estimado, " M<br>",
"Diferencia a favor: $", diferencia, " M (",
descuento_pct, "%)")) %>%
addLegend("bottomright",
colors = c("#2E86C1", "#C0392B", "#F39C12", "grey"),
labels = c("Recomendada estrato 4", "Recomendada estrato 5",
"Otras candidatas viables", "Mercado del norte"),
title = "Ofertas para la Vivienda 1") %>%
addLayersControl(overlayGroups = c("Ofertas recomendadas", "Candidatas viables",
"Mercado del norte"),
options = layersControlOptions(collapsed = FALSE))*Mapa 5. Ubicación Espacial de los Apartamentos candidatos (que se ajustan a las condiciones solicitadas)
Tras aplicar los criterios de búsqueda —estratos 5 o 6, precio máximo de 850 millones de pesos, área construida mínima de 300 m², cinco o más habitaciones, tres o más baños y tres o más parqueaderos— se identificaron dos ofertas potenciales, ambas de estrato 5. No se identificaron ofertas de estrato 6 que cumplieran simultáneamente todos los requerimientos y el límite financiero (Ver Mapa 5). . La primera alternativa, ubicada en Guadalupe, presenta 573 m², cinco habitaciones, ocho baños y tres parqueaderos. Su precio ofertado es de 730 millones de pesos, mientras que el modelo estima un valor de 849,6 millones. Por tanto, la oferta se encuentra aproximadamente 119,6 millones (14,1%) por debajo de la valoración estimada, lo que la convierte en la alternativa más atractiva desde la comparación con el modelo.
La segunda alternativa, localizada en Seminario, cuenta con 300 m², seis habitaciones, cinco baños y tres parqueaderos. Su precio ofertado es de 670 millones, superior en 102,4 millones (18,0%) al valor estimado de 567,6 millones. Aunque se encuentra dentro del crédito y coincide exactamente con el área mínima requerida, el modelo sugiere que debe revisarse cuidadosamente o negociarse el precio, salvo que atributos no observados justifiquen la prima solicitada.
Las conclusiones deben interpretarse como una guía inicial de valoración. Dado que el modelo no incorpora variables como estado de conservación, antigüedad, tamaño de lote, características de lujo, seguridad, administración y ubicación específica, la elección final debe complementarse con visita al inmueble, avalúo profesional, revisión documental y análisis de costos de compra y mantenimiento.
El análisis desarrollado para C&A permitió construir dos modelos de regresión lineal múltiple diferenciados por zona geográfica y tipo de vivienda, con el propósito de apoyar la recomendación de compra para los dos empleados de la compañía internacional. Los modelos estiman el precio ofertado, en millones de pesos, a partir del área construida, estrato, número de habitaciones, parqueaderos y baños. Esta aproximación es consistente con la valoración inmobiliaria hedónica, en la cual el valor esperado de una propiedad se relaciona con sus atributos físicos y de localización.
Para la Vivienda 1, correspondiente a una casa en la Zona Norte con 200 m² de área construida, dos baños, cuatro habitaciones, un parqueadero y estrato 4 o 5, el modelo estimó un precio de 327,5 millones de pesos para estrato 4 y de 381,1 millones de pesos para estrato 5. Dado que el crédito preaprobado es de 350 millones, la vivienda de estrato 4 constituye la alternativa financieramente viable según la predicción puntual, dejando un margen aproximado de 22,5 millones. En cambio, la opción de estrato 5 supera el presupuesto en 31,1 millones; por tanto, solo sería recomendable si se logra una negociación favorable, se cuenta con recursos propios complementarios o se incrementa el monto de financiación.
El análisis de oferta disponible para casas de área comparable en la Zona Norte mostró que existen opciones dentro del presupuesto, pero son limitadas. Para estrato 4, se identificaron ofertas desde 315 millones, mientras que en estrato 5 las alternativas comienzan cerca de 330 millones; no obstante, el valor estimado de ambos grupos se ubica por encima de 350 millones.
Para la Vivienda 2, correspondiente a un apartamento en la Zona Sur con 300 m², cinco habitaciones, tres baños, tres parqueaderos y estrato 5 o 6, el modelo evidenció una capacidad explicativa alta. El área construida, estrato, baños y parqueaderos fueron determinantes relevantes del precio, mientras que la relación de habitaciones debe entenderse de manera condicional: a igual área, estrato, baños y parqueaderos, un mayor número de habitaciones puede reflejar una distribución interna más fragmentada.
Las predicciones para el apartamento indican que el estrato 5 es la alternativa más compatible con el crédito de 850 millones. Para un perfil de 300 m², cinco habitaciones, tres baños y tres parqueaderos, el modelo estimó un valor aproximado de 633,5 millones de pesos en estrato 5 y de 795,5 millones de pesos en estrato 6. Por tanto, ambas alternativas se encuentran dentro del crédito preaprobado en términos de predicción puntual; sin embargo, la alternativa de estrato 5 deja un margen financiero mucho mayor y reduce el riesgo de exceder el presupuesto cuando se incorporan gastos adicionales de compra.
Al evaluar ofertas reales con criterios más estrictos —área mínima de 300 m², al menos cinco habitaciones, tres baños, tres parqueaderos, estrato 5 o 6 y precio máximo de 850 millones— se identificaron únicamente dos viviendas candidatas, ambas de estrato 5. La oferta ubicada en Guadalupe, con 573 m², cinco habitaciones, ocho baños y tres parqueaderos, presenta un precio ofertado de 730 millones frente a un valor estimado de 849,6 millones. Esto representa una diferencia favorable de aproximadamente 119,6 millones, equivalente al 14,1% por debajo de la valoración del modelo. Esta es la alternativa prioritaria, siempre que se valide la calidad del inmueble, la consistencia de sus datos, los costos de mantenimiento asociados a su gran tamaño y su situación jurídica.
La segunda alternativa, ubicada en Seminario, cuenta con 300 m², seis habitaciones, cinco baños y tres parqueaderos. Su precio ofertado de 670 millones es inferior al crédito disponible, pero supera en aproximadamente 102,4 millones la valoración estimada por el modelo, equivalente a un 18% por encima del valor predicho. Por ello, esta vivienda puede mantenerse como alternativa secundaria por cumplir exactamente el mínimo de área requerido y dejar un margen de 180 millones frente al crédito. Sin embargo, se recomienda negociar el precio o verificar si sus atributos no incluidos en el modelo.
Notas de clase (2026). Curso de Modelos Estadísticos para la toma de decisiones. Brigthspace. Maestría en Ciencia de Datos, PUJ
Greenacre, M. (2017). Correspondence analysis in practice (3rd ed.). Chapman and Hall/CRC.
Husson, F., Lê, S., & Pagès, J. (2017). Exploratory multivariate analysis by example using R (2nd ed.). Chapman and Hall/CRC.
Jolliffe, I. T., & Cadima, J. (2016). Principal component analysis: A review and recent developments. Philosophical Transactions of the Royal Society A: Mathematical, Physical and Engineering Sciences, 374(2065), 20150202. https://doi.org/10.1098/rsta.2015.0202
Kaufman, L., & Rousseeuw, P. J. (2009). Finding groups in data: An introduction to cluster analysis. John Wiley & Sons.
Rousseeuw, P. J. (1987). Silhouettes: A graphical aid to the interpretation and validation of cluster analysis. Journal of Computational and Applied Mathematics, 20, 53–65. https://doi.org/10.1016/0377-0427(87)90125-7
En la elaboración de este informe se utilizó AI como herramienta de apoyo para la elaboración de código en R y revisión de la presentación de resultados.
La inteligencia artificial no sustituyó el trabajo analítico de los autores. La selección de la base de datos, definición de variables, depuración, filtrado de observaciones, ejecución de los modelos, obtención de resultados, validación de supuestos, interpretación final y recomendaciones fueron realizadas, revisadas y verificadas por los autores.
los autores asumen plena responsabilidad por la exactitud de los análisis, la verificación de los resultados generados en R, la utilización de las fuentes y el contenido final del documento.