BuscaExtraescolares

Metodología del observatorio

Definición formal de cada métrica publicada en el observatorio, con fórmulas, umbrales y limitaciones. Sin cifras: solo cómo se calculan.

Definición de las métricas del Observatorio

Este documento es la definición formal de cada métrica publicada en el Observatorio de la oferta de extraescolares en España. No contiene cifras: solo definiciones, fórmulas, umbrales y tratamiento de casos límite, para que cualquiera pueda reproducir o auditar los cálculos.

Todas las métricas se calculan con el mismo código para la página viva y para las ediciones mensuales congeladas: lib/observatorio/metrics.ts (computeMetrics), un módulo puro y determinista. Los umbrales viven en lib/observatorio/config.ts (OBSERVATORIO_CONFIG, congelado). La versión del cálculo se publica en cada edición como calc_version (CALC_VERSION): sube si cambia cualquier definición de esta página.

Los agregados crudos los produce la vista materializada observatorio_agregados (migración 0059), que se refresca a diario a las 04:00 UTC con pg_cron. La población procede del INE (migración 0060). La fecha de corte publicada es el refreshed_at de esa vista, nunca la hora de renderizado.

Criterio de inclusión de fichas

Una academia entra en el cómputo si y solo si:

  • academies.status = 'published'. Quedan fuera los borradores, las fichas archivadas (archived) y las fichas de demostración.
  • Su ciudad (cities) tiene provincia reconocida: cities.province casa con observatorio_ine_provincias.nombre_cities. La migración aborta si alguna provincia de cities queda huérfana, así que no hay academias publicadas fuera del nivel provincial.
  • Para el nivel municipal hace falta además que su ciudad esté mapeada a un municipio INE (observatorio_ine_municipios). Las academias en ciudades no mapeadas cuentan en su provincia pero no en el nivel municipal; el porcentaje de fichas en municipios mapeados se publica como limitación.

Reglas de conteo:

  • La unidad es la academia, no la actividad ni la sede.
  • Las categorías se agregan a su categoría raíz (coalesce(parent.slug, cat.slug)). Una academia con varias materias de la misma raíz cuenta una vez en esa raíz (count(distinct academy_id)).
  • Una academia con categorías de varias raíces cuenta una vez en cada raíz; por tanto la suma por categorías es mayor o igual que el total y no debe interpretarse como una partición.
  • En el total (categoria_slug is null) cada academia cuenta exactamente una vez. Una academia sin ninguna categoría cuenta en el total y en ninguna categoría.
  • La vista materializada no expone ninguna columna de la academia (ni nombre, ni plan, ni contacto, ni estado de reclamación): solo conteos.

Pseudocódigo del agregado (equivalente al SQL de la migración 0059):

-- total por provincia
select provincia_codigo, count(distinct academy_id)
from academias_publicadas group by provincia_codigo;

-- por provincia y categoría raíz
select provincia_codigo, coalesce(par.slug, k.slug) as categoria_slug,
       count(distinct academy_id)
from academias_publicadas join academy_categories using (academy_id)
     join categories k on k.id = category_id
     left join categories par on par.id = k.parent_id
group by 1, 2;

Las mismas dos consultas, con ine_code en lugar de provincia_codigo, dan el nivel municipal (solo municipios mapeados).

1. Totales

Definición. Número de academias publicadas por provincia, por comunidad autónoma y en el conjunto de España.

Fórmula. Provincia = fila de la vista con nivel='provincia' y categoria_slug is null. CCAA = suma de sus provincias. Nacional = suma de las 52 provincias.

Umbral. Ninguno: el total se publica siempre, incluso 0.

Nulos. Una provincia sin filas en la vista se publica con 0 academias, nunca como «sin dato».

2. Oferta por categoría raíz (nacional)

Definición. Academias publicadas que tienen al menos una materia de cada categoría raíz, y su peso sobre el total nacional.

Fórmula. academias(categoría) = Σ provincias academias(provincia, categoría); pct_nacional = academias(categoría) / total_nacional × 100.

Umbral. Ninguno.

Nulos. pct_nacional = null si el total nacional es 0 (nunca división por cero). Las categorías con 0 academias se publican con 0, no se ocultan.

3. Categoría × provincia

Definición. Academias de cada categoría raíz en cada provincia.

Fórmula. Fila de la vista nivel='provincia', categoria_slug = slug. El mapa por_categoria se rellena siempre con todas las categorías raíz (con ceros) para que la serialización de una edición sea reproducible.

Umbral. Los cruces se publican para todas las provincias, pero solo las provincias con cobertura (métrica 6) entran en desiertos, diversidad y categorías infrarrepresentadas.

Nulos. Combinación ausente en la vista = 0.

4. Categoría × municipio

Definición. Academias de cada categoría raíz en un municipio.

Fórmula. Igual que la métrica 3 sobre las filas de nivel='municipio'.

