Protocole de test A/B sur les prix

Protocole de test A/B sur les prix










Accueil » Ressources » Ici

Il n'y a pas d'optimisation sans prise de mesures et l'optimisation des prix nécessite à la fois des essais et des mesures. En effet, trop souvent le pricing se concentre uniquement sur les "changements de prix" sans exploiter ceux-ci en vue de mieux connaître la façon dont le marché réagit aux nouveaux prix. L'élaboration d'une stratégie de pricing devrait être un processus guidé par la connaissance, dans lequel la plupart des changements sont analysés a posteriori pour ajuster les stratégies existantes. Dans le présent article, nous détaillons un protocole de test A/B sur les prix qui peut être exécuté avec l'aide de Lokad. Cette présentation mentionne les outils Lokad mais ce protocole n'est pas spécifique à Lokad et peut être reproduit avec d'autres outils, Excel notamment si les tableaux sont gérés de façon très précise.

1. Création d'un document de référence

Dès que vous êtes en mesure d'effectuer des expériences sur les prix, si vous ne structurez pas les données récoltées, les résultats s'accumulent de façon désorganisée et leurs potentiels enseignements peuvent vous échapper. Nous vous suggérons donc de commencer chaque expérience de ce type par la création d'un "document de référence" où seront regroupées toutes les informations liées à l'expérience. Ce document peut être un fichier Word mais nous vous encourageons à utiliser des outils collaboratifs disponibles sur le Web comme Google Sites ou Hackpad ou n'importe quel système de gestion du contenu en ligne.

Puis, une fois ce document créé, prenez le temps de trouver un nom facilement mémorisable à l'expérience. En effet, une expérience ne sera utile que si les participants peuvent en parler aisément et si les membres de l'équipe de pricing et, éventuellement, leurs successeurs — puisque les employés changent au fur et à mesure que le temps passe — se rappellent des conclusions. L'ennui est l'ennemi de la connaissance. Si le nom ne marque pas les esprits alors cette information sera oubliée même par les plus dévoués des employés.

2. Création d'un projet dédié à l'expérience

Nous vous suggérons de créer, dans votre compte Lokad, un projet dédié à cette expérience sur les prix. Pour plus de clarté, ce projet doit avoir le même nom que l'expérience. De plus, nous vous suggérons d'exploiter la fonctionnalité de lien hypertexte de la vignette label pour relier directement le projet au document de référence, de manière à ce que ce dernier soit disponible en ligne. Par conséquent, votre script devrait commencer comme ceci :

// Expérience sur les prix : Sevilla
// Début : 09-07-2014 Fin : 08-08-2014
// Auteur : Joannes Vermorel
show label "http://example.org/my-reference-document Ref. Document"

Grâce à ce script, la vignette label apparaît dans le tableau de bord en tant que lien hypertexte pointant vers le document de référence, qui présente en détails l'expérience en elle-même.

Plusieurs objectifs sont associés à ce projet, à chaque étape de l'expérience :

  1. Créer les groupes d'articles qui jouent le rôle d'échantillons de contrôle.
  2. Faire en sorte que ces groupes restent inchangés.
  3. Définir la nouvelle stratégie de pricing.
  4. Vérifier le déploiement des prix.
  5. Compiler les résultats des deux groupes de contrôle.

Chacune de ces étapes est mise en œuvre grâce à une partie du script élaboré dans le cadre de ce projet.

3. Définition de l'hypothèse testée

Dès qu'il s'agit de tester une stratégie de pricing, il est très tentant de réexpliquer les résultats après coup, que ceux-ci soient en cohérence avec les attentes initiales ou non. Cette distorsion psychologique est liée à "l'erreur de narration", décrite par Taleb :

L’erreur de narration concerne notre quasi-incapacité à observer des suites d’événements sans leur attribuer coûte que coûte un lien logique, une flèche de relation. Les explications permettent de lier les faits ; elles les rendent d’autant plus mémorables. Elles permettent de leur donner du sens (…) Cette erreur est liée à notre propension à la surinterprétation et au fait que nous préférons les histoires compactes aux vérités brutes. Nassim Nicholas Taleb, Le Cygne Noire
.

Cette difficulté est particulièrement importante en matière de pricing car il n'existe pas "d'environnement contrôlé" pour les conditions du marché. Quel que soit le soin apporté au protocole de l'expérience, de nombreux facteurs restent en dehors de tout contrôle, en commençant par les initiatives des concurrents.

