← 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
Detectar zonas que se van a revalorizar: XGBoost + message-passing sobre un grafo de barrios

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