Plan de clustering (K-means) — antes de correr

Fecha: 2026-09-14 · Proyecto: ~/nef/estado_turismo/spab-retrieval Regla: no clusterizar sobre datos sucios. Primero el setting correcto (feature set homogéneo, periodos alineados, sin features que sesguen); luego K-means.

1. Objetivo

Segmentar destinos para la campaña (RUTA §5.2: “Segmentación de destinos”). Interpretar grupos con nombre (“plazas caras con valor en caída”, etc.), no “clúster 3”. Alimenta el buyer persona y el destino de la campaña (criterio 7).

2. Unidad de análisis

Destino (snapshot actual), no destino-periodo — aún no hay suficientes meses completos por destino para un panel. Se documenta como límite.

3. Compuertas de calidad (PRERREQUISITOS, antes de clusterizar)

Medido hoy — completitud por feature:

featurecoberturaperiodo¿apta?
precio_hospedaje (booking)10/102026-09✅ destino-level
rating (places)10/102026-09✅
reviews_conteo (places)10/102026-09✅
menciones_caro (places)10/102026-09✅
vistas_wikipedia10/102026-08✅ (1 mes de desfase)
ocupacion_hotelera (datatur)8/102026-06⚠️ falta Tulum/Bacalar
llegadas_turistas (UPM)7/102026-07⚠️ falta playa/san-miguel; es extranjeros
llegadas_vuelo (opensky)3/102026-09❌ cobertura parcial
anfitriones_multi (airbnb)1/102026-09❌ solo CDMX
cuartos_oferta (compendio)10/102024-12⚠️ estatal (sesga)
delitos_100k (sesnsp)0/10—❌ falta CSV

Puertas a cerrar ANTES

  1. Ocupación Tulum/Bacalar → proxy “Riviera Maya” (Tulum) + decisión Bacalar. Sin esto, los 2 destinos eje no entran, o entran con hueco.
  2. Ocupación canónica → DataTur (evitar el Airbnb 0.18 vs DataTur 0.52 en CDMX).
  3. Periodos alineados → usar el último valor por feature y fijar un “vintage” común documentado (p. ej. “snapshot 2026-09”), o alinear por mes. No mezclar sin declararlo.
  4. cuartos_oferta NO entra como feature de destino (es estatal → 4 destinos Q.Roo idénticos = conglomerado artificial). Se usa como capacidad, no en K-means.
  5. SESNSP (delitos) → descargar el CSV para poder incluir seguridad.
  6. Exclusión por incompletitud: un destino con ≥2 features faltantes sale (se declara, no se imputa).

4. Vectores propuestos

  • K-means v1 (hoy, sin cerrar puertas): features completas destino-level que NO sesgan: precio, rating, reviews_conteo, menciones_caro, vistas_wikipedia (5 features, 10 destinos). Corre ya; sirve de línea base.
  • K-means v2 (tras puertas 1–3,5): + ocupacion_hotelera + delitos_100k (+ quizá llegadas_turistas con la salvedad de extranjeros).

5. Método

  1. Normalización: z-score por feature (media 0, σ 1). Alternativa robusta (mediana/IQR) — se comparan.
  2. k: probar 2–6. Elegir con codo (inercia) + silueta + Davies-Bouldin; se justifica el k elegido (criterio 4).
  3. Inicialización: k-means++ , n_init=20, semilla fija (reproducible).
  4. Validación: silueta y DB; estabilidad por bootstrap (¿los grupos se repiten?).
  5. Jerárquico (Ward) en paralelo como contraste.

6. Interpretación y entrega

  • Nombrar clusters por su centro (p. ej. “caro-inflado / emergente-barato / consolidado-caro”).
  • Trazar cada cluster a las features (qué lo define) y a la campaña.
  • Salida: script scripts/clustering.py + tabla de asignación + gráfico.

7. Anti-basura (explícito)

  • No imputar en ingesta (regla del esquema); si falta, se excluye y se dice.
  • No meter features estatales como si fueran del destino.
  • No mezclar periodos sin declararlo.
  • No clusterizar con <5 features o con destinos incompletos.
  • Reportar n, cobertura y qué destino quedó fuera y por qué.

8. Orden de ejecución sugerido

  1. Cerrar puertas 2 y 3 (canónica + periodos) — barato.
  2. Decidir proxy Tulum y Bacalar (puerta 1).
  3. Descargar SESNSP (puerta 5).
  4. Correr K-means v1 (línea base) mientras tanto, documentando límites.
  5. Correr v2 y comparar.