Módulo 5: Ab Testing Fundamentals

Midiendo el lift

Descripción

Con control y variant bien definidos (lección 3), asignados al azar (lección 4), y con H0 formulada de antemano (lección 5), por fin llega el momento de calcular un número real. Ese número se llama el lift (lift, literalmente "levantamiento" o "elevación"): la diferencia relativa entre la tasa de conversión de variant y la de control, expresada como porcentaje de mejora (o empeoramiento) sobre la línea base de control.

La fórmula es simple:

lift = (conversionRate(variant) - conversionRate(control)) / conversionRate(control)

Y esta lección la construye, la ejecuta sobre los datos reales del lanzamiento de recommendations, y hace algo igual de importante que calcularla bien: advierte, con toda claridad, sobre qué NO se puede concluir todavía con este número. El lift que calculas hoy es puramente descriptivo — describe lo que pasó en esta muestra específica de usuarios—. Todavía no sabes si ese lift es un efecto real de recommendations o si es la clase de variación que aparecería igual, aunque el carrusel no hiciera absolutamente nada, solo por tener dos grupos distintos de gente. Esa pregunta —¿es real, o es azar?— es, con toda intención, el trabajo completo del módulo 6.

Conexión con el módulo. Esta lección construye abTest(), la función que vas a reutilizar sin cambios en el mini-proyecto de la lección 8 y que el módulo 6 va a extender —no reemplazar— agregándole el cálculo de significancia (pValue, intervalo de confianza) que todavía no existe hoy. La parte descriptiva que construyes aquí (conversionRate, lift) sigue siendo, exactamente igual, parte de abTest() en el módulo 6 — solo se le suma el análisis de si ese lift es confiable.

Una analogía: el mismo aumento de sueldo, dos salarios de partida

Imagina dos personas que reciben, cada una, un aumento de sueldo de exactamente $1,000 al mes. Para la primera persona, que ganaba $10,000 al mes, ese aumento representa un 10% de mejora sobre su salario —un cambio notable—. Para la segunda persona, que ganaba $100,000 al mes, el mismo aumento de $1,000 representa apenas un 1% de mejora —casi imperceptible en proporción a lo que ya ganaba—. La diferencia absoluta es idéntica en ambos casos ($1,000), pero la diferencia relativa —lo que de verdad importa para entender cuánto cambió la situación de cada persona— es diez veces mayor para la primera.

El lift de un A/B test tiene exactamente esta misma naturaleza: es una diferencia relativa, no absoluta, y esa distinción no es un detalle técnico —cambia por completo cómo se interpreta el resultado—. Una diferencia de "+0.6 puntos porcentuales" (de 3.2% a 3.8%, el caso de recommendations en Mercado) suena chica en términos absolutos. Pero, igual que el aumento de $1,000 sobre un salario de $10,000, esa diferencia representa una mejora relativa del 18.75% sobre la tasa de conversión de partida — un salto mucho más significativo de lo que "+0.6 puntos" sugiere a simple vista. Por eso el lift se calcula siempre como una proporción sobre control, no como una resta simple.

Ejemplo trabajado: abTest() sobre el lanzamiento de recommendations

Vamos a construir la parte descriptiva de abTest() y ejecutarla sobre los números reales del experimento de Mercado: seis semanas después del lanzamiento, control (sin recommendations) tuvo 12,000 usuarios con 384 conversiones; variant (con recommendations) tuvo 12,000 usuarios con 456 conversiones.

// abTest: la parte DESCRIPTIVA de un A/B test -- calcula la conversionRate de
// cada grupo y el lift relativo entre variant y control.
//
// ADVERTENCIA IMPORTANTE: este lift es puramente descriptivo. Todavia NO sabemos
// si la diferencia es un efecto real de recommendations o si es azar -- dos
// grupos aleatorizados de 12,000 usuarios cada uno pueden diferir por pura
// variacion estadistica, incluso sin ningun efecto real de por medio. Decidir
// si el lift es "real" (significancia: p-value, intervalo de confianza) es
// el z-test de proporciones del modulo 6 -- NO se implementa todavia aqui.
function abTest({ control, variant }) {
  const controlRate = control.conversions / control.n;
  const variantRate = variant.conversions / variant.n;
  const lift = (variantRate - controlRate) / controlRate;
  return { controlRate, variantRate, lift };
}