Umbral. Solo se publica el desglose por categoría de los municipios con academias >= MIN_FICHAS_MUNICIPIO_CRUCE (OBSERVATORIO_CONFIG.MIN_FICHAS_MUNICIPIO_CRUCE). Por debajo del umbral, un cruce categoría × municipio sería ruido.

Nulos. Por debajo del umbral, por_categoria = null (ausencia declarada, no ceros). El total del municipio sí se publica siempre.

5. Densidad por cada 1.000 niños y niñas de 3 a 16 años

Definición. Academias registradas por cada 1.000 habitantes de la franja de edad objetivo (EDAD_MIN = 3, EDAD_MAX = 16), según población INE.

Fórmula. densidad = academias / pob_3_16 × 1.000.

Umbral. Solo se calcula para provincias con cobertura (métrica 6). Una provincia sin cobertura no se publica con densidad 0: se publica como «sin cobertura suficiente» junto a su número de fichas.

Nulos. densidad = null si pob_3_16 es 0, falta el dato INE o la provincia no tiene cobertura. Nunca Infinity ni NaN.

Implementación (lib/observatorio/metrics.ts):

export function densidad(academias: number, pob: number | null): number | null {
  if (pob === null || !(pob > 0)) return null;
  return (academias / pob) * 1000;
}

6. Cobertura y ranking de densidad por provincia

Definición. Una provincia tiene cobertura suficiente si el directorio registra en ella al menos MIN_FICHAS_PROVINCIA_COBERTURA academias publicadas (OBSERVATORIO_CONFIG.MIN_FICHAS_PROVINCIA_COBERTURA). El ranking de densidad ordena de mayor a menor solo las provincias con cobertura.

Fórmula. Ranking denso con empates al mismo puesto y salto posterior (1-2-2-4). Las provincias sin densidad quedan fuera del ranking con ranking_densidad = null.

Umbral. MIN_FICHAS_PROVINCIA_COBERTURA.

Nulos. Las provincias sin cobertura se listan aparte, con su número de fichas (incluido 0). «Sin cobertura suficiente» significa que nuestro directorio no tiene suficientes fichas ahí, no que no haya oferta.

7. Densidad y ranking por comunidad autónoma

Definición. Lo mismo que las métricas 5 y 6, agregando las provincias de cada comunidad.

Fórmula. academias(ccaa) = Σ provincias; pob_3_16(ccaa) = Σ pob_3_16; densidad y ranking idénticos a los provinciales.

Umbral. La cobertura de una comunidad se evalúa sobre su suma: academias(ccaa) >= MIN_FICHAS_PROVINCIA_COBERTURA.

Nulos. Igual que en las métricas 5 y 6.

8. Cobertura municipal

Definición. Porcentaje de municipios de la provincia en los que el directorio registra al menos una academia.

Fórmula. municipios_con_oferta / municipios_total × 100, donde municipios_total es el número real de municipios INE de la provincia y municipios_con_oferta cuenta solo municipios mapeados con al menos una ficha.

Umbral. Solo para provincias con cobertura.

Nulos. null si la provincia no tiene cobertura o municipios_total es 0. Al depender de municipios mapeados, esta métrica es un suelo: nunca sobreestima la cobertura.

9. Diversidad de categorías

Definición. Número de categorías raíz distintas con al menos una academia, excluyendo las categorías cajón de sastre (CATEGORIAS_EXCLUIDAS_DIVERSIDAD, hoy otras y eventos).

Fórmula. diversidad = número de categorías con academias(ámbito, categoría) > 0.

Umbral. Por provincia se publica si la provincia tiene alguna academia; por municipio, solo para municipios grandes (pob_total > UMBRAL_MUNICIPIO_GRANDE_HAB, campo es_grande).

Nulos. null si la provincia no tiene academias o el municipio no es grande.

10. Cobertura geográfica por categoría

Definición. Número de provincias con cobertura en las que una categoría tiene al menos una academia.

Fórmula. provincias_presentes(categoría) = número de provincias p con cobertura(p) y academias(p, categoría) > 0.

Umbral. El de cobertura provincial, para no contar presencias en provincias con muestra insuficiente.

Nulos. Ninguno: el mínimo es 0.

11. Concentración

Definición. Porcentaje del total nacional que suman las N provincias con más fichas, para cada N de TOP_CONCENTRACION (hoy 5 y 10).

Fórmula. pct(N) = suma de las N provincias con más academias / total_nacional × 100.

Umbral. Ninguno.

Nulos. pct = null si el total nacional es 0.

12. Desiertos de oferta

Definición. Pares categoría × provincia en los que el directorio registra como mucho DESIERTO_MAX_FICHAS academias.

Fórmula. Hay desierto en (p, c) si la provincia p tiene cobertura, la categoría c no está excluida y academias(p, c) <= DESIERTO_MAX_FICHAS.

Umbral. DESIERTO_MAX_FICHAS y cobertura provincial; las categorías excluidas de diversidad tampoco generan desiertos.

