Análisis de cohorte
Análisis de cohorte
El análisis de cohortes agrupa los objetos (usualmente usuarios) por un solo evento de inicio y compara cómo y cuánto tiempo permanecen activos y valiosos. Este enfoque separa el efecto del tiempo en el sistema (estaciones, promociones) del efecto de la edad de la cohorte (días desde el inicio).
1) Definiciones básicas
Cohorte (cohort): muchos jugadores unidos por un evento de «nacimiento» - registro, primer depósito, primer juego, primera compra.
El eje del calendario (calendar time): fechas reales (2025-10-01,...).
El eje de edad de la cohorte (cohort age): días/semanas desde el «nacimiento» (D0, D1,...).
Métricas de retención: D1/D7/D30 (Exacto y Rolling), WAU/MAU, Stickiness (DAU/MAU).
Monetización: ARPU/ARPPU, LTV acumulativo (en D7/D30/D90).
Unidad de contabilidad: usuario (user/master_id) - fijar en el pasaporte.
2) Clases de cohortes y cuándo elegirlas
Acquisition-cohorte: por fecha de inscripción/primera visita - evaluación de los canales de atracción y onboarding.
Activation/Monetization-cohortes: en el primer depósito/compra - evaluación de la monetización y la promoción.
Cohorte de características: por el primer uso de la categoría de fichas/juegos - el efecto de lanzamientos.
Behavior-cohorte: por RFM/patrón de inicio (por ejemplo, «móvil nocturno»).
3) Ejes y mallas: cómo ver la matriz
Matriz de cohortes: las filas son cohortes (calendario), las columnas son edad (D0... D90).
Estacionalidad: compara las diagonales (el mismo día calendario) para separar los efectos estacionales.
Normalización: métricas relativas (CR, share) + acumulativas (LTV), muestra ambas.
4) Pasaporte cohortes y métricas (template)
5) Pseudo-SQL: Matriz de retención (Aprox. Dn)
sql
WITH regs AS (
SELECT user_id, DATE_TRUNC('day', MIN(ts)) AS cohort_day
FROM event_register
GROUP BY 1
),
act AS (
SELECT user_id, DATE_TRUNC('day', ts) AS act_day
FROM event_activity
),
ages AS (
SELECT r. user_id, r. cohort_day, a. act_day,
(a. act_day - r. cohort_day) AS age_days
FROM regs r
JOIN act a ON a. user_id = r. user_id
),
exact AS (
SELECT cohort_day,
age_days,
COUNT(DISTINCT user_id) AS users_active
FROM ages
GROUP BY 1,2
),
coh_size AS (
SELECT cohort_day, COUNT(DISTINCT user_id) AS cohort_size
FROM regs GROUP BY 1
)
SELECT e. cohort_day,
e. age_days,
e. users_active::decimal / NULLIF(c. cohort_size,0) AS exact_retention
FROM exact e
JOIN coh_size c USING (cohort_day)
WHERE age_days IN (1,7,30,90)
ORDER BY cohort_day, age_days;
Rolling Dn (actividad en 1... n día)
sql
WITH days AS (... as above...),
roll AS (
SELECT cohort_day,
CASE WHEN age_days BETWEEN 1 AND 7 THEN 7
WHEN age_days BETWEEN 1 AND 30 THEN 30 END AS bucket,
COUNT(DISTINCT user_id) AS any_active
FROM days
WHERE age_days BETWEEN 1 AND 30
GROUP BY 1,2
)
SELECT r. cohort_day, r. bucket AS Dn,
r. any_active::decimal / s. cohort_size AS rolling_retention
FROM roll r
JOIN (SELECT cohort_day, COUNT(DISTINCT user_id) cohort_size FROM regs GROUP BY 1) s USING (cohort_day)
ORDER BY cohort_day, Dn;
6) Cohorte LTV y monetización
LTV acumulativo (Dn): suma de ingresos por usuario cohorte a Dn.
ARPU/ARPPU: ingresos por usuario/por persona que paga por Dn.
% de los que pagan: participación con pago ≥1 a Dn.
sql
WITH reg AS (
SELECT user_id, DATE_TRUNC('day', MIN(ts)) AS cohort_day
FROM event_register GROUP BY 1
),
pay AS (
SELECT user_id, amount, DATE_TRUNC('day', ts) AS pay_day
FROM fact_payments
),
ltv AS (
SELECT r. cohort_day,
(pay_day - r. cohort_day) AS age_days,
SUM(amount) AS rev
FROM reg r JOIN pay p USING (user_id)
WHERE pay_day >= r. cohort_day
GROUP BY 1,2
),
cum AS (
SELECT cohort_day, age_days,
SUM(rev) OVER (PARTITION BY cohort_day ORDER BY age_days ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS rev_cum
FROM ltv
)
SELECT c. cohort_day, c. age_days,
c. rev_cum::decimal / NULLIF(sz. cohort_size,0) AS ltv_per_user
FROM cum c
JOIN (SELECT cohort_day, COUNT(DISTINCT user_id) cohort_size FROM reg GROUP BY 1) sz USING (cohort_day)
WHERE age_days IN (7,30,90)
ORDER BY cohort_day, age_days;
7) Survival/hazard para la retención
Kaplan-Meier: curva de supervivencia no modular (S (t)) es la proporción de no «descongelados».
Modelos Hazard (Soh/Logit-on-day): el impacto de los signos (canal, país, plataforma, bonos, contenido) en el riesgo de salida.
Práctica: construimos KM por segmentos, luego explicamos la diferencia con el modelo hazard.
8) Estacionalidad, TZ y calendario
TZ: almacenar eventos en UTC, analizar en TZ local del mercado; sean consistentes.
El calendario: prazdniki/zarplatnye/matchi/relizy - como las banderas; comparar cohortes de semanas similares.
Ventana deslizante: para las cohortes semanales/mensuales, multiplicidad por días festivos y períodos de presentación de informes.
9) Segmentación y atribución
Segmentos: canal de atracción, plataforma/OS, geo, primer contenido, precio/límites, método de pago.
Atribución de cohorte: «quién trajo» al usuario - fijar el algoritmo (último no directo, data-driven).
Pesaje LTV: compare no solo CR, sino también LTV (D30/D90) a través de canales/segmentos.
10) Visualización
Tarjeta térmica de matriz de cohorte (CR/LTV).
Las líneas de tendencia D1/D7/D30 por calendario.
Survival/Hazard gráficos.
Puente «que cambió LTV a D30»: contribución de pago, frecuencia, cheque medio.
11) Experimentación y causalidad
A/B: onboarding, tutoriales, paywall, offers. La métrica principal es D7/D30 retention y LTV (D30).
Cuasiexperimentos: DiD/control sintético para el despliegue en los mercados.
Modelos de Uplift: dirija la ganancia de retorno en re-activación (Qini/AUUC, uplift @ k).
12) Explotación y gobierno
Versificación: 'RET _ D7 _ vN', 'LTV _ D30 _ vN'; changelog cuando cambia la definición de actividad/moneda.
SLO frescura: cohortes diarias - listo hasta 06:00 lock.; archivo de datos ≤ 1 h.
Calidad: coverage de eventos, proporción de duplicados, proporción de bots/frod fuera de cohortes.
Acceso: RLS/CLS, enmascaramiento PII; exportación - sólo unidades.
Runbooks: caída de D1 (onboarding), D7 (contenido), desguace de eventos/identidades.
13) Errores frecuentes (anti-patrones)
Mezcla de ejes: compara diferentes edades de cohorte en diferentes temporadas sin correcciones.
Rolling vs Nat: interpretado como lo mismo.
Mezcla de unidades: sesiones en el denominador, usuarios en el numerador.
Agregando «promedios medios»: en lugar de sumar numeradores/denominadores.
Ignorar TZ/calendario: desplazamiento de D1 en los límites de días/días festivos.
No hay filtro de bots/frod/QA.
Restarts no contabilizados: cuentas divididas/merge sin puentes de identidad.
14) Lista de verificación antes de publicar el informe de cohorte
- Definido evento de nacimiento, unidad, TZ, ventanas de actividad
- Se excluyen los bots/frod/QA; identidades mezcladas (registro de oro)
- Se construyeron las matrices CR (Nat/Rolling) y LTV a D7/D30/D90
- Se ha tenido en cuenta el calendario/días festivos; segmentos por canal/plataforma/geo
- Survival/hazard gráficos y bridge LTV agregados
- Versiones documentadas de métricas y algoritmo de atribución
- SLO de frescura personalizada, monitoreo de coverage/duplicados/errores
- Listo para runbooks sobre caídas de D1/D7 y acantilados de eventos
Resultado
El análisis de cohortes son dos ejes y disciplina: «momento de nacimiento» fijo, ventanas correctas y TZ, matrices de retención y LTV, segmentación y verificación causal de cambios. Este enfoque ayuda no solo a observar las curvas, sino también a tomar decisiones: dónde arreglar el onboarding, qué canales escalar, qué contenido y offers mantienen a los jugadores más tiempo y aumentar el LTV.