Ir al contenido
wannacode

Prueba A/B

En resumen: Una prueba A/B compara dos variantes en visitantes repartidos al azar y comprueba si la diferencia en la conversión es real o solo ruido.

Problema

«¿Es mejor el carrito nuevo?»

El equipo hizo una página de carrito nueva: más corta, con menos campos. Nadie sabe si es mejor. Así que durante dos semanas cada visita al sitio ve, al azar, el carrito viejo (old) o el nuevo (new). La columna ordered es 1 si la visita termina con un pedido:

Pythondatos: las tablas de la tienda

Esto es una prueba A/B: dos versiones, visitantes repartidos al azar, una medida. La medida aquí es la conversión: la proporción de visitas que terminan con un pedido. El carrito viejo tiene el 3,10 %, el nuevo el 3,72 %.

La diferencia es de 0,62 puntos porcentuales: una diferencia entre dos porcentajes. Eso es cerca de una quinta parte más de pedidos. Pero ¿es ruido?

La idea

¿Es ruido la diferencia?

Esta es la pregunta de la lección sobre hipótesis. La hipótesis nula: el carrito no cambia nada. Si es cierta, las etiquetas old y new no importan y puedes mezclarlas. ¿Con qué frecuencia dan los datos mezclados una diferencia de al menos 0,62 puntos?

Pythondatos: las tablas de la tienda

En 2000 mezclas la mayor diferencia es de 0,76 puntos, pero solo 6 veces es al menos tan grande como la real. p es 0,003. Una diferencia así rara vez viene del ruido.

Más precisamente, para curiosos

ordered es 0 o 1, así que la media de la columna es exactamente la proporción de pedidos. La mezcla aquí es un bucle: la tabla tiene 28 176 filas, y 2000 mezclas a la vez en una matriz necesitarían mucha memoria en el navegador.

Pruébalo

¿En cada dispositivo?

¿La mejora viene de los teléfonos o de las computadoras de escritorio? Guarda en rates la conversión en porcentaje para cada dispositivo (filas) y variante (columnas), y en lift la diferencia new − old para cada dispositivo, en puntos.

Pythondatos: las tablas de la tienda

La idea

El camino más rápido: chi2_contingency

Para dos proporciones hay una comprobación lista. Primero pd.crosstab cuenta las parejas: cuántas visitas de cada variante tienen pedido y cuántas no. Luego scipy.stats.chi2_contingency dice cuán rara es una tabla así si la variante no cambia nada:

Pythondatos: las tablas de la tienda

p es 0,0046, cerca de 0,005. La mezcla dio 0,003: los dos caminos dicen lo mismo. La pequeña diferencia se debe a que 2000 mezclas miden p de forma aproximada (6 casos), y chi2_contingency hace una pequeña corrección para una tabla de 2 × 2, que sube p un poco.

La idea

¿Cuán grande es la mejora?

p solo dice «difícilmente ruido». El jefe pregunta otra cosa: ¿cuánto mejor es el carrito nuevo? Para eso necesitas un intervalo. Como en la lección sobre intervalos, sacas de cada grupo muestras nuevas con reemplazo y observas cómo cambia la diferencia:

Pythondatos: las tablas de la tienda

La mejora es de 0,62 puntos, y el intervalo del 95 % va de 0,21 a 1,04 puntos. El cero queda fuera del intervalo: es el mismo «difícilmente ruido». Pero el intervalo dice también cuánto: puede ser algo más de 0,2, puede ser más de 1 punto.

Más precisamente, para curiosos

Aquí son 2000 repeticiones, no 10 000, para que corra rápido: cada una saca 14 000 filas. Según la fórmula, el intervalo de una diferencia entre dos proporciones es la diferencia ± 1,96 × √(p₁(1 − p₁)/n₁ + p₂(1 − p₂)/n₂). Da casi lo mismo:

Pythondatos: las tablas de la tienda

La idea

Cuántas visitas necesitas

¿Cuánto debe durar la prueba? Eso lo decides antes de empezar, a partir de dos números: la conversión hasta ahora (3,1 %) y la menor mejora que te importa (0,6 puntos). Hay una regla práctica para una probabilidad del 80 % de ver la mejora con el umbral de 0,05:

visitas por grupo ≈ 16 × p × (1 − p) / mejora²

Pythondatos: las tablas de la tienda

Necesitas 13 351 visitas por grupo, 26 701 en total. La probabilidad de que la prueba detecte una mejora real se llama potencia. Puedes comprobarla con una simulación: inventa 2000 pruebas con conversiones del 3,1 % y del 3,7 % y cuenta con qué frecuencia p sale por debajo de 0,05. rng.binomial(n, 0.031) da cuántos pedidos salen de n visitas, cada una con un 3,1 % de probabilidad:

Pythondatos: las tablas de la tienda

Con 2000 visitas por grupo la prueba detecta la mejora solo en el 18 % de los casos, con 5000 en el 37 %. Con 13 351 es el 78 %, cerca del 80 % de la regla. Una prueba pequeña no dice «no hay diferencia»: simplemente no puede verla.

