Essais A/B

Analyse bayésienne des données en Python

Michal Oleszak

Machine Learning Engineer

Essais A/B

  • Expérience aléatoire : répartir 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 bayésienne des données en Python

Essais A/B

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

 

Deux groupes d'utilisateurs voient deux mises en page différentes.

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

Essais A/B

  • Expérience aléatoire : répartir les utilisateurs en deux groupes (A et B)
  • Montrer à chaque groupe une version différente (p. ex. la mise en page du site)
  • Comparer selon un indicateur (p. ex. taux de clics)

Deux groupes voient deux mises en page; l'une a un taux de clics plus élevé.

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

Essais A/B : approche fréquentiste

  • Fondé sur les tests d'hypothèses
  • Vérifier si A et B performent pareil ou non
  • Ne dit pas de combien A est meilleur que B
Analyse bayésienne des données en Python

Essais A/B : approche bayésienne

  • Calculer les taux de clics postérieurs 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 erronée
Analyse bayésienne des données en Python

Essais A/B : approche bayésienne

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

Simuler la postérieure bêta

On sait 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 bayésienne des données en Python

Comparer les postérieures

Listes de 1 (clics) et 0 (aucun 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érieures :

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

Deux tracés de densité a posteriori, qui se chevauchent partiellement.

Analyse bayésienne des données en Python

Comparer les postérieures

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 bayésienne des données en Python

Perte attendue

Si nous déployons la pire 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 bayésienne des données en Python

Données sur les annonces

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 bayésienne des données en Python

Faisons un essai A/B !

Analyse bayésienne des données en Python

Preparing Video For Download...