Ainsi, il est essentiel de définir l'hypothèse testée dès le début de l'expérience pour garantir que les résultats valident ou invalident bien cette hypothèse de départ et non une hypothèse ad-hoc revue au cours de l'expérience. Vous devriez consigner cette hypothèse au début du document de référence cité précédemment. Voici un exemple de bonne hypothèse : "les importantes baisses des volumes des ventes ne s'expliquent pas par une baisse de la demande mais par les prix agressifs de concurrents moins visibles. Ainsi, si nous réduisons fortement nos marges sur ces produits, les volumes des ventes devraient redécoller".

4. Création des groupes de contrôle positif and négatif

Une fois l'hypothèse définie, il faut concevoir l'expérience en elle-même. Il est impossible, incommode, voire souvent illégal, d'afficher des prix différents pour un même article à différents groupes de clients. Ainsi, en pratique, dans la distribution, l'approche consiste à sélectionner deux groupes d'articles équivalents, qui ne représentent qu'une petite partie du catalogue.

Ces deux échantillons sont appelés :
  • "groupe de contrôle positif" sur lequel la nouvelle stratégie de pricing est appliquée.
  • "groupe de contrôle négatif" sur lequel l'ancienne stratégie de pricing reste en place.
    En comparant les résultats de ces deux groupes, vous pouvez déterminer si l'hypothèse de départ était la bonne. Avec Envision, il est très simple de sélectionner de façon aléatoire deux groupes de contrôle, grâce à la fonction hash :

seed := "hello world"
R = rankd(hash(concat(Id, seed)))
where R <= 1000
  // groupe de contrôle positif
where R > 1000 & R <= 2000
  // groupe de contrôle négatif

Dans le script ci-dessus, nous générons un mélange aléatoire de tous les articles à la ligne 2. La fonction hash renvoie un nombre pseudo-aléatoire pour la chaîne passée en entrée. Ce fonctionnement n'est pas réellement aléatoire car, pour une même chaîne en entrée, la fonction hash retourne la même valeur à chaque fois. Ainsi, pour générer des échantillons distincts, il faut modifier la chaîne passée avec seed. Puis, à la ligne 3, nous sélectionnons 1 000 articles qui feront partie du groupe de contrôle positif. Enfin, nous répétons l'opération à la ligne 5 pour sélectionner les 1 000 articles du groupe de contrôle négatif.

Cette logique peut facilement être adaptée à des situations dans lesquelles les deux groupes doivent remplir certaines conditions. Par exemple, supposons que les groupes de contrôle doivent contenir uniquement des articles de la marque 'Fabrikam'', voici le script associé :

where Brand == "Fabrikam" // seule la marque "Fabrikam" est ciblée
  seed := "hello world"
  R = rankd(hash(concat(Id, seed)))
  where R <= 50
    // groupe de contrôle positif
  where R > 50 & R <= 100
    // groupe de contrôle négatif

5. Sauvegarde des groupes de contrôle

Lorsque des conditions complexes sont utilisées pour la sélection des groupes de contrôle, il se peut que le programme d'échantillonnage ne retourne pas la même liste d'articles au fur et à mesure que le temps passe. Par exemple, si de nouveaux articles sont lancés, ils peuvent influencer le programme d'échantillonnage décrit dans la section précédente. Nous vous recommandons donc de sauvegarder les groupes de contrôle dans un fichier séparé afin qu'ils n'évoluent pas accidentellement.

seed := "hello world"
R = rankd(hash(concat(Id, seed)))
Control = ""
where R <= 1000
  Control = "pos" // groupe positif
where R > 1000 & R <= 2000
  Control = "neg" // groupe négatif

// exportation du groupe
startDate := "2014-07-09"
endDate := "2014-08-09"
where Control != ""
show table "sample" export:"/exp/g-sevilla.tsv" with
Id
startDate as "Date"
endDate
Control
Price

Dans le script ci-dessus, une fois les groupes établis, nous enregistrons les résultats dans un fichier intitulé `g-sevilla.tsv`. Nous vous expliquerons dans la section suivante l'utilité du préfixe 'g' (ou des autres préfixes) dans la prévention des recoupements d'échantillons. 'Sevilla' est simplement un exemple de nom d'expérience facile à mémoriser. Ce fichier est déjà dans un format qui vous permettra de le recharger dans Lokad par la suite. Vous devriez exécuter ce code une fois puis exclure les lignes qui commandent l'exportation du fichier en les commentant pour ne pas écraser le fichier existant. Puis, par mesure de sécurité, téléchargez ce fichier et sauvegardez-en une copie que vous rattachez à votre document de référence.