Nulos. Las provincias sin cobertura no generan desiertos (lista vacía), para no confundir «poca oferta registrada» con «poca cobertura del directorio».

13. Brecha urbano-rural

Definición. Densidad en municipios urbanos frente a densidad en el resto. Urbano = municipio con más de UMBRAL_URBANO_HAB habitantes (campo es_urbano).

Fórmula. densidad_urbana = academias en municipios mapeados urbanos / pob_3_16_urbano × 1.000; igual para la rural; ratio = densidad_urbana / densidad_rural. Se calcula a nivel nacional y por provincia con cobertura.

Umbral. UMBRAL_URBANO_HAB; por provincia, además, cobertura provincial.

Nulos. null si falta población o si la densidad rural es 0 (el ratio no se publica como Infinity). Sesgo declarado: el numerador solo incluye academias de municipios mapeados, mientras el denominador es la población INE completa, así que ambas densidades son suelos.

14. Categorías infrarrepresentadas

Definición. En cada provincia con cobertura, las categorías cuyo peso local está muy por debajo del peso nacional de esa misma categoría.

Fórmula. La categoría c está infrarrepresentada en la provincia p si academias(p, c) / academias(p) < INFRARREPRESENTACION_FACTOR × (academias_nacional(c) / total_nacional), con INFRARREPRESENTACION_FACTOR = 0,5 (la mitad del peso nacional).

Umbral. Cobertura provincial; categorías excluidas fuera.

Nulos. Lista vacía si la provincia no tiene cobertura o no tiene academias.

15. Evolución mensual e interanual

Definición. Variación del total nacional y del total de cada provincia entre la última edición congelada y la anterior (mensual), y frente a la edición de hace doce meses (interanual).

Fórmula. var_abs = actual - anterior; var_pct = (actual - anterior) / anterior × 100 (lib/observatorio/evolution.ts).

Umbral. Se necesitan al menos dos ediciones; con menos, la sección no se publica.

Nulos. var_pct = null si el valor anterior es 0 (nunca Infinity); el interanual es null si no existe la edición de hace doce meses. Una provincia ausente en la edición anterior se trata como 0 en ella.

16. Categorías que más crecen

Definición. Categorías raíz ordenadas por crecimiento absoluto entre la última edición y la anterior.

Fórmula. Igual que la métrica 15, aplicada a academias(categoría), ordenando por var_abs descendente y, en caso de empate, por slug.

Umbral. El mismo de la métrica 15 (dos ediciones o más).

Nulos. var_pct = null si la categoría no tenía academias en la edición anterior.

Limitaciones

  1. La muestra es nuestro directorio, no un censo. Medimos la oferta registrada en BuscaExtraescolares, no el conjunto del sector ni la demanda de las familias.
  2. La cobertura no es homogénea por provincia. Por eso publicamos un umbral explícito y separamos las provincias «sin cobertura suficiente» en lugar de asignarles densidad 0.
  3. Las cifras crecen a medida que se incorporan centros. Una subida entre ediciones puede reflejar más altas en el directorio, no necesariamente más oferta real.
  4. Municipios no mapeados. Las academias de ciudades sin municipio INE asignado cuentan en su provincia pero no en el nivel municipal; el porcentaje de fichas en municipios mapeados se publica en cada edición.
  5. Población INE de referencia fija. La densidad usa el padrón a la fecha de referencia declarada (ine_fecha_ref), que se actualiza una vez al año; entre actualizaciones, el denominador no cambia.
  6. Una academia puede aparecer en varias categorías. La suma por categorías no es una partición del total.

Reproducibilidad

Cada edición mensual guarda los agregados crudos, la población usada y las métricas calculadas, junto con calc_version y ine_fecha_ref. Recalcular computeMetrics sobre los agregados y la población guardados debe devolver exactamente las métricas guardadas; el smoke scripts/smoke-observatorio.ts lo comprueba. Las ediciones son inmutables: una errata se corrige con una fe de erratas en la edición siguiente, nunca reescribiendo la anterior.

Umbrales vigentes

Valores actuales de OBSERVATORIO_CONFIG, leídos directamente de la configuración del cálculo (no se copian a mano, así que no pueden quedar desfasados).

Umbrales y constantes del cálculo
ConstanteValor
MIN_FICHAS_PROVINCIA_COBERTURA20
MIN_FICHAS_MUNICIPIO_CRUCE15
UMBRAL_URBANO_HAB20.000
UMBRAL_MUNICIPIO_GRANDE_HAB50.000
DESIERTO_MAX_FICHAS2
CATEGORIAS_EXCLUIDAS_DIVERSIDADotras, eventos
TOP_CONCENTRACION5, 10
INFRARREPRESENTACION_FACTOR0,5
EDAD_MIN3
EDAD_MAX16

Fuentes y licencias

Los datos del observatorio se publican bajo licencia CC BY 4.0, citando «BuscaExtraescolares — Observatorio de la oferta de extraescolares en España» con enlace a la edición utilizada.