// Datos pedagogicos: el lanzamiento de recommendations en Mercado, semana del
// experimento. control = NO vio el carrusel de recomendaciones; variant = SI
// lo vio. La metrica primaria es checkoutConversionRate (lo definiste en la
// leccion 5, como H0).
const mercadoExperiment = {
  control: { n: 12000, conversions: 384 },
  variant: { n: 12000, conversions: 456 },
};

console.log('=== abTest() -- lift descriptivo sobre recommendations de Mercado ===\n');
const result = abTest(mercadoExperiment);

console.log('control:  n=' + mercadoExperiment.control.n + '  conversions=' + mercadoExperiment.control.conversions +
  '  conversionRate=' + (result.controlRate * 100).toFixed(2) + '%');
console.log('variant:  n=' + mercadoExperiment.variant.n + '  conversions=' + mercadoExperiment.variant.conversions +
  '  conversionRate=' + (result.variantRate * 100).toFixed(2) + '%');
console.log('\nlift = (variantRate - controlRate) / controlRate = ' +
  (result.lift * 100).toFixed(2) + '%');
console.log('\nATENCION: este lift es descriptivo. Todavia no sabemos si +' +
  (result.lift * 100).toFixed(2) + '% es un efecto real de recommendations o azar.');
console.log('Eso lo decide la significancia estadistica -- modulo 6.');

Qué esperar. Al correr el archivo con Node, la salida es exactamente esta:

=== abTest() -- lift descriptivo sobre recommendations de Mercado ===

control:  n=12000  conversions=384  conversionRate=3.20%
variant:  n=12000  conversions=456  conversionRate=3.80%

lift = (variantRate - controlRate) / controlRate = 18.75%

ATENCION: este lift es descriptivo. Todavia no sabemos si +18.75% es un efecto real de recommendations o azar.
Eso lo decide la significancia estadistica -- modulo 6.

Fíjate en la magnitud del salto entre la diferencia absoluta y la relativa, exactamente como en la analogía del sueldo: control convierte al 3.20%, variant al 3.80% — una diferencia absoluta de apenas 0.6 puntos porcentuales. Pero como esos 0.6 puntos se miden sobre una base de partida chica (3.20%), la mejora relativa —el lift— es del 18.75%: casi una quinta parte más conversiones que la línea base de control. Ambos números son ciertos al mismo tiempo; describen la misma diferencia desde dos ángulos distintos, y confundirlos —o reportar solo uno sin aclarar cuál es— es exactamente el segundo error común de esta lección.

Por qué el denominador de la fórmula es siempre control

Vale la pena detenerse en un detalle de la fórmula que parece arbitrario pero no lo es: el lift se divide siempre entre conversionRate(control), nunca entre conversionRate(variant). Esto tiene una razón concreta: control representa la línea base —lo que ya existía, lo que se está tratando de mejorar—, así que el lift contesta la pregunta "¿cuánto mejoramos sobre lo que ya teníamos?", no "¿cuánto peor sería quedarnos en lo viejo, medido desde lo nuevo?". Si el orden se invirtiera —dividiendo entre variantRate en vez de controlRate— el número resultante contestaría una pregunta distinta y, en la práctica, siempre daría un porcentaje más chico cuando el cambio es una mejora (en este caso, (3.80 - 3.20) / 3.80 = 15.79%, no 18.75%). La convención de la industria —y la que usa abTest() hoy— es consistente: el lift siempre se mide como el cambio relativo sobre la línea base, y esa línea base es, por definición, control.

Errores comunes

Celebrar el lift observado como si ya fuera un resultado confiable, sin significancia. Qué pasa: un reporte de producto anuncia "recommendations mejora la conversión en un 18.75%, decisión: enviar a todos" basándose únicamente en el resultado de abTest() de hoy. Por qué pasa: un lift de +18.75% es un número contundente y fácil de comunicar, y después de todo el trabajo de diseñar el experimento (lecciones 3 a 5), es tentador tratar el primer número calculado como la respuesta final. Cómo detectarlo: la palabra "significativo", "p-value" o "intervalo de confianza" no aparece en ningún lugar del reporte, solo el lift crudo. Cómo corregirlo: como advierte el comentario del código de hoy, un lift de +18.75% sobre 12,000 usuarios por grupo podría ser azar —dos grupos aleatorizados de ese tamaño pueden diferir por variación natural, incluso sin ningún efecto real—. Confirmar si esta diferencia es demasiado grande para ser casualidad es, con toda intención, el trabajo del módulo 6, no de esta lección.