Plus tard pour éviter de définir des groupes qui ont des articles en commun avec d'autres expériences en cours, vous pouvez recharger le fichier et utiliser ses données pour exclure les articles concernés, avec le script suivant par exemple :

read "/exp/g-*" as Experiments // chargement de toutes les expériences réalisées jusqu'ici

today := Date(2014,7,9)
IsPartOfGroup = false
where Experiments.EndDate < today // toutes les expérience en cours sont exclues
  // recherche d'un groupe existant correspondant
  IsPartOfGroup = exists(Experiments.Date) 

where not IsPartOfGroup
  seed := "hello world"
  R = rankd(hash(concat(Id, seed)))
  Control = ""
  where R <= 1000
    // groupe positif
  where R > 1000 & R <= 2000
    // groupe négatif

6. Définition du nouveau script de pricing

Dans les sections précédentes, nous avons passé en revue plusieurs stratégies de pricing. À ce moment du protocole, il est temps de mettre en œuvre le script de détermination des nouveaux prix. Les détails de la logique de détermination des prix ne font pas l'objet du présent article, vous devez simplement savoir que, généralement, les prix peuvent être exportés à l'aide d'une simple vignette de type table :

read "/exp/g-sevilla.tsv" as Scope

// Le code de création des groupes de contrôle est mis en commentaire. 
// Les groupes de contrôles sont chargés à partir de la copie du fichier maintenue inchangée.
Control = last(Scope.Control) or ""

where Control != "" // exclusion des articles qui ne font pas partie du périmètre
  // Logique de pricing
  show table "sample" export:"/exp/p-sevilla.tsv" with Id, today() as Date, Price

Dans ce script, nous commençons par charger la copie des groupes de contrôle, puis, nous redéfinissons un périmètre limité à ces groupes de contrôle. Enfin, nous exportons un fichier qui contient les nouveaux prix. Dans la pratique, il peut s'avérer plus compliqué de garder les nouveaux prix inchangés que de le faire pour les groupes de contrôle. En effet, les prix évoluent en fonction de leur stratégie sous-jacente, pendant tout le temps de l'expérience.

7. Publication des prix et observation

Une fois le script en place et les nouveaux prix déterminés, ces derniers doivent être publiés sur tous vos canaux de vente. Nous vous recommandons d'opter, si possible, pour un processus de publication des prix automatisé. Lokad propose une interface de programmation REST qui est compatible avec le lancement automatique de projets. Lorsqu'un script termine son exécution, les fichiers de sortie peuvent être récupérés via FTP ou FTPS et importés dans vos systèmes de production.

Pour être confiant sur les observations effectuées une fois les prix revus, il est capital de vérifier que les prix affichés par tous les canaux de vente sont bien ceux déterminés par les scripts Envision. Nous constatons régulièrement des importations partielles ou qui comportent des erreurs et qui conduisent à des divergences entre les prix publiés et ceux établis par la stratégie de pricing. Dans l'idéal, l'historique des prix publiés devrait être renvoyé à Lokad. Lorsqu'une telle boucle de données est en place, la comparaison des prix publiés et des prix calculés par Lokad est possible, ainsi que la vérification de leur cohérence. Dans le script ci-dessous, nous chargeons l'historique des prix renvoyé par la production puis le périmètre de l'expérience et les prix calculés initialement.

//  ... articles sélectionnés et autres fichiers de données ...
read "/prices.tsv" as Prices // envoyé par les systèmes de production
read "/exp/g-sevilla.tsv" as Scope
read "/exp/p-sevilla.tsv" as ExpPrices

// Le code de création des groupes de contrôle est mis en commentaire. 
// Les groupes de contrôles sont chargés à partir de la copie du fichier maintenue inchangée.
Control = last(Scope.Control) or ""

where Control != "" // exclusion des articles qui ne font pas partie du périmètre
  // date de publication des prix
  when date <= date(2014,8,1) 
    where last(Prices.Price) != last(ExpPrices.Price)
      show table "Item count with price mismatch" with count(Id) 

Le script renvoie le nombre d'incohérences entre les prix fournis par la production et ceux générés par le script de pricing.

Enfin, après quelques jours ou semaines, en fonction de la durée de l'expérience, les observations de l'évolution des ventes dans les deux groupes peuvent être comparées pour déterminer si l'hypothèse de départ était la bonne. De nombreuses expériences concluantes sont un atout pour les commerçants qui peuvent utiliser ces informations pour concevoir des stratégies de pricing de plus en plus efficaces.