Ir al contenido
wannacode

Contrastar una hipótesis

En resumen: Un contraste de hipótesis pregunta si una diferencia podría ser casualidad: la hipótesis nula dice «no hay diferencia», y el valor p es cuántas veces el azar da una diferencia al menos así de grande.

Problema

«¿Es el viernes de verdad más fuerte?»

El jefe quiere poner una persona más en el empaquetado los viernes y quitar una los domingos. Antes pregunta: ¿el viernes es de verdad más fuerte, o este año simplemente salió así? Esto es cuántos pedidos entran de media por día, según el día de la semana (0 es lunes, 6 es domingo):

Pythondatos: las tablas de la tienda

Contamos todos los pedidos, también los cancelados: la pregunta es cuántos llegan, y un pedido cancelado también se recibe y se tramita. Un viernes entran de media 36,35 pedidos, y un domingo 24,62. El año tiene 52 viernes y también 52 domingos. Cada día es un poco distinto: un viernes trae 22 pedidos, otro 68. ¿Es real una diferencia de 11,73 pedidos, o es ruido como en la lección sobre muestras?

La idea

Si el día no importara

La pregunta «¿es el viernes más fuerte que el domingo?» es una hipótesis. Para comprobarla, partes de la explicación aburrida: el día no importa y la diferencia es casualidad. Esa es la hipótesis nula.

Si la hipótesis nula es cierta, las etiquetas «viernes» y «domingo» no significan nada. Puedes mezclarlas: pon los 104 días en un montón, mézclalos y di que los primeros 52 son «viernes» y los otros 52 «domingos». La diferencia entre las dos mitades es la diferencia que da el azar por sí solo:

Pythondatos: las tablas de la tienda

La diferencia real es de 11,73 pedidos. Tres mezclas dan 0,50, 1,23 y 1,46. np.concatenate pega los dos arreglos en uno, y rng.permutation devuelve una copia mezclada.

La idea

10 000 mezclas y el valor p

Tres mezclas son pocas. Haces 10 000 de una vez: np.tile repite los 104 días en 10 000 filas, y rng.permuted(..., axis=1) mezcla cada fila por separado. Luego un solo cálculo da la diferencia de cada fila:

Pythondatos: las tablas de la tienda

La mayor diferencia de 10 000 mezclas es de 7,50 pedidos. La real es de 11,73. La proporción de mezclas con una diferencia al menos así de grande es el valor p: aquí es 0, es decir, menos de 1 entre 10 000. Si el día no importara, una diferencia así casi nunca saldría. La conclusión: el viernes es de verdad más fuerte.

Este enfoque se llama prueba de permutaciones. np.abs está ahí porque la pregunta es «¿hay una diferencia?», sin decir de antemano en qué dirección. El umbral habitual es 0,05: por debajo, dices que la diferencia es estadísticamente significativa.

Pruébalo

Lunes y sábado

1. La prueba de permutaciones de viernes contra domingo da p = 0 en 10 000 mezclas. ¿Qué significa?

La diferencia entre lunes y sábado es menor. ¿Es casualidad? Guarda en gap la diferencia del número medio de pedidos por día (lunes menos sábado), en gaps las diferencias de 10 000 mezclas y en p el valor p.

Pythondatos: las tablas de la tienda

La idea

Cuando no hay diferencia

El domingo hay menos pedidos. ¿Son también más pequeños los propios pedidos? Aquí se comparan 10 459 pedidos sin los cancelados, no días, así que una tabla de números de 2000 × 10 459 ocuparía unos 170 MB. Un bucle con 2000 mezclas de la máscara tarda menos de un segundo:

Pythondatos: las tablas de la tienda

Hay 1204 pedidos de domingo, con una media de 10,83 €, y los demás tienen de media 10,60 €. La diferencia es de 0,23 € y p = 0,425: en el 42,5 % de las mezclas la diferencia es al menos así de grande. Es ruido corriente.

