Maria comenzó como agente de bienes raíces en Cali hace 10 años. Después de laborar dos años para una empresa nacional, se traslado a Bogotá y trabajó para otra agencia de bienes raíces. Sus amigos y familiares la convencieron de que con su experiencia y conocimientos del negocio debía abrir su propia agencia. Terminó por adquirir la licencia de intermediario y al poco tiempo fundó su propia compañía, C&A (Casas y Apartamentos) en Cali. Santiago y Lina, dos vendedores de la empresa anterior aceptaron trabajar en la nueva compaña. En la actualidad ocho agentes de bienes raíces colaboran con ella en C&A.
Actualmente las ventas de bienes raíces en Cali se han visto disminuidas de manera significativa en lo corrido del año. Durante este periodo muchas instituciones bancarias de ahorro y vivienda están prestando grandes sumas de dinero para la industria y la construcción comercial y residencial. Cuando el efecto producto de las tensiones políticas y sociales disminuya, se espera que la actividad económica de este sector se reactive.
Hace dos días, María recibió una carta solicitando asesoría para la compra de dos viviendas por parte de una compañía internacional que desea ubicar a dos de sus empleados con sus familias en la ciudad. Las solicitudes incluyen las siguientes condiciones:
| Características | Vivienda 1 | Vivienda 2 |
|---|---|---|
| Tipo | Casa | Apartamento |
| Área construida | 200 | 300 |
| Parqueaderos | 1 | 3 |
| Baños | 2 | 3 |
| Habitaciones | 4 | 5 |
| Estrato | 4 o 5 | 5 o 6 |
| Zona | Norte | Sur |
| Crédito preaprobado | 350 millones | 850 millones |
Carga y análisis exploratorio inicial de datos
Perfilado inicial de variables: Objetivo: ver tipo de dato, cardinalidad y cantidad de nulos por columna.
| variable | dtype | n_unique | n_missing |
|---|---|---|---|
| id | numeric | 8320 | 3 |
| zona | character | 6 | 3 |
| piso | character | 13 | 2638 |
| estrato | numeric | 5 | 3 |
| preciom | numeric | 540 | 2 |
| areaconst | numeric | 653 | 3 |
| parqueaderos | numeric | 11 | 1605 |
| banios | numeric | 12 | 3 |
| habitaciones | numeric | 12 | 3 |
| tipo | character | 3 | 3 |
| barrio | character | 437 | 3 |
| longitud | numeric | 2929 | 3 |
| latitud | numeric | 3680 | 3 |
Hacemos normalización de nombres (errores tipográficos). Quitamos identificadores que no son son útiles.
Como la idea es hacer análisis para las zonas norte y sur, revisemos que los datos si estén correctamente catalogados.
Como se puede ver, las zonas están mal catalogadas, vamos a corregir eso para Norte y Sur que son las zonas que nos importan.
Se recategorizó la ciudad únicamente en Zona Norte y Zona Sur usando una frontera probabilística de latitud y longitud aprendida con un modelo logístico (GLM) a partir de “semillas” geográficas (los puntos más australes y más boreales dentro del casco urbano). Para evitar sesgos por periferia, solo se clasificaron inmuebles dentro de un corredor Este–Oeste definido entre los percentiles 12 y 88 de la longitud muestral. Dentro de ese corredor, un inmueble se asigna a Sur si la probabilidad de pertenecer al Norte es ≤ 0,45; se asigna a Norte si esa probabilidad es ≥ 0,70 y, además, su latitud supera el percentil 62 de la distribución (piso mínimo de latitud para Norte). Los casos que no cumplen ninguna de estas dos condiciones se consideran zona neutral y se excluyen del análisis Norte/Sur. Previamente, se aplicó un filtro urbano amplio a las coordenadas (latitud 3,2–3,6 y longitud −76,7 a −76,4) para remover puntos fuera del área de interés. Con este esquema se reduce el traslape entre zonas y se “eleva” la frontera de Norte sin invadir el Sur; si la probabilidad no convence, el punto no se fuerza: queda fuera.
Caso 1: Vivienda Norte
Primero, constuimos un data set de solo Casas en Zona Norte; luego, mostramos las primeros tres lineas y tablas de validación.
| zona | piso | estrato | precio | area_construida | parqueaderos | baños | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Zona Norte | 02 | 5 | 320 | 150 | 2 | 4 | 6 | Casa | acopi | -76.51341 | 3.47968 |
| Zona Norte | 02 | 5 | 780 | 380 | 2 | 3 | 3 | Casa | acopi | -76.51674 | 3.48721 |
| Zona Norte | NA | 3 | 380 | 300 | NA | 5 | 8 | Casa | acopi | -76.50743 | 3.46566 |
| tipo | zona | n |
|---|---|---|
| Casa | Zona Norte | 689 |
| variable | dtype | n_unique | n_missing |
|---|---|---|---|
| zona | character | 1 | 0 |
| piso | character | 8 | 288 |
| estrato | numeric | 4 | 0 |
| precio | numeric | 169 | 0 |
| area_construida | numeric | 259 | 0 |
| parqueaderos | numeric | 11 | 186 |
| baños | numeric | 11 | 0 |
| habitaciones | numeric | 11 | 0 |
| tipo | character | 1 | 0 |
| barrio | character | 136 | 0 |
| longitud | numeric | 359 | 0 |
| latitud | numeric | 365 | 0 |
División de datos
Solo piso y parqueadero tienen nulos, como ambos son categóricos vamos a imputarlos con la moda. Pero antes dividamos el data set en datos de entrenamiento y de prueba, parea evitar data leakeage.Posteriormente lo dividiremos en datos numérico: area construida, precio y estrato, todos los demás quedaran en categóricos y serán reclasificado, solo posteriormente imputaremos los nulos en los datos de entrenamiento con la moda
Dividimos base1 en entrenamiento (80%) y prueba (20%) con semilla fija para reproducibilidad (sin tocar coordenadas ni imputar nada todavía).
| conjunto | n |
|---|---|
| train | 551 |
| test | 138 |
Separamos numéricos (area_construida, precio, estrato) y dejamos el resto como categóricos (factor).
| tipo | n_columnas |
|---|---|
| numéricas (train) | 3 |
| categóricas (train) | 7 |
| numéricas (test) | 3 |
| categóricas (test) | 7 |
| variable | n_na_train | n_na_test |
|---|---|---|
| piso | 227 | 61 |
| parqueaderos | 155 | 31 |
Limpieza de datos
Imputamos solo en entrenamiento los NAs de piso y parqueaderos con la moda de train_df; guardo las modas en imputer_modes para aplicar luego a test (sin fuga de información).
| variable | na_antes | moda_train | na_despues |
|---|---|---|---|
| piso | 227 | 02 | 0 |
| parqueaderos | 155 | 2 | 0 |
Aplica amos test_df las modas ya aprendidas en train_df (guardadas en imputer_modes) sin recalcular nada.
Detectamos outliers en train_df por z-score (k = 3 por defecto) en columnas numéricas area_construida, precio, estrato. Reporto media, sd, límites y conteos.
| variable | mean | sd | z_k | lower_limit | upper_limit | n | n_out_low | n_out_high | n_outliers | pct_outliers |
|---|---|---|---|---|---|---|---|---|---|---|
| area_construida | 304.5947 | 174.2279 | 3 | -218.0891 | 827.2784 | 551 | 0 | 10 | 10 | 1.81 |
| precio | 544.8348 | 328.7218 | 3 | -441.3305 | 1531.0002 | 551 | 0 | 12 | 12 | 2.18 |
| estrato | 4.4283 | 1.0188 | 3 | 1.3718 | 7.4848 | 551 | 0 | 0 | 0 | 0.00 |
Winsorizamos sono en datos de entrenamiento: capeo valores por debajo/encima a los límites (inferior/superior) calculados arriba; reporto cuántos quedaron exactamente en cada límite.
| variable | lower_limit | upper_limit | n_out_low_before | n_out_high_before | n_at_lower_after | n_at_upper_after | n_out_high_after |
|---|---|---|---|---|---|---|---|
| area_construida | -218.0891 | 827.2784 | 0 | 10 | 0 | 10 | 0 |
| precio | -441.3305 | 1531.0002 | 0 | 12 | 0 | 12 | 0 |
| estrato | 1.3718 | 7.4848 | 0 | 0 | 0 | 0 | 0 |
capeo en TEST usando los mismos límites calculados en TRAIN (z_limits).
Correlaciones
Matriz de correlaciones (Spearman) en TRAIN usando nuestro set numérico: precio, area_construida, estrato.
Correlación entre categóricas y precio en TRAIN usando Correlation Ratio (η) + p(Kruskal–Wallis). Solo se reportan variables con ≥2 niveles y datos suficientes.
Las columnas numéricas tiene una correlación aceptable. En las categóricas tenemos resultados mixtos. Barrio es quien presentó mayor correlación, pero como tiene tanto valores únicos (126) no nos sirve como predictora. Piso puede ser descartada porque es muy baja su correlación, habitaciones también tiene poca correlación, pero ya que hay tan pocas variables, dejémosla. Lo hago en TRAIN y TEST para evitar incoherencias más delante.
| columna | motivo |
|---|---|
| barrio | Alta cardinalidad (niveles en TRAIN ≈ 126), poco útil como predictora. |
| piso | Baja correlación con el precio (η muy baja). |
Modelo 1
Ajustamos un modelo lineal múltiple en TRAIN (BASE1–Zona Norte): precio ~ area_construida + estrato + habitaciones + parqueaderos + baños.
| term | estimate | std.error | statistic | p.value | conf.low | conf.high | signif |
|---|---|---|---|---|---|---|---|
| (Intercept) | -303.0225 | 44.7335 | -6.7740 | 0.0000 | -390.8937 | -215.1514 | *** |
| area_construida | 0.8762 | 0.0628 | 13.9622 | 0.0000 | 0.7529 | 0.9994 | *** |
| estrato | 88.4126 | 9.4702 | 9.3359 | 0.0000 | 69.8101 | 107.0151 | *** |
| habitaciones | -10.1167 | 5.3176 | -1.9025 | 0.0576 | -20.5623 | 0.3289 | . |
| parqueaderos | 39.1976 | 7.0813 | 5.5354 | 0.0000 | 25.2876 | 53.1076 | *** |
| baños | 39.0330 | 6.7789 | 5.7580 | 0.0000 | 25.7170 | 52.3490 | *** |
Reporte de métricas globales del modelo (R², R² ajustado, RMSE y MAE en TRAIN) para juzgar el ajuste.
| r_squared | r_squared_adj | sigma_residual | rmse_train | mae_train | n_obs |
|---|---|---|---|---|---|
| 0.6109 | 0.6074 | 196.0003 | 194.9302 | 135.8981 | NA |
Coeficientes e interpretación (con IC95% y significancia)
Área construida: 0.8762 M por m² [ 0.7529 ; 0.9994] [0.7529;0.9994], p<0.001. Traducción útil: +10 m² ≈ +8.8 M [ + 7.5 ; + 10.0] [+7.5;+10.0]. Lógico y fuerte: a mayor área, mayor precio.
Estrato: +88.41 M por +1 nivel [ + 69.81 ; + 107.02] [+69.81;+107.02], p<0.001. El estrato captura localización/calidad de entorno: efecto grande y coherente.
Parqueaderos: +39.20 M por +1 [ + 25.29 ; + 53.11] [+25.29;+53.11], p<0.001. La disponibilidad de parqueo se capitaliza claramente en el precio.
Baños: +39.03 M por +1 [ + 25.72 ; + 52.35] [+25.72;+52.35], p<0.001. Más baños ⇒ mayor confort/segmento ⇒ mayor precio; de nuevo, consistente.
Habitaciones: −10.12 M por +1 [ − 20.56 ; + 0.33] [−20.56;+0.33], p=0.0576 (marginal, ~10%). Señal “rara” pero plausible: condicional al área, más cuartos pueden implicar espacios más pequeños (menor lujo) y arrastrar el precio hacia abajo. También puede haber colinealidad con área/baños; tomar con pinzas.
Intercepto: −303.02 M (no interpretable en el rango real de las covariables: corresponde a área, estrato, etc. en cero).
Calidad de ajuste (TRAIN)
R² = 0.611, R² ajustado = 0.607 → ajuste moderado-alto: el modelo explica ~61% de la variabilidad del precio.
RMSE ≈ 194.9 M; MAE ≈ 135.9 M.
Lectura práctica: el error típico ronda 136–195 millones. Para valorar si esto es “mucho o poco”, conviene compararlo con la mediana o el rango de precios de base1; si tus casas suelen estar en, por ejemplo, 600–900 M, el error puede ser tolerable; si están en 300–500 M, es más alto relativo.
Los signos tienen sentido: área, estrato, baños y parqueaderos positivos y fuertes tiene todo el sentido. El caso de habitaciones negativo (y apenas significativo) es el único raro: sugiere que, a igual área, pasar de espacios amplios a más cuartos reduce la calidad percibida. También puede ser ruido e incluso multicolinealidad.
Diagnósis
Diagnósticos del modelo (residuales estandarizados, leverage, Cook’s).
| row_id | fitted | resid | std_resid | leverage | cooksd |
|---|---|---|---|---|---|
| 1 | 555.561 | 34.439 | 0.177 | 0.010 | 0.000 |
| 2 | 356.990 | 83.010 | 0.428 | 0.022 | 0.001 |
| 3 | 610.838 | 489.162 | 2.502 | 0.005 | 0.005 |
| 4 | 570.391 | 59.609 | 0.305 | 0.005 | 0.000 |
| 5 | 526.021 | -230.021 | -1.181 | 0.012 | 0.003 |
Pruebas formales por supuesto: BP (homocedasticidad), Shapiro (normalidad, con cautela), Durbin–Watson (independencia), VIF (multicolinealidad) e influencias (Cook’s).
| supuesto | metric | estado |
|---|---|---|
| Homocedasticidad (BP) | p=0.000 | Revisar |
| Normalidad (Shapiro) | p=0.000 | Revisar |
| Independencia (Durbin–Watson) | DW=2.08, p=0.826 | OK |
| Multicolinealidad (VIF) | max(VIF)=1.69 | OK |
| Influencias (Cook’s) | Cook’s > 4/n: 47 casos (umbral=0.007) | Revisar |
| variable | VIF |
|---|---|
| area_construida | 1.426 |
| estrato | 1.333 |
| habitaciones | 1.457 |
| parqueaderos | 1.154 |
| baños | 1.686 |
Gráficos interactivos (plotly) para inspección visual: residuales vs ajustados (linealidad/varianza), Q-Q de residuales (normalidad) y escala-ubicación.
Puntos influyentes (Cook’s). Muestra top casos y gráfico interactivo.
| row_id | fitted | resid | std_resid | leverage | cooksd | flag |
|---|---|---|---|---|---|---|
| 456 | 578.5939 | 952.4063 | 4.9220 | 0.0254 | 0.1051 | TRUE |
| 265 | 738.7786 | 661.2214 | 3.4473 | 0.0423 | 0.0876 | TRUE |
| 399 | 763.9985 | -563.9985 | -2.9595 | 0.0546 | 0.0844 | TRUE |
| 316 | 847.8185 | 683.1817 | 3.5377 | 0.0292 | 0.0627 | TRUE |
| 27 | 698.4438 | -348.4438 | -1.8707 | 0.0969 | 0.0626 | TRUE |
| 328 | 866.1166 | 664.8836 | 3.4411 | 0.0282 | 0.0572 | TRUE |
| 113 | 736.0457 | 794.9545 | 4.0878 | 0.0156 | 0.0440 | TRUE |
| 135 | 1075.6175 | 455.3827 | 2.3715 | 0.0402 | 0.0392 | TRUE |
| 423 | 1129.0334 | 401.9668 | 2.0960 | 0.0426 | 0.0326 | TRUE |
| 59 | 1194.1503 | -544.1503 | -2.8098 | 0.0237 | 0.0320 | TRUE |
Validación de supuestos
Homoscedasticidad (BP p=0.000): la prueba rechaza varianza constante; en las gráficas se aprecia un leve “abanico” a precios altos, típico en datos de vivienda. Para inferencia confiable usamos errores estándar (SE) robustos y sugerimos, como mejora, un modelo logarítmico.
Normalidad de residuales (Shapiro p=0.000): desviaciones en colas; el Q–Q no muestra patologías extremas. Con tamaños moderados, la inferencia con SE robustos es suficiente para decisiones prácticas.
Independencia (DW=2.08, p=0.826): sin evidencia de autocorrelación; esperable en corte transversal.
Multicolinealidad (max VIF ≈ 1.69): baja; los coeficientes están bien identificados.
Puntos influyentes (47 con Cook’s > 4/n): existen observaciones influyentes, pero no se detectan patrones espurios claros en las gráficas. Recomendación: mantener el modelo con SE robustos y, como prueba de sensibilidad, comparar con un ajuste robusto (p. ej., rlm) o excluir el top-10 de Cook’s para verificar estabilidad.
Conclusión: las gráficas sugieren un comportamiento razonable; formalmente BP/Shapiro fallan. Para no cambiar la especificación aún, reportamos coeficientes con SE robustos y dejamos como mejora futura un modelo logarítmico y/o no linealidades (área², interacciones).
Predicción para Vivienda 1
Usando el modelo actual (sin cambios), se predice el precio para Vivienda 1 con área=200 m², parqueaderos=1, baños=2, habitaciones=4 y dos escenarios de estrato (4 y 5). Se compara con el crédito preaprobado = 350 M.
| caso | area_construida | estrato | habitaciones | parqueaderos | baños | pred | lwr_ci | upr_ci | fit | lwr_pi | upr_pi | credito_m | gap_m | decision |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Vivienda 1 (estrato 4) | 200 | 4 | 4 | 1 | 2 | 302.7 | 275.3 | 330.0 | 302.7 | -83.3 | 688.6 | 350 | -47.3 | Cubre crédito |
| Vivienda 1 (estrato 5) | 200 | 5 | 4 | 1 | 2 | 391.1 | 356.9 | 425.2 | 391.1 | 4.5 | 777.6 | 350 | 41.1 | Supera crédito |
Estrato 4: pred ≈ 302.7 M → el crédito de 350 M cubre (margen ≈ +47.3 M).
Estrato 5: pred ≈ 391.1 M → excede el crédito (brecha ≈ −41.1 M).
El intervalo de predicción (PI95%) será más ancho que el IC95% porque captura la variabilidad de una vivienda individual; úsalo para juzgar el riesgo de que un inmueble concreto se salga del rango esperado. Si tu decisión es binaria (“¿alcanza el crédito?”), el punto de corte práctico es la predicción puntual, pero puedes ser conservador y mirar el límite inferior del PI para estrato 5: si aun así está por encima de 350 M, la compra con ese crédito es poco probable sin ajuste.
Recomendaciones para Vivienda 1
| id_row | status_credito | pred_m | gap_m | area_construida | estrato | habitaciones | baños | parqueaderos | barrio |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Dentro del crédito (≤350M) | 276.4 | 73.6 | 170 | 4 | 4 | 2 | 1 | el caney |
| 2 | Dentro del crédito (≤350M) | 216.9 | 133.1 | 203 | 3 | 4 | 2 | 1 | san antonio |
| 3 | Dentro del crédito (≤350M) | 343.8 | 6.2 | 247 | 4 | 4 | 2 | 1 | colseguros |
| 4 | Dentro del crédito (≤350M) | 232.6 | 117.4 | 120 | 4 | 4 | 2 | 1 | alamos |
| 5 | Dentro del crédito (≤350M) | 170.4 | 179.6 | 150 | 3 | 4 | 2 | 1 | alamos |
Caso 2: Vivienda Sur
Apartamento en Zona Sur. Mostramos primeras tres lineas y tablas de validación.
| zona | piso | estrato | precio | area_construida | parqueaderos | baños | habitaciones | tipo | barrio | longitud | latitud |
|---|---|---|---|---|---|---|---|---|---|---|---|
| Zona Sur | 01 | 5 | 240 | 87 | 1 | 3 | 3 | Apartamento | acopi | -76.51700 | 3.36971 |
| Zona Sur | 01 | 4 | 220 | 52 | 2 | 2 | 3 | Apartamento | acopi | -76.51974 | 3.42627 |
| Zona Sur | 01 | 5 | 310 | 137 | 2 | 3 | 4 | Apartamento | acopi | -76.53105 | 3.38296 |
| tipo | zona | n |
|---|---|---|
| Apartamento | Zona Sur | 2350 |
| variable | dtype | n_unique | n_missing |
|---|---|---|---|
| zona | character | 1 | 0 |
| piso | character | 13 | 577 |
| estrato | numeric | 4 | 0 |
| precio | numeric | 325 | 0 |
| area_construida | numeric | 255 | 0 |
| parqueaderos | numeric | 6 | 387 |
| baños | numeric | 9 | 0 |
| habitaciones | numeric | 7 | 0 |
| tipo | character | 1 | 0 |
| barrio | character | 143 | 0 |
| longitud | numeric | 988 | 0 |
| latitud | numeric | 1178 | 0 |
División de datos
Solo piso y parqueadero tienen nulos, como ambos son categóricos vamos a imputarlos con la moda. Pero antes dividamos el data set en datos de entrenamiento y de prueba, parea evitar data leakeage.Posteriormente lo dividiremos en datos numérico: area construida, precio y estrato, todos los demás quedaran en categóricos y serán reclasificado, solo posteriormente imputaremos los nulos en los datos de entrenamiento con la moda
dividimos base1 en entrenamiento (80%) y prueba (20%) con semilla fija para reproducibilidad. Tal como se hizo en el caso 1
| conjunto | n |
|---|---|
| train2 | 1880 |
| test2 | 470 |
Separamos numéricos (area_construida, precio, estrato) y dejamos el resto como categóricos.
| tipo | n_columnas |
|---|---|
| numéricas (train2) | 3 |
| categóricas (train2) | 7 |
| numéricas (test2) | 3 |
| categóricas (test2) | 7 |
| variable | n_na_train | n_na_test |
|---|---|---|
| piso | 466 | 111 |
| parqueaderos | 316 | 71 |
Limpieza de datos
Imputamos solo en entrenamiento los NAs de piso y parqueaderos con la moda de train_df; guardamos las modas en imputer_modes para aplicar luego al test (sin fuga de información).
| variable | na_antes | moda_train | na_despues |
|---|---|---|---|
| piso | 466 | 05 | 0 |
| parqueaderos | 316 | 1 | 0 |
Se aplica al test_df las modas ya aprendidas en train_df (guardadas en imputer_modes) sin recalcular nada.
Detectamos outliers en train_df por z-score (k = 3 por defecto) en columnas numéricas area_construida, precio, estrato. Reporto media, sd, límites y conteos.
| variable | mean | sd | z_k | lower_limit | upper_limit | n | n_out_low | n_out_high | n_outliers | pct_outliers |
|---|---|---|---|---|---|---|---|---|---|---|
| area_construida | 98.787 | 55.893 | 3 | -68.893 | 266.466 | 1880 | 0 | 33 | 33 | 1.76 |
| precio | 306.168 | 202.212 | 3 | -300.467 | 912.802 | 1880 | 0 | 35 | 35 | 1.86 |
| estrato | 4.679 | 0.849 | 3 | 2.131 | 7.227 | 1880 | 0 | 0 | 0 | 0.00 |
Winsorizamos solo en datos de entrenamiento: capeo de valores por debajo/encima a los límites (inferior/superior) calculados arriba;se reporta cuántos quedaron exactamente en cada límite.
| variable | lower_limit | upper_limit | n_out_low_before | n_out_high_before | n_at_lower_after | n_at_upper_after | n_out_high_after |
|---|---|---|---|---|---|---|---|
| area_construida | -68.893 | 266.466 | 0 | 33 | 0 | 33 | 0 |
| precio | -300.467 | 912.802 | 0 | 35 | 0 | 35 | 0 |
| estrato | 2.131 | 7.227 | 0 | 0 | 0 | 0 | 0 |
capeo en TEST usando los mismos límites calculados en TRAIN (z_limits).
Correlaciones
Matriz de correlaciones (Spearman) en TRAIN usando nuestro set numérico: precio, area_construida, estrato.
“correlación” entre categóricas y precio en TRAIN usando Correlation Ratio (η) + p(Kruskal–Wallis). Solo se reportan variables con ≥2 niveles y datos suficientes.
En este data set hay mejor correlaciones que el previo, pero también se aprecia unn poco más de colinealidad. Las columnas numéricas tiene una correlación aceptable. En las categóricas tenemos resultados mixtos. Barrio es quien presentó mayuior correlación, pero como tiene tanto valores únicos (143) no nos sirve como predictora. Piso puede ser descartada porque es muy baja su correlación, habitaciones también tiene poca correlación, pero ya que hay tan pocas variables, dejémosla. Lo hago en TRAIN y TEST para evitar incoherencias más delante. Si bien las correlaciones mejoraron, el resultado en las columnas usadas fue el mismo
| columna | motivo |
|---|---|
| barrio | Alta cardinalidad (niveles en TRAIN2 ≈ 128). |
| piso | Baja correlación (η baja). |
Modelo 2
Ajustamos un modelo lineal múltiple en los datos de entrenamiento: precio: area_construida + estrato + habitaciones + parqueaderos + baños.
| term | estimate | std.error | statistic | p.value | conf.low | conf.high | signif |
|---|---|---|---|---|---|---|---|
| (Intercept) | -246.0471 | 11.9222 | -20.6378 | 0 | -269.4292 | -222.6650 | *** |
| area_construida | 1.9502 | 0.0634 | 30.7820 | 0 | 1.8260 | 2.0745 | *** |
| estrato | 54.7042 | 2.4478 | 22.3480 | 0 | 49.9034 | 59.5050 | *** |
| habitaciones | -17.7524 | 3.1095 | -5.7091 | 0 | -23.8508 | -11.6540 | *** |
| parqueaderos | 55.3332 | 3.5199 | 15.7200 | 0 | 48.4298 | 62.2366 | *** |
| baños | 31.6276 | 2.7952 | 11.3150 | 0 | 26.1456 | 37.1096 | *** |
Reporte de métricas globales del modelo (R², R² ajustado, RMSE y MAE en TRAIN) para juzgar el ajuste.
| r_squared | r_squared_adj | sigma_residual | rmse_train | mae_train | n_obs |
|---|---|---|---|---|---|
| 0.8486 | 0.8482 | 69.1926 | 69.0821 | 48.1017 | NA |
Coeficientes e interpretación (con IC95% y significancia)
Área construida: +1.95 M por cada 1 m² (IC95% [1.826; 2.075], p<0.001). Traducción útil: +10 m² ≈ +19.5 M (IC95% [18.26; 20.75]). Señal fuerte y consistente: a mayor área, mayor precio.
Estrato: +54.70 M por cada nivel adicional (IC95% [49.90; 59.51], p<0.001). Captura diferencias de entorno/calidad de servicios; efecto grande y coherente.
Parqueaderos: +55.33 M por cada cupo (IC95% [48.43; 62.24], p<0.001). La disponibilidad de parqueo se capitaliza de forma marcada en apartamentos.
Baños: +31.63 M por baño adicional (IC95% [26.15; 37.11], p<0.001). Más confort/segmento ⇒ mayor precio.
Habitaciones: −17.75 M por habitación adicional (IC95% [−23.85; −11.65], p<0.001). Interpretación: a igual área, más cuartos implican espacios individuales más pequeños (menos “lujo por m²”), lo que empuja el precio a la baja; señal negativa significativa en este segmento.
Intercepto = −246.05 M (no interpretable en el rango real de covariables).
Ajuste global
R² = 0.8486, R² ajustado = 0.8482 → el modelo explica ~85% de la variabilidad del precio en apartamentos del Sur.
RMSE ≈ 69.08 M; MAE ≈ 48.10 M; σ(residual) ≈ 69.19 M. Lectura práctica: el error típico ronda 48–69 millones. Júzgalo frente a la mediana/rango de precios del segmento; para inmuebles de, p. ej., 400–700 M, la precisión es buena para priorización de ofertas y decisiones operativas.
Los signos tienen sentido: área, estrato, baños y parqueaderos salen positivos y de magnitud alta, coherentes con la formación de precios en apartamentos del Sur. La señal “rara” es habitaciones, que ahora es negativa y significativa (≈ −17.8 M por cuarto; IC95% [−23.9; −11.7]): a igual área, más cuartos fragmentan el espacio y reducen el “lujo por m²”, presionando el precio a la baja. Dado que los VIF son bajos, no parece multicolinealidad; más bien, el efecto captura un trade-off real de diseño/segmentación. Aun así, conviene chequear robustez con log(precio), términos no lineales (p. ej., área²) y/o excluir los top Cook’s como sensibilidad.
Diagnosis
Diagnósticos del modelo (residuales estandarizados, leverage, Cook’s).
| row_id | fitted | resid | std_resid | leverage | cooksd |
|---|---|---|---|---|---|
| 1 | 163.116 | -21.116 | -0.306 | 0.002 | 0 |
| 2 | 92.186 | 20.814 | 0.301 | 0.004 | 0 |
| 3 | 203.870 | 32.130 | 0.465 | 0.001 | 0 |
| 4 | 182.618 | 32.382 | 0.469 | 0.002 | 0 |
| 5 | 107.787 | 27.213 | 0.394 | 0.004 | 0 |
Pruebas formales por supuesto: BP (homocedasticidad), Shapiro (normalidad, con cautela), Durbin–Watson (independencia), VIF (multicolinealidad) e influencias (Cook’s).
| supuesto | metric | estado |
|---|---|---|
| Homoscedasticidad (BP) | p=0.000 | Revisar |
| Normalidad (Shapiro) | p=0.000 | Revisar |
| Independencia (DW) | DW=2.00, p=0.519 | OK |
| Multicolinealidad (VIF) | max(VIF)=3.00 | OK |
| Influencias (Cook’s) | Cook’s > 4/n: 149 casos (umbral=0.002) | Revisar |
| variable | VIF |
|---|---|
| area_construida | 3.000 |
| estrato | 1.697 |
| habitaciones | 1.392 |
| parqueaderos | 1.947 |
| baños | 2.673 |
Gráficos interactivos (plotly) para inspección visual: residuales vs ajustados (linealidad/varianza), Q-Q de residuales (normalidad) y escala-ubicación.
Puntos influyentes (Cook’s). Muestra top casos y gráfico interactivo.
| row_id | fitted | resid | std_resid | leverage | cooksd | flag |
|---|---|---|---|---|---|---|
| 534 | 1100.4760 | -187.6738 | -3.0221 | 0.1945 | 0.3675 | TRUE |
| 978 | 630.2279 | -460.2279 | -6.7673 | 0.0340 | 0.2684 | TRUE |
| 1474 | 704.7391 | -334.7391 | -4.9061 | 0.0276 | 0.1140 | TRUE |
| 1520 | 644.1031 | -345.1031 | -5.0500 | 0.0246 | 0.1070 | TRUE |
| 953 | 737.0171 | -387.0171 | -5.6404 | 0.0166 | 0.0897 | TRUE |
| 1811 | 530.8176 | -270.8176 | -3.9735 | 0.0298 | 0.0807 | TRUE |
| 467 | 575.0335 | 337.7687 | 4.9085 | 0.0109 | 0.0444 | TRUE |
| 1352 | 671.6476 | -331.6476 | -4.8169 | 0.0098 | 0.0384 | TRUE |
| 1619 | 612.0197 | -262.0197 | -3.8153 | 0.0149 | 0.0366 | TRUE |
| 260 | 712.6826 | 200.1196 | 2.9211 | 0.0197 | 0.0286 | TRUE |
Validación de supuestos
Homoscedasticidad (Breusch–Pagan): p = 0.000 → Revisar. Hay evidencia de varianza no constante. Para la inferencia, usa errores estándar robustos (HC3). Como mejora de especificación, considera log(precio) y/o términos no lineales si el “abanico” en residuales vs ajustados es notorio.
Normalidad de residuales (Shapiro–Wilk): p = 0.000 → Revisar. Con 𝑛 n grande (umbral Cook’s 4/n≈0.002 sugiere 𝑛 n≈2000), es normal que Shapiro rechace. La estimación OLS sigue siendo insesgada; reporta SE robustos y apóyate en el Q–Q para confirmar que las desviaciones son sobre todo en colas.
Independencia (Durbin–Watson): DW = 2.00, p = 0.519 → OK. Sin autocorrelación de primer orden; esperable en corte transversal.
Multicolinealidad (VIF): max(VIF) = 3.00 → OK. Detalle VIF: área_construida = 3.00; baños = 2.67; parqueaderos = 1.95; estrato = 1.70; habitaciones = 1.39. Todos bajo umbrales habituales (≤5), por lo que los coeficientes están bien identificados.
Influencias (Cook’s): 149 casos con Cook’s > 4/n (umbral = 0.002) → Revisar. Con muchos datos el umbral es muy bajo y “salta” más de lo habitual, pero hay puntos realmente influyentes. En el Top 10 destaca row_id 534 (leverage≈0.195, std_resid≈−3.02, Cook’s≈0.368). Recomendación: corrida de sensibilidad excluyendo el Top k (p. ej., 1% de Cook’s) y/o ajuste robusto (p. ej., rlm). Verifica outliers por posibles errores de captura.
Conclusión operativa
Mantén la especificación actual para el informe, reportando SE robustos (HC3).
Si se desea mejorar ajuste/estabilidad: probar log(precio), no linealidades en área y una corrida robusta o con trimming de los casos de Cook’s más altos.
A nivel explicativo, los VIF bajos confirman que los efectos (área, estrato, baños, parqueaderos positivos; habitaciones negativo) no son artefactos de colinealidad sino patrones consistentes con el segmento de apartamentos del Sur.
Predicción para Vivienda 2
Usando el modelo actual (sin cambios), predigo el precio para Vivienda 2 —apartamento en Zona Sur— con área = 300 m², parqueaderos = 3, baños = 3, habitaciones = 5 y dos escenarios de estrato (5 y 6). La comparación se hace contra el crédito preaprobado = 850 millones.
| caso | area_construida | estrato | habitaciones | parqueaderos | baños | pred | lwr_ci | upr_ci | fit | lwr_pi | upr_pi | credito_m | gap_m | decision |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Vivienda 2 (estrato 5) | 300 | 5 | 5 | 3 | 3 | 784.7 | 762.3 | 807.0 | 784.7 | 647.1 | 922.2 | 850 | -65.3 | Cubre crédito |
| Vivienda 2 (estrato 6) | 300 | 6 | 5 | 3 | 3 | 839.4 | 817.4 | 861.4 | 839.4 | 701.9 | 976.8 | 850 | -10.6 | Cubre crédito |
Estrato 5: pred ≈ 784.7 M (IC95% 762.3–807.0; PI95% 647.1–922.2). Con crédito 850 M, cubre con un margen ≈ +65.3 M.
Estrato 6: pred ≈ 839.4 M (IC95% 817.4–861.4; PI95% 701.9–976.8). Con crédito 850 M, cubre con margen ≈ +10.6 M. Ojo: el límite superior del PI (≈ 976.8 M) supera el crédito; es un escenario posible (menos probable) en el que una unidad comparable podría exceder 850 M.
Nota: El PI95% es más ancho que el IC porque representa la variabilidad de una vivienda individual. Si quieres ser conservador, para estrato 6 conviene mantener ofertas con predicciones ≤ 830–840 M o tener margen de negociación.
Recomendaciones para Vivienda 2
| id_row | status_credito | pred_m | gap_m | area_construida | estrato | habitaciones | baños | parqueaderos | barrio |
|---|---|---|---|---|---|---|---|---|---|
| 1 | Dentro del crédito (≤850M) | 84.8 | 765.2 | 50 | 3 | 1 | 1 | 1 | pasoancho |
| 2 | Dentro del crédito (≤850M) | 191.9 | 658.1 | 84 | 4 | 0 | 0 | 1 | primero de mayo |
| 3 | Dentro del crédito (≤850M) | 72.9 | 777.1 | 53 | 3 | 2 | 1 | 1 | mel√©ndez |
| 4 | Dentro del crédito (≤850M) | 74.8 | 775.2 | 54 | 3 | 2 | 1 | 1 | el dorado |
| 5 | Dentro del crédito (≤850M) | 82.6 | 767.4 | 58 | 3 | 2 | 1 | 1 | la hacienda |
Conclusiones
Caso 1 (Vivienda 1, Casa Zona Norte)
Drivers: área, estrato, baños y parqueaderos ↑ precio; habitaciones ↓ (leve, condicional al área).
Calidad del modelo: R²≈0.61; error típico MAE≈136 M, RMSE≈195 M → ajuste medio.
Diagnóstico: heterocedasticidad y no-normalidad (BP/Shapiro); DW ok; VIF bajo.
Decisión: con estrato 4 la predicción (~303 M) sí cabe en crédito (350 M); con estrato 5 (~391 M) no.
Caso 2 (Vivienda 2, Apto Zona Sur)
Drivers: área (≈1.95 M por m²), estrato (+54.7 M), parqueaderos (+55.3 M), baños (+31.6 M); habitaciones negativo (–17.8 M) condicional al área.
Calidad del modelo: R²≈0.85; MAE≈48 M, RMSE≈69 M → ajuste alto y errores sustancialmente menores.
Diagnóstico: BP/Shapiro fallan; DW ok; VIF máx≈3 (bien). Muchos puntos influyentes → validar robustez, pero el modelo es estable.
Decisión: para 300 m², 5 hab, 3 baños, 3 parqueaderos:
Estrato 5: ~784.7 M (IC95% 762–807) → cubre crédito 850 M.
Estrato 6: ~839.4 M (IC95% 817–861) → cubre crédito. Los PI95% (hasta ~922–977 M) pueden pasarse del crédito en casos individuales.
Conclusiones comunes
Coherencia: área, estrato, baños y parqueaderos son determinantes en ambos casos; habitaciones resta valor dado el mismo metraje.
Riesgo: Caso 2 es más predecible (menor error). En ambos, usar SE robustos y guiarse por PI, no solo por la media.
Recomendación práctica: priorizar inmuebles cuyo límite superior del intérvalo de predicción (PI) quede dentro del crédito o dejar margen de negociación (especialmente en Zona Sur/estrato 6).
Siguiente paso: probar log(precio) y/o transformaciones (no linealidades) para reducir heterocedasticidad y revisar sensibilidad quitando top-Cook’s.