Más precisamente, para curiosos

p_value es la comprobación de dos proporciones con una fórmula (una prueba z). Trabaja con arreglos enteros a la vez, así que 2000 pruebas tardan un momento. Para una tabla de 2 × 2 da casi lo mismo que chi2_contingency. El 16 de la regla viene del umbral de 0,05 y una potencia del 80 %: (1,96 + 0,84)² × 2 ≈ 16.

Pruébalo

Una mejora mayor

El equipo de producto dice: «Solo nos importa una mejora de al menos 1 punto.» ¿Cuántas visitas por grupo necesita la regla? Guárdalas en per_group como un número entero.

Pythondatos: las tablas de la tienda

La idea

No mires antes del final

La tentación es mirar el resultado cada día. Aquí está p calculada con todas las visitas hasta cada día:

Pythondatos: las tablas de la tienda

El día tres p es 0,053, el día cuatro 0,077, el día cinco 0,041. Si hubieras parado el día cinco, habrías declarado una victoria. Aquí el carrito nuevo de verdad es mejor, pero eso se ve por la prueba entera. La regla «paro en cuanto p baje de 0,05» es el error mismo.

¿Por qué? Compruébalo con una prueba A/A: los dos grupos ven lo mismo, y no hay diferencia. Simulamos 1000 pruebas así de 14 días y miramos p cada día:

Pythondatos: las tablas de la tienda

Si solo miras al final, las falsas «victorias» son el 4,9 %, tanto como promete el umbral de 0,05. Si miras cada día y paras en la primera p por debajo de 0,05, son el 21,7 %: cuatro veces más. El ruido tiene 14 oportunidades de caer por debajo de la línea.

1. La prueba está planificada para 14 días. El día cinco p es 0,041. Un compañero dice: «Está por debajo de 0,05, paremos y activemos el carrito nuevo.» ¿Qué está mal?

La idea

Muchas métricas, muchos segmentos

El carrito nuevo trae más pedidos. ¿Son también más grandes? Compara el valor por pedido:

Pythondatos: las tablas de la tienda

26,30 € con el carrito nuevo y 26,71 € con el viejo, p = 0,73. No hay evidencia de que el carrito cambie el valor del pedido. Eso no es «hemos demostrado que son iguales»: puede haber una diferencia pequeña, pero esta prueba no la ve.

Imagina ahora un informe con 20 métricas: pedidos, valor, devoluciones, tiempo en la página… Cada métrica sin una diferencia real tiene un 5 % de probabilidad de salir con p por debajo de 0,05. ¿Con qué frecuencia «gana» al menos una?

Pythondatos: las tablas de la tienda

Una métrica «gana» en el 5,1 % de los casos, como se esperaba. Pero al menos una de 20 «gana» en el 64,1 % de las pruebas. Lo mismo vale para los segmentos: móvil, escritorio, clientes nuevos, cada día de la semana. Por eso la métrica principal se elige antes de la prueba. Una «victoria» casual en la métrica número 20 es una idea para la próxima prueba, no una conclusión.

La idea

Por qué la prueba dice «causa»

¿Por qué crees que el carrito causa más pedidos y no solo los acompaña? Porque la variante se asignó al azar. El azar iguala todo lo que no mides. Aquí están los dispositivos en los dos grupos:

Pythondatos: las tablas de la tienda

En los dos grupos los de escritorio son el 35 % y los teléfonos el 65 %. Lo mismo vale para la hora, el día, los hábitos de la gente: los grupos se diferencian solo en el carrito. Así que la diferencia en los pedidos viene de él.

Cuando los datos no son de una prueba, no es así. En la próxima lección un banner parece subir los pedidos, pero en cada dispositivo por separado no lo hace.

Ejercicio

Un informe para el jefe

El jefe pregunta: «¿Trae el carrito nuevo más dinero por visita?» Guarda en per_visit los ingresos medios por visita de cada variante (todas las visitas, también las que no tienen pedido) y en p el valor p de la comparación con scipy.stats.ttest_ind.

Pythondatos: las tablas de la tienda

Si lo hubieras planificado desde el principio: ¿cuántos días debería haber durado la prueba? Las visitas por día son de media len(visits) / 14. Guarda en per_group las visitas por grupo según la regla (una mejora de 0,6 puntos con un 3,1 %), en per_day las visitas por día y en days los días, redondeados hacia arriba.

Pythondatos: las tablas de la tienda

Test

Ponte a prueba

1. La comprobación del carrito nuevo da p = 0,005. ¿Qué significa?
2. Quieres ver una mejora de 0,3 puntos en lugar de 0,6. ¿Cuántas visitas necesitas?
3. El informe sigue 20 métricas. Una de ellas tiene p = 0,04, las demás no. ¿Qué dices?
4. El pedido medio es de 26,30 € con el carrito nuevo y de 26,71 € con el viejo, p = 0,73. ¿Qué conclusión es correcta?
5. ¿Por qué después de la prueba A/B puedes decir «el carrito nuevo lleva a más pedidos» y no solo «los dos van juntos»?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·