La conclusión honesta es «no hay evidencia de que el pedido del domingo sea distinto». No es «hemos demostrado que son iguales»: puede haber una diferencia pequeña, solo que estos datos no la muestran. El domingo la gente pide con menos frecuencia, y no hay evidencia de que pida menos.

La idea

Lo que p no dice

El valor p responde una pregunta estrecha: cuán sorprendentes son los datos si la hipótesis nula es cierta. No es dos cosas con las que a menudo se confunde:

  • no es la probabilidad de que la hipótesis sea cierta: p = 0,425 no significa «un 42,5 % de probabilidad de que no haya diferencia»;
  • no es el tamaño de la diferencia: una p muy pequeña significa «no es casualidad», no «una diferencia grande».

Cuán grande es la diferencia lo dice la propia diferencia con un intervalo. Con el bootstrap de la lección anterior, por separado para los viernes y los domingos:

Pythondatos: las tablas de la tienda

El viernes tiene de media 11,73 pedidos más, con un intervalo del 95 % de 9,00 a 14,56. Es 1,48 veces el domingo. Con este número el jefe decide a cuánta gente pone, y p solo dice que no está persiguiendo ruido.

Más precisamente, para curiosos

El umbral de 0,05 es una convención, no una ley de la naturaleza. Con p = 0,06 los datos no son «casi evidencia», y con p = 0,04 no son «seguramente ciertos». Con muchísimos datos, incluso una diferencia diminuta da una p pequeña: con un millón de pedidos en cada grupo y una diferencia de 10 céntimos la prueba será «significativa», pero de ahí no se sigue ninguna decisión. Así que anota siempre las dos cosas, la diferencia y el intervalo.

La idea

Lo mismo con scipy

scipy.stats tiene las pruebas listas. ttest_ind (la prueba t) compara las medias de dos grupos con una fórmula. permutation_test hace la mezcla por ti, por tandas (batch), para que no se acabe la memoria:

Pythondatos: las tablas de la tienda

Para el pedido del domingo la prueba t da 0,426, permutation_test 0,419 y nuestro bucle 0,425. La respuesta es la misma: no hay evidencia. Para viernes contra domingo la prueba t da 1,04 × 10⁻¹²: cero a efectos prácticos, como nuestro 0 de 10 000.

Más precisamente, para curiosos

La prueba t supone que la media de cada grupo está distribuida casi de forma normal. Con cientos de pedidos en un grupo eso es cierto (teorema central del límite). Con pocos datos y una cola larga la prueba de permutaciones es más segura, porque no supone nada sobre la distribución. permutation_test da una p algo distinta de la nuestra: las mezclas son otras, y además cuenta los propios datos como una de ellas, (cantidad + 1) / (mezclas + 1).

Ejercicio

Diciembre y viernes

En diciembre se venden tarjetas regalo. ¿Es el pedido de diciembre mayor que los pedidos de los demás meses, o es casualidad? Guarda en gap la diferencia del pedido medio (diciembre menos los demás meses) y en p el valor p. Puedes usar una prueba de permutaciones o stats.ttest_ind.

Pythondatos: las tablas de la tienda

El pedido del viernes es algo menor que el de los demás días. ¿Hay evidencia de ello? Haz una prueba de permutaciones con 2000 mezclas (semilla 42): gap es la diferencia del pedido medio (viernes menos los demás días), p es el valor p y evidence indica si p está por debajo del umbral de 0,05.

Pythondatos: las tablas de la tienda

Test

Ponte a prueba

1. ¿Cuál es la hipótesis nula cuando comparas el pedido medio del domingo con el de los demás días?
2. Para el pedido del domingo, p = 0,425. ¿Qué conclusión es honesta?
3. ¿Por qué p se calcula con np.abs(gaps) >= abs(gap) y no con gaps >= gap?
4. p para diciembre es 5,1 × 10⁻²³, y para viernes contra domingo 1,0 × 10⁻¹². ¿Significa eso que diciembre es la diferencia mayor?

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