Confundir la diferencia en puntos porcentuales con el lift relativo. Qué pasa: alguien reporta "recommendations mejoró la conversión en 18.75 puntos porcentuales" —tomando el número del lift relativo (18.75%) y tratándolo como si fuera una diferencia absoluta en puntos, cuando la diferencia absoluta real es de apenas 0.6 puntos—. Por qué pasa: ambos números —0.6 puntos y 18.75%— describen la misma comparación, y es fácil, sin la analogía del sueldo de esta lección presente, mezclar cuál es cuál. Cómo detectarlo: si "18.75 puntos porcentuales" se suma directamente a la tasa de control (3.20% + 18.75 = 21.95%, un número absurdamente alto para este contexto), algo salió mal en la interpretación. Cómo corregirlo: reporta siempre los tres números juntos y con su etiqueta explícita — controlRate (3.20%), variantRate (3.80%), y lift (+18.75%, siempre marcado como "relativo" o "%") — exactamente como hace la salida de abTest() de hoy, para que nunca quede ambigüedad sobre cuál de los dos tipos de diferencia se está citando.

Reportar el lift sin mencionar el tamaño de muestra (n) que lo respalda. Qué pasa: un mensaje dice "el lift fue de +18.75%" sin mencionar en ningún lado que ese número viene de 12,000 usuarios por grupo — el mismo +18.75% sonaría igual de impresionante si viniera de apenas 50 usuarios por grupo. Por qué pasa: el lift, como porcentaje, se siente como un resumen completo por sí solo, y agregar el tamaño de muestra parece un detalle técnico prescindible para una comunicación rápida. Cómo detectarlo: el reporte cita un porcentaje de lift sin ningún número de n o conversions al lado. Cómo corregirlo: como hace la salida de abTest() de hoy, reporta siempre el lift junto con el n y las conversions de cada grupo que lo produjeron. Un lift idéntico calculado sobre muestras muy chicas merece mucha menos confianza que uno calculado sobre 12,000 usuarios por grupo — el módulo 7 va a formalizar exactamente cuánta muestra hace falta para confiar en un lift de un tamaño dado.

Ejercicios

Ejercicio 1 — Calcula el lift a mano con otros números. Un segundo experimento en Mercado, sobre un rediseño del botón de checkout, da estos resultados: control = 8,000 usuarios, 240 conversiones; variant = 8,000 usuarios, 264 conversiones. Sin ejecutar Node, calcula controlRate, variantRate, y el lift.

Ver solución

controlRate = 240/8000 = 3.0%. variantRate = 264/8000 = 3.3%. lift = (0.033 - 0.030) / 0.030 = 0.003/0.030 = 10.0%. Nota que la diferencia absoluta (0.3 puntos porcentuales) es más chica que la del ejemplo de recommendations (0.6 puntos), y el lift relativo (10.0%) también es más chico que el de recommendations (18.75%) — en este caso ambas comparaciones (absoluta y relativa) apuntan en la misma dirección, a diferencia de otros casos donde pueden divergir según la tasa de partida de cada experimento.

Ejercicio 2 — Detecta el denominador invertido. Un compañero de equipo calcula el lift del experimento de recommendations así: lift = (variantRate - controlRate) / variantRate = (0.038 - 0.032) / 0.038 = 15.79%, y lo reporta como "el lift oficial". ¿Qué hizo distinto de la fórmula de abTest() de hoy, y por qué el resultado de tu compañero (15.79%) es distinto del oficial (18.75%)?

Ver solución

