← Todos los artículos
· 2 min de lectura

Detectar zonas que se van a revalorizar: XGBoost + message-passing sobre un grafo de barrios

XGBoost de 3 clases + propagación tipo GNN entre barrios vecinos para capturar el "efecto contagio" de la gentrificación. Datos sintéticos calibrados con el INE. Con código y métricas reales.

#Machine Learning#XGBoost#GNN#Message passing#Inmobiliario
Captura real de Deteccion de Zonas de Revalorizacion en funcionamiento ▶ Probar la demo
Captura real de Deteccion de Zonas de Revalorizacion, la herramienta de la que habla este artículo.

La gentrificación es contagiosa. Cuando un barrio se pone de moda, el de al lado sube justo después: los que no pueden pagar el primero se mudan al vecino, y el efecto se propaga por el mapa como una mancha de aceite. Un modelo que puntúe cada barrio de forma aislada nunca capturará esto. La solución tiene dos piezas: un clasificador fuerte y una propagación sobre el grafo de vecindad.

Pieza 1: XGBoost de 3 clases

El clasificador base es un XGBoost (600 árboles, max_depth=6, learning_rate=0.04) que predice la probabilidad de que un barrio tenga revalorización Baja / Media / Alta a partir de 18 features socioeconómicas: precio/m², tendencia a 1 y 3 años, inversión en infraestructura, accesibilidad de transporte, licencias de obra nueva y de rehabilitación, renta media, densidad, vacancia comercial, edad de los edificios, etc.

En lugar de quedarme con la clase más probable, convierto las tres probabilidades en un score continuo 0-100, que se propaga mucho mejor que una etiqueta discreta:

proba = model.predict_proba(X)      # [P(baja), P(media), P(alta)]
score = (proba[:, 2] * 1.0 + proba[:, 1] * 0.5) * 100   # 0-100

Pieza 2: message-passing sobre el grafo de barrios

Aquí es donde entra el "efecto contagio". Construyo un grafo donde cada barrio se conecta con sus vecinos geográficos y aplico 2 rondas de message-passing: cada barrio mezcla su propio score con la media de sus vecinos. Es el mismo principio que una Graph Neural Network, con una diferencia que conviene declarar con honestidad: los pesos son fijos, no aprendidos. Es una difusión/suavizado sobre el grafo, no una GNN entrenada con backpropagation:

def message_passing(score, neighbors):
    # Ronda 1: 65% score propio + 35% media de vecinos
    s1 = {i: 0.65 * score[i] + 0.35 * mean(score[j] for j in neighbors[i])
          for i in score}
    # Ronda 2: 72% + 28% (converge, suaviza sin aplanar)
    s2 = {i: 0.72 * s1[i] + 0.28 * mean(s1[j] for j in neighbors[i])
          for i in s1}
    return s2

El resultado: un barrio con score medio pero rodeado de barrios al alza sube; uno alto pero aislado se modera. Justo la dinámica espacial que un modelo tabular puro no ve.

Datos: sintéticos, pero calibrados (y lo digo)

Punto de honestidad importante: el dataset son 4.000 barrios sintéticos, no un registro real de transacciones. Ahora bien, no son números al azar: están calibrados con el Índice de Precios de Vivienda del INE (2015-2024) para que las distribuciones y correlaciones se parezcan a las de España. Sirve para demostrar la arquitectura y el razonamiento; no para decidir dónde comprar tu casa.

Resultados honestos

MétricaValor
F1-score (macro)0.61
MCC0.41
CV F1 (5-fold)0.59 ± 0.02

Con 3 clases equilibradas, el azar da un F1 de 0.33; el modelo llega a 0.61, un 28% por encima del azar. No es magia —predecir revalorización es genuinamente difícil— pero la varianza baja en validación cruzada (±0.02) dice que generaliza y no está sobreajustado. Prefiero un 0.61 honesto y estable que un 0.9 sospechoso.

Qué mejoraría

Lo siguiente sería sustituir el message-passing de pesos fijos por una GNN de verdad (GraphSAGE o GAT) que aprenda cuánto pesa cada vecino según sus features, y alimentarla con datos reales de portales inmobiliarios en lugar de sintéticos.

Pruébalo tú mismo

Es un proyecto personal y open source: no vendo nada, solo comparto cómo está construido. Puedes probar la demo en vivo y trastear con ella. El código está en GitHub. Si te resulta útil o tienes una idea para mejorarlo, encantado de leerla.

Sobre este proyecto

Deteccion de Zonas de Revalorizacion

XGBoost (3 clases: Baja/Media/Alta revalorización) + GNN con 2 rounds de message-passing espacial. F1-macro=0.61 · MCC=0.41 clasificando zonas con datos sintéticos calibrados con e...

Newsletter

¿Te aviso de nuevos proyectos y artículos?

Sin spam. Solo un email cuando publico algo nuevo de IA. Baja en un clic.

Sigue leyendo