Test A/B

Analyse de données bayésienne en Python

Michal Oleszak

Machine Learning Engineer

Test A/B

  • Expérience aléatoire : diviser les utilisateurs en deux groupes (A et B)

 

 

Deux groupes d'utilisateurs.

1 Image : adaptée de https://commons.wikimedia.org/wiki/File:A-B_testing_simple_example.png
Analyse de données bayésienne en Python

Test A/B

  • Expérience aléatoire : diviser les utilisateurs en deux groupes (A et B)
  • Exposer chaque groupe à une version différente (p. ex. mise en page du site)

 

Deux groupes d'utilisateurs voyant deux mises en page de site différentes.

1 Image : adaptée de https://commons.wikimedia.org/wiki/File:A-B_testing_simple_example.png
Analyse de données bayésienne en Python

Test A/B

  • Expérience aléatoire : diviser les utilisateurs en deux groupes (A et B)
  • Exposer chaque groupe à une version différente (p. ex. mise en page du site)
  • Comparer lequel obtient le meilleur score sur un indicateur (p. ex. taux de clics)

Deux groupes d'utilisateurs voyant deux mises en page différentes, l'une avec un taux de clics plus élevé.

1 Image : adaptée de https://commons.wikimedia.org/wiki/File:A-B_testing_simple_example.png
Analyse de données bayésienne en Python

Test A/B : approche fréquentiste

  • Basé sur des tests d'hypothèses
  • Vérifier si A et B ont les mêmes performances ou non
  • Ne dit pas de combien A est meilleur que B
Analyse de données bayésienne en Python

Test A/B : approche bayésienne

  • Calculer les taux de clics a posteriori pour les mises en page A et B et les comparer
  • Calculer directement la probabilité que A soit meilleur que B
  • Quantifier de combien c'est meilleur
  • Estimer la perte attendue si la décision est mauvaise
Analyse de données bayésienne en Python

Test A/B : approche bayésienne

  • Quand un utilisateur arrive sur le site, deux cas :
    • Clic (succès)
    • Pas de clic (échec)
  • Utiliser une loi binomiale ! (probabilité de succès = taux de clics)
Analyse de données bayésienne en Python

Simuler une loi bêta a posteriori

Nous savons que si l'a priori est $Beta(a, b)$, alors l'a posteriori est $Beta(x, y)$, avec :

$x = \text{NumberOfSuccesses} + a$

$y = \text{NumberOfObservations} - \text{NumberOfSuccesses} + b$

def simulate_beta_posterior(trials, beta_prior_a, beta_prior_b):
    num_successes = np.sum(trials)
    posterior_draws = np.random.beta(
      num_successes + beta_prior_a, 
      len(trials) - num_successes + beta_prior_b, 
      10000
    )
    return posterior_draws
Analyse de données bayésienne en Python

Comparer les postérieurs

Listes de 1 (clics) et 0 (pas de clic) :

print(A_clicks)
print(B_clicks)
[0 1 1 0 0 0 0 0 0 0 1 ... ]
[0 0 0 1 0 0 0 1 1 0 1 ... ]

 

Simuler des tirages a posteriori pour chaque mise en page :

A_posterior = simulate_beta_posterior(A_clicks, 1, 1)
B_posterior = simulate_beta_posterior(B_clicks, 1, 1)

Tracer les postérieurs :

sns.kdeplot(A_posterior, shade=True, label="A")
sns.kdeplot(B_posterior, shade=True, label="B")
plt.show()

Deux courbes de densité a posteriori, partiellement superposées.

Analyse de données bayésienne en Python

Comparer les postérieurs

Différence a posteriori entre B et A :

diff = B_posterior - A_posterior

sns.kdeplot(diff, shade=True, label="difference: A-B")
plt.show()

Un tracé de densité avec presque toute la masse de probabilité au-dessus de zéro.

Probabilité que B soit meilleur :

(diff > 0).mean()
0.9639
Analyse de données bayésienne en Python

Perte attendue

Si nous déployons la moins bonne version du site, combien de clics perdons-nous ?

# Différence (B-A) quand A est meilleur 
loss = diff[diff < 0]


# Perte attendue (moyenne) expected_loss = loss.mean() print(expected_loss)
-0.0077850237030215215
Analyse de données bayésienne en Python

Données publicitaires

print(ads)
                               user_id   product site_version                 time  banner_clicked
0     f500b9f27ac611426935de6f7a52b71f   clothes      desktop  2019-01-28 16:47:08               0
1     cb4347c030a063c63a555a354984562f  sneakers       mobile  2019-03-31 17:34:59               0
2     89cec38a654319548af585f4c1c76b51   clothes       mobile  2019-02-06 09:22:50               0
3     1d4ea406d45686bdbb49476576a1a985  sneakers       mobile  2019-05-23 08:07:07               0
4     d14b9468a1f9a405fa801a64920367fe   clothes       mobile  2019-01-28 08:16:37               0
...                                ...       ...          ...                  ...             ...
9995  7ca28ccde263a675d7ab7060e9ed0eca   clothes       mobile  2019-02-02 08:19:39               0
9996  7e2ec2631332c6c4527a1b78c7ede789   clothes       mobile  2019-04-04 03:27:05               0
9997  3b828da744e5785f1e67b5df3fda5571   clothes       mobile  2019-04-15 15:59:06               0
9998  6cce0527245bcc8519d698af2224c04a   clothes       mobile  2019-05-21 20:43:21               0
9999  8cf87a02f96327a1a8a93814f34d0d0c  sneakers       mobile  2019-03-02 21:27:57               0
Analyse de données bayésienne en Python

Lançons un test A/B !

Analyse de données bayésienne en Python

Preparing Video For Download...