Tu compañero dividió entre variantRate (0.038) en vez de controlRate (0.032) — el denominador invertido respecto a la convención de la lección de hoy—. Esto produce un número más chico (15.79% contra 18.75%) porque el denominador es más grande (0.038 > 0.032), y una misma diferencia absoluta (0.006) dividida entre un número más grande da un resultado relativo más chico. El problema de fondo no es que 15.79% esté "mal calculado" matemáticamente —la aritmética es correcta—, sino que contesta una pregunta distinta a la que el lift está diseñado para contestar: "¿cuánto mejoramos sobre lo que ya teníamos (control)?", no "¿qué tan atrás quedaría control si lo midiera desde variant?". Por eso la fórmula estándar de la industria, y la que usa abTest(), siempre divide entre controlRate — la línea base que se está tratando de mejorar.

Ejercicio 3 — Redacta el mensaje correcto (ni exagerado, ni incompleto). Usando los tres errores comunes de esta lección como checklist, redacta el mensaje de 3-4 frases que un equipo de Mercado debería enviar internamente al calcular por primera vez el lift de recommendations, evitando los tres errores.

Ver solución

Un mensaje razonable: "El experimento de recommendations muestra una conversionRate de 3.20% en control (n=12,000) contra 3.80% en variant (n=12,000) — una diferencia absoluta de 0.6 puntos porcentuales, equivalente a un lift relativo de +18.75%. Este resultado es puramente descriptivo: con este tamaño de muestra, todavía no sabemos si +18.75% es un efecto real de recommendations o variación natural entre los dos grupos aleatorizados. El siguiente paso, antes de tomar cualquier decisión de enviar o revertir, es calcular la significancia estadística de esta diferencia — el trabajo del módulo 6." El mensaje evita los tres errores: no celebra el resultado como definitivo (error 1), distingue con claridad la diferencia absoluta (0.6 puntos) de la relativa (18.75%, error 2), y menciona el tamaño de muestra que respalda el número (n=12,000 por grupo, error 3).

Resumen y siguiente paso

En esta lección construiste y ejecutaste abTest() — la parte descriptiva de un A/B test —, que calcula conversionRate para control y variant, y el lift: la diferencia relativa entre ambas, siempre medida sobre la línea base de control. Sobre el experimento real de recommendations en Mercado, obtuviste controlRate = 3.20%, variantRate = 3.80%, y un lift de +18.75%. Y viste, con la analogía del aumento de sueldo, por qué esa diferencia relativa (18.75%) puede sonar mucho más grande que la diferencia absoluta que la produce (apenas 0.6 puntos porcentuales) — ambos números son correctos, y confundirlos es un error real y frecuente.

Antes de avanzar deberías poder: calcular conversionRate y lift a mano dados n y conversions de dos grupos, explicar por qué el denominador de la fórmula del lift es siempre controlRate, y distinguir con claridad una diferencia absoluta (puntos porcentuales) de una relativa (lift).

Tienes ahora el lift —+18.75%— pero, como el código de hoy advirtió en cada salida, todavía no sabes si es real. La lección 7 cierra este módulo con la pregunta complementaria: dado todo lo que ya sabes diseñar y calcular, ¿qué puede — y qué definitivamente no puede — contestar un A/B test, sin importar qué tan bien esté diseñado?

Recursos

  • Ron Kohavi, Diane Tang y Ya Xu, Trustworthy Online Controlled Experiments: A Practical Guide to A/B Testingexperimentguide.com. El capítulo sobre métricas del libro cubre en detalle la diferencia entre cambios absolutos y relativos, y por qué la convención de dividir entre control es el estándar en experimentación de producto a gran escala. En inglés.
  • Optimizely, "A/B Testing" (glosario de optimización) — optimizely.com/optimization-glossary/ab-testing. Incluye ejemplos de cálculo de uplift (el mismo concepto que el lift de esta lección, con otro nombre) sobre casos reales de e-commerce. En inglés.
  • Ron Kohavi y Stefan Thomke, "The Surprising Power of Online Experiments" (Harvard Business Review, sept-oct 2017) — hbr.org/2017/09/the-surprising-power-of-online-experiments. El caso del titular de Bing ilustra un lift que sí resultó ser significativo y de alto impacto — el contraste que motiva por qué el módulo 6 es un paso indispensable antes de actuar sobre un lift observado. En inglés.