Google Analytics 4 – Collection de ressources

Comme vous le savez, Google Analytics 4 change complètement de paradigme, comparé à Universal Analytics. Il s’agit d’ailleurs en réalité du déploiement à grande échelle de la propriété que l’on retrouvait dans sa version bêta sous le nom de « Web + App ».

Aussi, au vu de la rupture à la fois technique, philosophique et fonctionnelle entre Universal Analytics et Google Analytics 4, le sujet mériterait largement d’y consacrer un livre entier et il n’est pas possible d’écrire un seul article pour traiter tout le sujet.

Désormais, le modèle de donnée est « event based » et l’arbitraire session est reléguée au second plan. Enfin, on peut accéder à la donnée brute en connectant sa propriété à Big Query. Jusqu’à présent ce dernier point n’était possible qu’avec GA 360. Ceci est une petite révolution.

Tout ceci impacte considérablement à la fois l’implémentation technique et l’exploitation des données dans Google Analytics.

Il existe déjà de nombreuses ressources que je vais accumuler ici. Cela permet d’avoir différents points de vue, conceptions et interprétations de la nouvelle philosophie « GA4 ».

De mon point de vue, Google tente avec GA4 de mieux coller aux besoins des data scientists et data analysts, avec un modèle de donnée plus flat, plus compréhensible, plus standard et beaucoup moins arbitraire quant à son agrégation et enrichissement des données brutes.

Ainsi, entre le modèle de données accessible via l’interface de Google Analytics et le modèle de données brut, la différence est moindre : il y a beaucoup moins de variables créées et calculées à partir de l’agrégation de la donnée de niveau hit qu’auparavant.

Ceci a de mon point de vue deux conséquences inéluctables :

  1. Rendre l’exploitation de la donnée plus simple pour un data scientist qui ne vient pas du web. Notamment grâce à la connexion de GA4 à Big Query.
  2. Rendre l’exploitation de la donnée plus complexe aux yeux d’un web analyst ou traffic manager sans background « data ». L’absence de certaines metrics et de certains rapports, l’apparition du « Analysis Hub » et l’intégration à Big Query peuvent être déroutants et masquer le fort potentiel de GA4.

N’hésitez pas à poser vos questions quelles qu’elles soient en commentaire, je m’efforcerai d’y répondre en complétant cet article. Soit via de nouvelles ressources, soit en complétant cette introduction, soit pourquoi pas via un nouvel article si des sujets intéressants sont soulevés 🙂

Avec les ressources ci-dessous, vous êtes armés d’une bonne base théorique pour prendre en main GA4, que vous soyez développeur ou utilisateur.

Implémentation de Google Analytics 4, par Simo Ahava : https://www.simoahava.com/analytics/implementation-guide-events-google-analytics-4/

Implémentation De Google Analytics 4 Ecommerce, par Simo Ahava : https://www.simoahava.com/analytics/google-analytics-4-ecommerce-guide-google-tag-manager/

Exploiter la connexion entre Big Query et une « web + app property » (article datant d’avant GA4) : https://www.simoahava.com/analytics/bigquery-query-guide-google-analytics-app-web/

Modéliser le concept de session à partir de la donnée GA4 importée dans Big Query : https://stuifbergen.com/2020/11/session-modeling-in-bigquery-sql-using-ga4-data-and-a-trip-to-paris/

Guide consacré à GA4 : https://ken-williams.com/

Documentation Google : implémentation de base : https://developers.google.com/analytics/devguides/collection/ga4

Documentation Google : implémentation Ecommerce : https://developers.google.com/tag-manager/ecommerce-ga4

Documentation Google : Events GA4 : https://support.google.com/analytics/answer/9322688?hl=en&ref_topic=9756175

Documentation Google : Events automatiquement collectés : https://support.google.com/analytics/answer/9234069

Documentation Google : noms d’events, de paramètres et de user properties réservés : https://developers.google.com/analytics/devguides/collection/protocol/ga4/reference?client_type=gtag

Documentation Google : Analysis Hub : https://support.google.com/analytics/answer/9327811?hl=en

Documentation Google : Data API : https://developers.google.com/analytics/devguides/reporting/data/v1

Créer de nouveaux events à partir des events existants, directement dans l’interface de Google Analytics : https://www.kristaseiden.com/creating-events-and-conversions-in-the-ga4-user-interface/

Modifier des events existants dans l’interface de Google Anaytics : https://www.kristaseiden.com/modifying-events-in-the-ga4-user-interface/

Définition d’une nouvelle audience (anciennement segment) : https://www.charlesfarina.com/audience-triggers-conversions-in-ga4/

Fonctionnement des sessions dans GA4 : https://www.qa2l.com/blog/211-google-analytics-4-exploring-sessions-with-debugview

Connecter GA4 à Big Query : https://online-metrics.com/ga4-bigquery/

Custom Dimensions dans GA4 : https://www.analyticsmania.com/post/a-guide-to-custom-dimensions-in-google-analytics-4/

Collecter de la donnée depuis les formulaires WordPress Contact Form 7

Le plugin le plus populaire pour intégrer des formulaires au sein d’un site WordPress est Contact Form 7. Comptant plus de cinq millions d’installations actives, son succès ne se dément pas.

En revanche, combien d’utilisateurs du plugin mesurent les envois via l’API proposé par le plugin lui-même ? Certainement beaucoup moins 🙂

Mauvaise méthode : Mesurer les envois via les clics sur le bouton depuis GTM

Si on souhaite mesurer les clics depuis un tag management system tel que GTM, la première idée va être de récupérer un sélecteur CSS sur le bouton d’envoi, pour tenter de catcher les clics générés sur celui-ci.

Je déconseille cette méthode pour plusieurs raisons, notamment car les CSS d’un site peuvent évoluer et il est toujours dangereux de rendre la collecte de données dépendante au front (HTML / CSS).

Bonne méthode : Mesurer les envois de manière fonctionnelle

La bonne méthode, de manière générale, est de tracker les boutons « critiques » en collaborant avec le développeur front-end du site web en question. L’idée va être d’envoyer l’événement que l’on souhaite récupérer via la fonction qui contrôle les actions du bouton.

Ainsi, la fonction qui renvoi un message à l’internaute du type « Merci pour votre envoi » doit être idéalement la même fonction qui renvoi vers votre container GTM un dataLayer.push() contenant les infos comme quoi un envoi vient d’être effectué et réussi.

Merci Contact Form 7

Contact Form 7 met à disposition des DOM events qui permettent justement de catcher les événements qui nous intéressent qui sont les suivants :

  • wpcf7invalid : soumission envoyée, mais erreur au sein du formulaire
  • wpcf7spam : soumission envoyée, mais email considéré comme un spam
  • wpcf7mailsent : soumission envoyée et email envoyé
  • wpcf7mailfailed : soumission envoyée mais email non envoyé
  • wpcf7submit : soumission envoyée, sans tenir compte de si l’email a été correctement envoyé ou non (il s’agit de mon point de vue de l’event le plus pertinent à utiliser dans une majorité de cas)

En plus des événements, Contact Form 7 met également à disposition plusieurs propriétés permettant de contextualiser l’événement telles que :

  • detail.contactFormId : l’ID du formulaire de contact
  • detail.pluginVersion : la version du plugin
  • detail.contactFormLocale : la locale (langue) du formulaire
  • detail.containerPostid : l’ID du post dans lequel le form est inclus

A partir de ces informations, il suffit de créer un listener JavaScript standard pour écouter et catcher l’événement souhaité, en l’occurrence la soumission de notre formulaire. Grâce aux propriétés embarquées au sein de l’événement, on peut connaître l’ID du formulaire soumis pour le comparer à l’ID du formulaire pour lequel on souhaite collecter de la donnée.

Ensuite, il suffit de réaliser un dataLayer.push() pour envoyer à GTM la donnée sous forme d’événement et de variables GTM. A noter que l’on peut embarquer ce code dans un tag GTM sous forme d’HTML personnalisé que l’on peut charger sur toutes les pages ou bien l’embarquer directement au sein de WordPress, à vous de voir.

Voici un exemple de code que l’on peut écrire pour envoyer à GTM un événement lorsque le formulaire ayant pour ID « 1234 » vient d’être remplis et soumis avec succès :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script>
    // Track the Contact Form 7 event
	document.addEventListener( 'wpcf7submit', function( event ) {
 
        // Check the form ID
	    if ( '1234' == event.detail.contactFormId ) {
 
            // If it's the right form, perform a dataLayer.push()
            dataLayer.push({
              'event':'userAction',
              'user_action_1': 'lead_form',
              'user_action_2': 'submission',
              'user_action_3': 'ok',
            });
 
        }
 
	}, false );
</script>

On voit ici qu’on peut facilement écouter l’événement, vérifier qu’il s’agit du formulaire qui nous intéresse et réaliser un dataLayer.push() pour en notifier GTM. Et tout ça sans être dépendant du front et sans devoir s’appuyer sur un sélecteur CSS, Jquery ou autre.

Il suffit ensuite de traiter la donnée pour l’envoyer là où vous le souhaitez, par exemple dans Google Analytics sous forme d’événement GA.

Note : vous trouverez la documentation officielle de Contact Form 7 concernant les événements DOM ici.

Retour sur ma formation de Data Analyst

Formation data analyst

J’ai terminé il y a quelques semaines ma formation de Data Analyst, formation née de la collaboration entre l’ENSAE et OpenClassrooms. Il s’agit d’un diplôme de niveau 6, ce qui est à cheval entre une L3 et un M1 d’un point de vue équivalence. Je ne vais pas revenir sur mon parcours m’ayant amené ici (déjà fait dans ce billet), mais simplement vous donner mon retour et présenter les différents projets.

Je sais que certaines personnes attendaient cet article. J’espère que cela pourra aider et répondre aux questions de ceux et celles qui hésitent à se lancer.

Edit : on m’a posé plusieurs fois la question concernant l’organisation et le temps passé. Mon objectif était de passer 20 heures par semaine sur la formation, que cela soit sur les cours ou bien sur les projets. Il faut savoir que certains projets demandaient beaucoup de temps de mise en oeuvre, d’autres demandaient plutôt une bonne maîtrise théorique avec une mise en oeuvre rapide. En fonction des projets je passais donc plus ou moins de temps sur la partie cours et/ou sur la partie pratique. Pour donner un ordre d’idée, mon rythme était grossomodo une validation de projet par mois en y consacrant 20 heures par semaine.

Points positifs

La formation est axée autour de projets à réaliser de A à Z, de la récupération des données jusqu’à la soutenance orale filmée. Parfois il s’agit de données fictives, mais la plus part des travaux sont basés sur des données réelles (FAO, Worldbank, RTE France…). Chaque projet est soutenu face caméra dans un temps imparti. Ceci permet d’appliquer quasiment immédiatement les connaissances acquises, de tester, de creuser et d’itérer entre théorie et application au quotidien. Enfin, cela oblige également à aiguiser son esprit de synthèse et de communication, puisque chaque soutenance doit être appuyée par une présentation sur slide et non par des fichiers techniques tels que des notebooks Jupyter.

Le second point pédagogique à retenir est qu’on est accompagné tout le long de sa formation par un mentor, qui est là pour vous aider, vous aiguiller, vous soutenir (Coucou Amaury :). Cela instaure au fil du temps une relation très particulière qu’on ne retrouve pas ailleurs. Formellement, il s’agit d’une visio-conférence hebdomadaire d’environ une heure. Si des difficultés majeures se présentent durant une phase de travail, on ne reste jamais longtemps dans le doute, sans réponse. Bien entendu, il est toujours possible d’échanger avec son mentor en dehors de la session officielle, bien que rien ne l’y oblige contractuellement.

Enfin, une fois officiellement étudiant, on a accès au Workplace d’OpenClassrooms, qui est le lieu de vie de la communauté. On y retrouve un groupe par formation, qui sont animés en permanence par les élèves, les mentors et l’équipe pédagogique puis des groupes plus informels pour inciter à créer du lien. C’est top pour échanger des conseils, des points de vue, des ressources, poser ses questions, etc. Pour ceux qui ne connaissent pas Workplace, il s’agit grossomodo d’un réseau Facebook privé.

Cette formation m’a apporté tout ce que je recherchais : des bases solides en statistiques et la possibilité de réaliser un stage en recherche (sur lequel je reviendrai dans un article dédié). Ayant un peu de background technique, c’était surtout la théorie que j’étais venu chercher, dans le but de continuer sur l’apprentissage du Machine Learning ensuite. C’est ce que je fais aujourd’hui en suivant un Master 2 en ligne en collaboration avec CentraleSupelec et OpenClassrooms.

Il y a un point dont je discutais avec Luc Bertrand (le directeur pédagogique de la branche data chez OpenClassrooms) : il est très difficile de définir ce qu’est un data analyst, que cela soit d’un point de vue académique : quelles connaissances doit-on acquérir ? Ou bien d’un point de vue marché du travail : quelles sont les compétences attendues par l’employeur recherchant un data analyst ?

OpenClassrooms a fait de mon point de vue le bon choix. A savoir enseigner les bases théoriques et techniques des statistiques pour permettre à l’élève d’aller ensuite dans la direction qu’il souhaite : vers encore plus de technique ou de théorie. Vers du Business Intelligence ou vers de la data science. Les différents projets permettent d’acquérir des compétences et une ouverture d’esprit qui seront utiles quelle que soit la suite envisagée.

De mon côté, j’ai appréhendé cette formation comme un tremplin vers la data science et le machine learning. Et en ce sens, je n’ai pas été déçu. Cela a demandé beaucoup d’efforts d’apprentissage allant au delà du minimum requis pour valider les différents projets. Notamment en allant chercher quotidiennement des ressources externes – généralement universitaires – pour comprendre et saisir l’intuition, les concepts et le raisonnement mathématique rencontrés au fil des projets. Mais que cela fut passionnant !

Points négatifs

Ces derniers sont très subjectifs et révèlent plutôt les points que j’aurais aimé être différents, dans la vision qui est la mienne. A savoir celle d’aborder cette année comme une année préparatoire vers de la théorie plus avancée.

Je dirais que la principale frustration a été l’absence de pratique de l’algèbre linéaire au sein des projets. Dans le sens où on ne réalise quasiment aucun calcul matriciel / vectoriel, car on implémente pas d’algorithmes à la main. Ce n’est pas le but initial de cette formation, mais cela reste indispensable quand l’on souhaite étudier ou travailler dans le domaine de l’analyse de données.

Il y a d’ailleurs parfois un choc culturel entre certains cours de l’ENSAE qui peuvent être très théoriques, où l’on admet que l’élève est à l’aise avec l’algèbre linéaire et la lecture d’équations mathématiques relativement avancées et la réalité des projets souvent très applicatifs ne nécessitant pas forcément de compétences théoriques pour être menés à bien.

Pour ma part j’ai beaucoup aimé ces quelques cours, mais ils sont souvent très denses et à la fois trop synthétiques. Il faut les considérer comme un appel à aller chercher d’autres ressources. C’était parfois seulement après plusieurs heures voire plusieurs journées de travail que le cours initial rattaché au projet me paraissait clair. Sans bagages mathématiques post-bac, les cours ne se suffisent donc pas à eux-même. De plus, leur compréhension n’étant la plus part du temps pas nécessaires dans la réussite des projets, on peut aisément imaginer qu’ils passent à la trappe pour bon nombre d’élèves.

Présentation des projets

Pour vous faire une meilleur idée de ce qui vous attend concrètement durant cette formation, je présente ici les principaux projets autour desquels la forme s’articule.

Réalisez une étude de santé publique

Ce projet est vraiment génial, car il plonge de suite dans la réalité du terrain : à savoir qu’il faut comprendre ses données, avant de pouvoir les traiter. La connaissance métier est souvent tout aussi importante que les compétences techniques. Le but du projet est d’analyser des données provenant de la FAO (Food and Agriculture Organization) qui est l’organisme rattaché à l’ONU ayant pour ambition de faire disparaître la faim dans le monde.

Données de la FAO

Ici, on apprend à récupérer des données puis à les traiter avec Python / Pandas et SQL. Toutes les bases du traitement de données sont passées en revue (import, nettoyage, sélection / regroupement / agrégation)

En plus de permettre de mieux comprendre un sujet si primordial, à savoir la faim dans le monde, on prend également conscience qu’avec un petit peu de manipulation et de technique, on peut déjà faire parler ses données, sans même aborder de concepts statistiques à proprement parler.

Il faudra compter une centaine d’heures de travail sur ce projet. Peut-être plus si vous n’avez jamais codé en Python, ni fait de SQL au paravant. Les livrables attendus seront une analyse exploratoire permettant de mettre en évidence les causes de la faim dans le monde et de rejeter certains aprioris.

Mon repository GitHub de mon projet

Analysez les ventes de votre entreprise

Ici, on ne réalise plus simplement un traitement de données disons basique, mais bel et bien une analyse statistique exploratoire. On répondra aux questions suivantes : Qu’est-ce qu’une analyse univariée ? Bivariée ? Qu’est-ce qu’une distribution d’une variable statistique ? Comment la caractériser ?

Les cours rattachés aux projets, majoritairement réalisées par Nicolas Rangeon, sont vraiment géniaux. Ils permettent de découvrir les statistiques de manière pédagogique et intuitive. Je dirais qu’on est sur un niveau à cheval entre une Terminale S et un début post-bac. Parmi les concepts qui vont être appris puis appliqués en Python, on peut citer :

  • Calcul d’une moyenne, d’une variance, d’une médiane, des quantiles
  • Calcul des indicateurs de dispersion : Skewness / Kurtosis
  • Analyse de concentration : indice de Gini, courbe de Lorenz
  • Construction et représentation graphique : boxplot (boîte à moustache), histogramme, séries temporelles
  • Analyse bivariée : coefficient de corrélation, régression linéaire, ANOVA.

Ce projet fait également office d’introduction à Matplotlib, la librairie la plus populaire pour la visualisation de donnés en Python. Il demandera une cinquantaine d’heures de travail, voire plus. Les livrables seront une analyse exploratoire statistique permettant d’avoir une vision claire du business de l’entreprise fictive.

Mon repository GitHub du projet

Produisez une étude de marché

Le but principal du projet est de comprendre ce qu’est une ACP (Analyse en composantes principales) ou plus couramment une PCA en anglais (Principal Components Analysis).

L’entreprise pour laquelle on travaille est fictive, il s’agit d’une entreprise agro-alimentaire spécialisée dans le poulet. En revanche, les données utilisées pour réaliser l’étude sont bien réelles puisqu’il s’agit à nouveau des données issues de la FAO.

Là aussi la partie théorique est enseignée par Nicolas Rangeon, qui prend le temps de vraiment décrire l’intuition et le mécanisme d’une PCA. Ne seront pas abordées les notions de diagonalisation de matrice, ni le calcul à proprement parler des vecteurs propres et des valeurs propres. Mais finalement cela n’est pas forcément utile pour comprendre le principe, l’utilité et l’intuition d’une PCA. Si l’on a compris qu’il s’agit de prendre dans ses données les axes ayant le plus d’inertie et de projeter les données sur ces axes, c’est déjà pas mal 🙂

D’autres fondamentaux statistiques sont également abordés. Cette fois-ci il ne s’agit plus uniquement d’analyse exploratoire mais aussi de statistiques inférentielles. On peut notamment citer :

  • Découverte des tests statistiques (tester une moyenne, une variance, test d’adéquation à une loi)
  • La comparaison de deux échantillons
  • La réduction de dimensions via une PCA
  • Clustering des données via l’algorithme k-means

Suite à l’analyse exploratoire, on doit déterminer quels sont les pays à cibler en priorité pour développer l’entreprise à l’international. Il faut compter une petite centaine d’heures pour réaliser ce projet. Ceci allant de la récupération des données, traitement, analyse, tests statistiques et conclusion.

Mon repository GitHub du projet

Détectez des faux billets

Le but pédagogique de ce projet est double :

1) Interpréter de manière un peu plus approfondie le résultat d’une PCA, notamment l’éboulis des valeurs propres (eigenvalues scree plot en anglais) et surtout le cercle des corrélations.

2) Découvrir un premier algorithme de classement supervisé linéaire, la régression logistique 🙂 Le cours rattaché au projet aborde la méthode des moindres carrés ordinaires (Ordinary least squares en anglais), la régression linéaire, la régression logistique et l’analyse de la variance. Les cours sont relativement théoriques et risquent parfois de perdre l’élève car il y a peu de détail et de contexte. Par exemple on y retrouve l’écriture matricielle explicite des paramètres d’une régression linéaire (appelée l’équation normale) mais sans explication ni démonstration. Cela aurait mérité un peu de justification, qui est intéressante et simple à comprendre. Car il s’agit simplement de minimiser la fonction de coût sous sa forme matricielle, en regardant sa dérivée en zéro. On obtient ainsi explicitement le vecteur contenant tous les paramètres.

Pour ceux que cela intéresse, voici une petite démonstration (sans le détail des calculs des dérivées) par ici.

Quand on n’a encore jamais fait de machine learning, ce projet est plaisant car il permet de voir comment un modèle mathématique simple (qui sous-tend ceci étant dit encore aujourd’hui beaucoup d’algorithmes plus complexes) permet déjà d’obtenir d’excellents résultats en terme de prédiction.

Cette fois-ci, le livrable attendu est un programme en Python auquel on soumet les caractéristiques d’un ou plusieurs billets sous forme de fichier CSV et qui donne en sortie pour chaque billet s’il s’agit d’un vrai ou non. On est donc ici dans les fondamentaux du Machine Learning. Avant de présenter le programme, il faudra présenter l’analyse exploratoire réalisée qui permet de justifier la construction du modèle.

Mon Repository GitHub du projet

Effectuez une prédiction de revenus

Ce projet est très particulier. Il fait appel à diverses méthodes statistiques et probabilistes permettant de générer un jeu de données enrichi, tant en termes de variables que d’individus. L’approche est plutôt bayesienne, bien que le terme n’est jamais employé. Ce qui est dommage, c’est que l’on est guidés dans la démarche sans vraiment d’explication. Un cours sur les probabilités est néanmoins rattaché au projet.

Démarche du projet :

A partir de classes de population de plusieurs pays, l’on va générer des individus et leur attribuer une « classe parents » correspondant aux revenus de leurs parents.Pour cela, on va suivre la méthode suivante :

  1. Générer de faux parents dont les revenus sont distribués selon une loi normale
  2. A partir du coefficient d’élasticité propre à chaque pays, on va attribuer une classe enfant à chaque parent. Cela permet ensuite de calculer les différentes probabilités conditionnelles, à savoir combien de chance a-t-on d’avoir un parent de telle classe quand l’enfant appartient à telle classe.
  3. Ensuite, à partir du jeu de données initial, pour chaque pays on duplique chaque classe de revenus plusieurs centaines de fois pour pouvoir ventiler les différentes probabilités conditionnelles et ainsi avoir un échantillon représentatif.

Notre jeu de données et désormais enrichi de centaines d’individus plutôt qu’un seul individu par classe ainsi que d’une feature supplémentaire « classe parents ». A partir de ce jeu de données enrichi, on va entraîner une régression linéaire pour prédire le revenu de chaque individu.

Enfin, on va analyser finement notre régression linéaire :

  1. Comprendre l’influence de chaque variable endogène
  2. Juger de la pertinence du modèle, notamment via l’analyse des résidus de la régression linéaire

Le livrable attendu sera le modèle de régression linéaire permettant de prédire les revenus ainsi que l’analyse du modèle permettant de conclure sur l’impact propre de chaque variable.

Mon repository GitHub du projet

Prédisez la demande en électricité

Ce projet est peut-être celui qui demande le plus d’efforts en terme d’investissement intellectuel car ici il ne sera pas possible de sélectionner correctement les hyper-paramètres du modèle de prédiction sans comprendre le mécanisme mathématique derrière. Tout le travail est centré atour de l’analyse et de la modélisation de séries temporelles. Les séries temporelles sont un sujet vaste et complexe. On a donc vite fait de se perdre dans cette jungle théorique où les approches sont diverses et variées.

Bien entendu, si l’on souhaite décrire ce que l’on voit ou analyser une série temporelle a posteriori ou bien encore prédire l’avenir de cette série, ce ne sont pas les mêmes outils. Le projet est principalement basé sur la prédiction (mais pas que), notamment à l’aide des modèles basés sur des méthodes stochastiques où l’on considère la série temporelle comme la réalisation d’une variable aléatoire.

Les modèles les plus connus sont les modèles ARMA et toutes ses variantes (ARIMA / SARIMA…). Certains de ces modèles comptent de nombreux hyper-paramètres et il n’est pas toujours facile de saisir l’intuition qui se cache derrière chacun d’entre-eux. C’est à mon avis le plus gros challenge de ce projet.

Pour ma part, en plus d’avoir passé beaucoup de temps à comprendre ces modèles, j’en ai aussi profité pour écrire ma propre fonction de grid-search car les méthodes classiques de cross-validation que l’on utilise en machine learning ne sont pas forcément les plus pertinentes ici.

Ici, le livrable attendu est la présentation du modèle utilisé (modèle, choix des hyper-paramètres, etc.) ainsi qu’une prévision des données sur une année.

Voici un excellent article à ce propos et le lien vers mon repository GitHub du projet.

Conclusion

Cette formation a tout changé pour moi. Elle a complètement chamboulé mes perspectives et m’a permis de révéler mon goût prononcé pour les mathématiques. J’ai pu découvrir les statistiques, les bases du machine learning, faire un stage en recherche.

Bien entendu le format ne correspondra peut-être pas à tout le monde. De plus le contenu et les projets vont continuer d’évoluer, donc ne vous fiez pas uniquement à ce que j’ai pu décrire ici. Enfin, peut-être que certains trouveront la formation trop théorique, d’autres au contraire pas assez.

Pour ma part j’aime beaucoup le choix qu’a fait OpenClassrooms d’orienter la formation vers des projets qui posent les fondamentaux de la data science et de l’analyse statistique plutôt que vers la préparation à un travail d’expert BI, même si la mise en pratique de la théorie pure est parfois absente. Cela aurait été par exemple intéressant d’implémenter une PCA ou un algorithme de régression à la main.

Je rédigerai d’autres articles bientôt pour parler de mon stage réalisé durant la formation, des cours en ligne hors OpenClassrooms qui me permettent de progresser encore aujourd’hui (je pense principalement aux cours d’Andrew Ng <3) et enfin pour parler de mon Master en ligne CentraleSupelec / OpenClassrooms que je viens de commencer 🙂

Pour toutes questions / retours, n’hésitez pas à commenter, à m’envoyer un email ou à me contacter sur Twitter / LinkedIn.

Réaliser un test d’indépendance Chi2 en Python avec scipy.stats

Test d’indépendance Khi2

Ici, je vais montrer comment réaliser un test du Chi2 avec deux variables qualitatives grâce à scipy.stats.chi2_contingency

Analalyse exploratoire

En introduction, j’aimerais vous renvoyer vers l’excellent cours de Nicolas Rangeon qui explique les étapes suivantes :

A partir de deux variables qualitatives, comment :

  1. Construire un tableau de contingence (matrice des valeurs observées)
  2. Construire la matrice des fréquences attendues grâce aux sommes marginales
  3. Construire la matrice des écarts au carré normalisés
  4. Transformer cette dernière matrice en heatmap grâce à seaborn

Il s’agit donc d’une analyse exploratoire permettant de :

  1. Comprendre comment est calculée la statistique khi-2
  2. Mettre en avant les fortes corrélations pour certaines valeurs de nos deux variables.

Test statistique

Bien ! Passons désormais au test d’indépendance pour savoir si nos deux variables sont corrélées ou non. Avant cela, quelques remarques sur la première partie :

La somme totale des valeurs de la matrice de la troisième étape suit une loi du khi-2 à k degrés de liberté. D’après la documentation de SciPy, voici comment est calculé le nombre k :

1
k = observed.size - sum(observed.shape) + observed.ndim - 1

Où observed est le tableau de contingence (matrice de la première étape).

Ici, scipy va (presque) tout faire pour nous. Nous allons nous contenter de réaliser l’étape n°1 de la première partie, à savoir la construction du tableau de contingence. Une fois cette matrice obtenue, scipy va faire le travail.

Les données

Je me contente de reprendre l’exemple utilisé par Nicolas Rangeon dans le cours linké dans la première partie. Il s’agit d’une liste d’individus, pour lesquels on connait deux informations :

Dans quel bar ils ont consommé (nom du bar)
Quelle boisson ont-ils consommé dans ce bar (Café, Thé ou autre).

Voici le code que j’ai écrit pour générer le jeu de données :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
X = ["Chez Luc"]*10
X.extend(["Au café Dembas"]*20)
X.extend(["Au café Ducoing"]*40)
X.extend(["Chez Sarah"]*30)
 
Y = ["Café"]*1
Y.extend(["Thé"]*9)
Y.extend(["Autre"]*0)
 
Y.extend(["Café"]*9)
Y.extend(["Thé"]*6)
Y.extend(["Autre"]*5)
 
Y.extend(["Café"]*20)
Y.extend(["Thé"]*10)
Y.extend(["Autre"]*10)
 
Y.extend(["Café"]*20)
Y.extend(["Thé"]*5)
Y.extend(["Autre"]*5)
 
data = {
    'bar':X,
    'boisson':Y
}
df = pd.DataFrame(data)

Voici le .head() obtenu :

L’idée est simplement d’avoir deux listes de valeurs qualitatives. Chaque ligne doit correspondre à un couple de valeurs.

Générer le tableau de contingence

Ici, on reprend la méthode utilisée dans l’analyse exploratoire (première partie), à savoir :

1
2
3
X = "bar"
Y = "boisson"
cont = df[[X, Y]].pivot_table(index=X, columns=Y, aggfunc=len).fillna(0).copy().astype(int)

En fait c’est très simple, on utilise la méthode pivot_table pour obtenir notre tableau de contingence. J’en profite au passage pour remplacer les valeurs nulles par des zéro, je crée une copie du dataframe original et je m’assure de tout convertir en int.

Et c’est tout ce qu’on a à faire ! Dans la première partie, à ce stade on calcule les sommes marginales grâce à la méthode value_counts(), mais ici pas besoin. Notre matrice des valeurs observées est prête, on a plus qu’à la soumettre à scipy.stats.chi2_contingency. Voici à quoi elle resemble dans notre cas :

Calcul de la p-value

En une ligne, le tour est joué :

1
st_chi2, st_p, st_dof, st_exp = st.chi2_contingency(cont)

Voici les valeurs récupérées :

1
2
3
4
5
6
7
8
# Statistique khi2, calculée à la main dans la première partie
st_chi2 = 21.99
 
# Nombe de degrés de liberté
st_dof = 6
 
# Pvalue : l'unique valeur nécessaire pour prendre notre décision
st_p = 0.00121

On récupère également dans st_exp le tableau des fréquences attendues, que l’on calcule manuellement dans la première partie.

Ce qui nous intéresse ici, c’est la variable st_p, qui contient la pvalue. Celle-ci est calculée par scipy de la manière suivante :

  1. Calcul de la stat khi2
  2. Calcul du nombre de degrés de liberté k
  3. Calcul de la loi à densité suivie par une loi khi2 à k degrés de liberté
  4. Confrontation de la stat khi2 calculée avec la loi à densité obtenue

L’hypothèse nulle est que les variables sont indépendantes. La p-valeur nous indique quelle probabilité (matérialisée par l’aire sous la courbe de la loi à densité) représente les valeurs encore plus éloignées que celle obtenue.

Test au seuil de 1%

Rejetons l’hypothèse nulle au seuil de 1%, donc pour une pvaleur inférieure à 0.01.

Dans notre cas, la pvaleur obtenue par notre échantillon est de 0.00121, ce qui est en dessous du seuil fixé. On peut donc rejeter l’hypothèse nulle. Les variables « nom du bar » et « boisson consommée » ne sont pas indépendantes. Ceci confirme ce qu’on aurait pu intuitivement deviner dans notre cas, juste avec l’analyse exploratoire.

Voici un notebook sur lequel vous trouverez l’ensemble du code :Test-du-khi2

Devenir Data Scientist : travail préparatoire en 500 heures

Devenir data scientist

Tout d’abord, un petit disclaimer : cet article s’adresse aux personnes sans background scientifique désireuses de reprendre des études et/ou d’entamer une reconversion autour des métiers de la data science. Si vous avez fait une prépa MPSI / PCSI ou bien une licence de maths, ce que je vais vous raconter, vous le savez certainement déjà.

Si vous êtes développeur ou si vous avez un profil multi-casquettes et que vous êtes à l’aise avec le web et son histoire, c’est bien. Il y aura d’autant plus de chances que cet article vous intéresse. Car c’est plus ou moins mon profil.

Dans ce billet je décris comment je m’y suis pris pour retrouver de bonnes bases pour être prêt à apprendre. C’est tout. Néanmoins, il s’agit d’une synthèse d’un travail personnel de plusieurs semaines. Il y a donc beaucoup de matière, que j’ai tenté de rendre la plus digeste possible. Le but final de ce travail préparatoire était de me sentir prêt pour attaquer cette formation.

Enfin, sachez que j’ai la fâcheuse habitude de « time reporter » le temps passé derrière mon bureau. Ceci est pratique pour facturer les clients au plus juste. Mais également pour mesurer le temps passé à apprendre tel ou tel sujet. Ce programme aura occupé environ 500 heures de mon temps. Je ne détaille pas tout dans cet article, mais si cela vous intéresse d’avoir plus d’informations sur la répartition du temps passé par sujet, n’hésitez pas à me le demander.

Sommaire

  1. Contexte
  2. Les fondamentaux des mathématiques
  3. Python et ses librairies phares avec Martin Daniel
  4. Les MOOcs : technique vs data science
  5. MOOCs OpenClassrooms orientés données / statistiques
  6. Se (re)faire une base en développement back-end
  7. Quelques MOOCs supplémentaires
  8. Conclusion

Contexte

Je fais du web depuis une dizaine d’années et je suis aujourd’hui consultant Analytics. Grossomodo, je connais plutôt bien les modèles de données que l’on retrouve en web analyse, principalement avec Google Analytics. Je sais manipuler ces données avec différents outils (Excel, Python, JavaScript) et je sais faire de jolis dashboards avec Data Studio. On fait également appel à moi pour concevoir des plans de marquage et en suivre l’implémentation technique en accompagnant les développeurs. Enfin, j’apporte ma connaissance métier sur l’analyse des chiffres remontés par tout ce joli monde.

Honnêtement ? Le marché est pléthorique. La demande est énorme. Au moins aussi importante qu’en data science. Sauf qu’aujourd’hui, j’ai envie de voir autre chose que du web. Et pour cela, il faut des connaissances scientifiques et mathématiques. Donc aujourd’hui, j’ai un besoin et une envie incommensurable d’acquérir de nouvelles connaissances. De les structurer. J’ai envie d’apprendre des bases universelles qui m’ouvriront les portes d’un nouveau monde. Celui dans lequel je pourrai travailler dans l’environnement, la santé, l’innovation.

Bref, je souhaite me reconvertir. Le mot est peut-être un peu fort. Car souvent quand on entend « reconversion », on imagine le cadre parisien trentenaire qui a fait une grande école de commerce, travaille dans le conseil dans une tour à La Défense et plaque tout pour ouvrir un Food Truck sur les côtes normandes. Ok j’ai moi-même travaillé dans une tour à La Défense. Mais la ressemblance s’arrête là, car je souhaite pour l’instant continuer à travailler avec de la donnée, derrière mon ordinateur 🤓

On a la chance immense d’être dans une époque où retourner sur les bancs de l’école n’est pas mal vu, quel que soit son âge. Le mot « reconversion » est dans toutes les bouches. Alors si vous y songez, un conseil : foncez. Il n’est jamais trop tard.

(Ré)apprendre les fondamentaux des mathématiques (200 heures)

Le piège en data science est qu’il existe des librairies super bien faites aujourd’hui. Ces librairies permettent de réaliser des analyses puissantes sans vraiment comprendre ce qu’il se passe sous le capot. Mais c’est à mon sens très dangereux. Tous les algorithmes que l’on peut facilement utiliser en quelques lignes de Python sont sous-tendus par des concepts mathématiques. On ne peut donc pas les ignorer.

Les fondamentaux appris au lycée sont une base indispensable. Je pense principalement aux statistiques, aux probabilités et aux intégrales. Mais en réalité, tout ce qu’on apprend durant les deux années de 1ère et Tle S est imbriqué. Même si certains mathématiciens reprochent au programme d’aborder trop de sujets différents durant ces deux année et de ne pas aller assez en profondeur.

Il est vrai qu’on peut facilement passer à côté de la beauté et de la puissance de certains outils et concepts, surtout dans un contexte de lycée. Mais le fait est qu’on ne peut que constater que ces bases sont indispensables et incroyablement liées les unes aux autres.

C’est la raison pour laquelle j’ai décidé de reprendre entièrement le programme de 1ère S et de terminale S. Pour cela j’ai articulé mon travail autour de trois supports :

1. Yvan Monka

N’allons pas par quatre chemins : qu’aurais-je fait sans lui ? Pas grand chose. Yvan est prof de maths en lycée et il anime une chaîne YouTube qui est tout bonnement extraordinaire.

Sa pédagogie frôle la perfection, ses vidéos sont reconnaissables à la petite musique d’intro (jouée par sa fille) et à son « Bonjour ! » plein d’entrain. Yvan est d’ailleurs déjà très populaire auprès des jeunes lycéens qui ne cessent de le remercier dans les commentaires de ses vidéos.

Sa chaîne balaye entièrement tout le programme des mathématiques enseignées au collège et au lycée en France. Les vidéos sont rangées par playlists et par catégories de playlists. Voici les deux catégories que je vous conseille de suivre :

Catégorie Première S : ici
Catégorie Terminale S : ici

Cerise sur le gâteau, Yvan reverse l’intégralité des fonds générés avec sa chaîne aux Restos du Coeur. Encore merci à ce grand monsieur 🙂

Yvan Monka édite également un site web.

2. Les bouquins Kartable

Kartable.fr est un site proposant des aides à la révision dans toutes les matières du collège et du lycée. Le supports sont sous forme de fiches de cours, de méthodes et d’exercices.

J’ai opté pour ma part pour la version papier. J’ai donc acheté le bouquin de 1ère S et de Terminale S.

Ceci a structuré ma manière d’apprendre, car les bouquins sont complets. Ils sont découpés en plusieurs chapitres, les mêmes qu’on retrouve au programme. Chaque chapitre contient un cours, des méthodes et des exercices corrigés.

3. Lucien, mon prof de maths particulier

Bien que l’on se soit vus une petite dizaine d’heures tout au plus, je n’aurais pas pu avancer autant sans lui. Tout simplement car reprendre les maths après plus de dix ans, cela fait bizarre 🙂 Si vous habitez Paris, je peux vous communiquer en privé ses coordonnées (sur son accord préalable bien entendu). Astrophysicien de formation, Lucien m’a vraiment aidé à comprendre les maths sous un angle plus conceptuel, il m’a challengé, m’a permis de prendre confiance en moi.

Pour vous donner une idée, son état d’esprit c’est « Ben regarde, c’est facile, tu fais ça et ça, bim c’est terminé. Et pourquoi on a inventé ça ? Ben parce que cela sert à ceci. Et en combinant avec ça, on obtient ça, et voilà ! »

Méthode de travail

Mon workflow était grossomodo le suivant :

  1. Lorsque je décidais quel chapitre j’allais travailler, je commençais par feuilleter le cours et les méthodes du bouquin.
  2. Ensuite je travaillais entièrement le chapitre grâce à la playlist dédiée sur la chaîne d’Yvan Monka. Elles sont également structurées en cours / méthodes / exercices. A noter qu’en fonction des chapitres on ne retrouve pas systématiquement des vidéos de cours ou d’exercices.
  3. Enfin, je réalisais les exercices de fin de chapitre proposés dans mon bouquin Kartable.
  4. Si j’avais des questions, des doutes ou si quelque chose n’était pas clair, j’en discutai ensuite avec Lucien.

Programme Mathématiques 1ère S et Tle S

J’ai mis en gras les thèmes qui me semblent indispensables, même si c’est presque impossible de dissocier les chapitres les uns des autres.

Première S

Les trinômes du second degré
Généralités sur les fonctions
Les fonctions de référence
La dérivation
Les suites (géométriques et arithmétiques)
La trigonométrie
Les vecteurs
Les équations de droite
Le produit scalaire
Les statistiques
Les probabilités
La loi binomiale et les fluctuations d’échantillonnage

Terminale S

Les suites (étude d’une suite, raisonnement par récurrence)
Les limites de fonction
La dérivation
La continuité
La fonction exponentielle
La fonction logarithme népérien
Etudes de fonctions et fonctions trigonométriques
Les primitives
Les intégrales
Les nombres complexes
La géométrie dans l’espace
Les lois de probabilités discrètes
Les lois à densité
Intervalle de fluctuation et estimation
La divisibilité et congruence (spé maths)
Le PGCD, les théorèmes de Bézout et Gauss, résolution d’équation de type ax + by = 1 (spé maths)
Les nombres premiers (spé maths)
Les matrices et suites de matrices (spé maths)

Pour conclure, si je devais m’efforcer de donner des priorités, je dirais :

  • Les suites. Car on en rencontre souvent dans la vraie vie et qu’elles sont fondamentales dans la réflexion algorithmique.
  • Les statistiques et probabilités pour des raisons évidentes. Dans la vraie vie lycéenne, les profs s’y attardent peu. Mais le programme est vraiment bien : on y voit les notions de base telles que l’analyse univariée, la loi binomiale, les intervalles de confiance et de fluctuation, le théorème de Moivre-Laplace, les lois de probabilité discrètes et les lois à densité
  • Les intégrales : indispensables pour calculer des probabilités sur des lois à densité.
  • Les matrices : là aussi il s’agit d’un outil incontournable, puisqu’il s’agit de tableaux de nombres. Elles sont un outil central en algèbre linéaire.

Les MOOCs : technique vs data science

En parallèle des maths, j’ai consacré une grande partie de mon temps à suivre des MOOCs, principalement chez OpenClassrooms. Dans ma vision des choses, je les ai classés en deux grandes catégories : ceux consacrés à la technique et ceux consacrés à la data science.

Même si la frontière est parfois mince, ce que je considère dédié à la technique est tout ce qui touche au développement, sans mettre en jeu de dimension mathématique. Cela peut être par exemple l’apprentissage d’un langage de programmation comme Python ou C++, apprendre à administrer un serveur SQL. Ou bien encore apprendre à déployer un serveur web sur GCP ou AWS, savoir comment fonctionne une API-Rest, infogérer un serveur dédié chez OVH ou que sais-je encore. En fonction du métier, certaines de ces compétences pourront ne jamais servir ou à l’inverse devenir centrales. Le fait est que cela reste à mon avis des bases incontournables.

Puis, il y a les compétences propres au data scientist. Si l’on travaille avec Python, cela va être d’apprendre entre autres Numpy, Pandas et Matplotlib. Travailler avec des notebooks Jupyter. Savoir importer, nettoyer, analyser un jeu de données. Ensuite d’autres compétences viennent se greffer, mais qui dépassent de mon point de vue le stade des bases fondamentales.

Découvrir Python et ses librairies phares avec Martin Daniel et Le Wagon

Quand on pense data science, on pense souvent Python. Et on pense aussi souvent Pandas. Cette librairie permet à Python de « concurrencer » R puisqu’elle apporte un nouvel objet qu’on retrouve nativement dans R, nommé « dataframe ». Cet objet permet de modéliser une table relationnelle.

Son créateur, Wes McKinney, a écrit un premier bouquin en 2012 « Python for Data Analysis ». Il permet de découvrir le monde de la data science avec Python. Principalement le data wrangling, la lecture, le nettoyage et la visualisation de données.

Ce bouquin a grandement inspiré Martin Daniel (data scientist chez Airbnb), qui a créé un MOOC en plusieurs vidéos. C’est avec ces vidéos que j’ai découvert Pandas il y a plus d’un an. Ici on va droit au but et très rapidement on comprend la puissance de ces outils.

Voici le lien de la formation : ici 🙂

Attention en revanche, ici tout est réalisé en Python 2. Plus les mois passent et plus les vidéos vont devenir obsolètes, car Pandas évolue aussi. Mais je les recommande quand même chaudement, car en une petite dizaine d’heures vous aurez un overview de ce qu’il est possible de faire.

Je vous conseille d’avoir déjà des notions de base en Python et d’avoir déjà manipulé des données SQL pour être à l’aise dès le début.

A noter qu’en septembre 2017, Wes McKinney a sorti une nouvelle édition de son bouquin. Cette fois-ci celui-ci est basé sur Python 3.

MOOCs OpenClassrooms orientés données / statistiques

Initiez-vous à l’algèbre relationnelle avec le langage SQL : Permet de (re)découvrir le langage SQL sous un autre angle. A savoir sous un angle agnostique, où l’on oublie le langage spécifique SQL pour mettre à la place des mots sur des concepts. Je recommande chaudement 🙂

Décrivez et nettoyez votre jeu de données : Permet d’apprendre les bases des statistiques : vocabulaire, analyse univariée et analyse bivariée. Je vous conseille d’avoir déjà un niveau de terminale S avant de l’attaquer pour ne pas découvrir les bases des statistiques de but en blanc ici. Bien que cela puisse marcher 🙂

Initiez-vous à la statistique inférentielle : Permet de découvrir les bases des différentes outils rencontrés en statistiques inférentielles : les estimateurs, les intervalles de confiance et les tests permettant de rejeter ou valider une hypothèse. Ici, tout est illustré avec R et non Python.

Découvrez les librairies Python pour la Data Sience : Un peu dans le même esprit que le MOOC de Martin Daniel, vous découvrirez ici en quelques heures tous les fondamentaux : Python, Numpy, Pandas, Scikit-Learn, Jupyter-Notebook.

Se (re)faire une base en développement back-end

Il s’agit toujours de MOOCs OpenClassrooms. Mais ceux-là ne sont rattachés à aucun parcours. Ils sont donc plus complets car sont censés se suffir à eux-même. Et ils sont aussi plus difficiles. Ils ont l’avantage de proposer des activités de haut niveau qui vous demanderont une certaine implication. Si vous partez de zéro sur ces sujets, vous pouvez prévoir 120 heures de travail à minima, si vous creusez un peu et faites les choses bien 🙂 Ceci est valable pour le second et le troisième, le premier étant une introduction à Git / Github réalisable en une journée.

Gérez votre code avec Git et Github : Vous découvrirez en quelques heures l’essentiel à savoir pour commencer à utiliser Git et Github dans vos projets.

Apprenez à programmer en Python Ici, le but est d’apprendre Python pour réaliser du développement logiciel. On n’y parle pas de Pandas ni de Jupyter-Notebook. En revanche on y apprend la programmation orientée objet, la philosophie Python, on découvre une partie de sa librairie standard. Cela reste aujourd’hui pour moi le meilleur support francophone pour découvrir Python. Si vous réalisez toutes les activités et que vous prenez du temps pour creuser certains sujets, comptez à minima 70 heures de travail.

Administrez vos bases de données avec MySQL Ici aussi, l’apprentissage est orienté développeur. Le fait est que c’est la ressource la plus complète que j’ai pu trouver sur le sujet. Les activités sont super intéressantes et ne concernent pas uniquement la partie utilisateur (requêtes). On y apprend aussi la partie administration (vues, triggers, procédures stockées, etc). Ceci permet à la sortie d’avoir un bel overview. Comptez à minima 50 heures de travail pour réaliser le MOOC entièrement.

Vous pouvez également suivre les MOOCs Python rattachés au parcours « Développeur d’application Python« . L’approche est complètement différente.

Au final, vous pouvez compter 200 heures sur les sujets Python / MySQL en creusant un peu.

Quelques MOOCs supplémentaires

Concevoir un site avec Flask : Flask est un mini framework Python. Sa philosophie est à l’opposé à celle de Django. Aujourd’hui Flask est populaire notamment dans le déploiement d’API Rest, mais aussi pour monter de petits sites web.

Toujours sur Flask, je vous conseille également l’excellente vidéo de Honoré Hounwanou. En deux heures, vous verrez comment déployer un blog Flask from scratch. Bien entendu vous pouvez doubler ce temps si vous souhaitez pratiquer en même temps que la vidéo.

Découvrez le cloud avec Amazon Web Services : Ici on retrouve Matthieu Nebra qui nous présente les trois services phares d’AWS : EC2, RDS et S3. Les pré-requis sont les connaissances de base en développement web : être à l’aise sous Linux et avec la console, savoir déployer un environnement Apache / MySQL / PHP.

Modélisez, implémentez et requêtez une base de données relationnelle avec UML et SQL. : Si vous êtes déjà familiarisé à SQL, seule la première partie du MOOC vous intéressera : elle explique comment modéliser une base de données à partir d’un domaine fonctionnel.

Conclusion

Voilà, vous savez à peu près tout 🙂 J’ai fait l’impasse sur certains sujets, car le billet est déjà trop long et trop dense. J’espère avoir suffisamment structuré l’ensemble pour que vous vous y retrouviez. Bien entendu, cette publication est avant tout l’occasion pour moi d’ouvrir le dialogue avec toute personne désireuse d’échanger sur le sujet.

Quelles que soient votre expérience et votre position actuelle, toute remarque, suggestion, critique ou question sont les bienvenues 🙂

A très vite !

OAuth 2 : point rapide et ressources bien faites

OAuth 2

Comment déléguer ses droits utilisateur à un widget ou à une application sans lui fournir explicitement ses identifiants de connexion ? C’est la problématique à laquelle ont souhaité répondre les concepteurs de OAuth.

OAuth 2 est un framework / protocole d’authentification pensé pour minimiser les échanges d’informations confidentielles, donc.

Parmi les cas d’usage les plus courants, on retrouve l’accès à une API externe et la connexion à un site via l’authentification sur un site tiers.

Voici un petit exemple fictif illustrant l’intérêt de OAuth 2 :

Accès à une API externe

Trois parties sont à considérer :

Le fournisseur de données : disons Instagram. Site sur lequel il faut créer un compte pour profiter pleinement de l’expérience utilisateur.

Un utilisateur lambda d’Instagram : Disons vous, cher lecteur.

Une application en ligne : imaginons une application qui propose d’aller liker à votre place toutes les photos ayant le hashtag de votre choix.

Quand on arrive sur l’application, celle-ci a besoin d’interagir avec l’API en votre nom, pour pouvoir liker les photos à votre place. On pourrait alors imaginer une solution où l’on donne tout simplement son identifiant et son mot de passe Instagram à l’application pour qu’elle se connecte à notre place.

Je ne sais pas vous, mais moi je suis pas du genre à donner mes identifiants de connexion Instagram à la première personne venue. Encore moins à une application en ligne. C’est là que OAuth 2 intervient : l’idée est tout simplement d’avoir un système où l’utilisateur peut déléguer ses droits à une application tierce sans jamais lui donner ses identifiants.

Tout repose sur le principe du jeton (token en anglais) : l’application récupère un token, matérialisé par une chaîne de caractères unique, qui lui permet d’accéder à la plateforme pendant un temps limité.

Comprendre les différents schémas d’obtention d’un token

Vous avez encore un peu de mal à visualiser la manière dont les tokens sont donnés, renouvelés et comment tout cela fonctionne ? Hé bien, je ne vais pas vous l’expliquer, car d’autres l’ont très bien fait avant moi 🙂

Avant de vous renvoyer vers des ressources externes, j’ai quand même envie de résumer en quelques mots les types d’authentification les plus courants en reprenant notre exemple d’application Instagram fictive :

Authentification explicite

  1. L’application s’est préalablement enregistrée auprès d’Instagram et a obtenu son client id
  2. Vous, l’internaute, arrivez sur l’application « I like for you »
  3. L’application vous redirige sur l’espace d’authentification d’Instagram, communiquant au passage son Client ID
  4. Vous vous identifiez et autorisez l’application à accéder à votre compte
  5. Instagram redirige vers l’URL définie par l’application avec un code en paramètre d’URL
  6. Le serveur de l’application récupère ce code et va s’en servir pour demander son token auprès d’Instagram
  7. Instagram renvoie au serveur le token

Et voilà ! Vous n’avez pas divulgué vos identifiants à l’application et en plus le token ne passe jamais côté navigateur

Authentification implicite

Même principe mais une étape en moins, le token étant directement communiqué au navigateur, en lieu et place du code intermédiaire.

  1. L’application s’est préalablement enregistrée auprès d’Instagram et a obtenu son client id
  2. Vous, l’internaute, arrivez sur l’application « I like for you »
  3. L’application vous redirige sur l’espace d’authentification d’Instagram, communiquant au passage son client id
  4. Vous vous identifiez et autorisez l’application à accéder à votre compte
  5. Instagram redirige vers l’URL définie par l’application avec le token en paramètre d’URL
  6. L’application côté client récupère ce token et peut donc requêter l’API.

C’est un peu moins secure puisque le token arrive jusqu’à votre navigateur et peut don cêtre plus facilement intercepté. Mais c’est super pratique. Ce schéma est notamment utilisé par Facebook Login.

Client Credentials Grant

Cette fois-ci, c’est simple et efficace : l’application s’authentifie directement avec un login et mot de passe. L’utilisateur n’intervient donc plus, c’est l’application elle-même qui possède son propre jeu d’identifiants. Cela signifie que cette dernière n’a pas besoin de droits supplémentaires à réclamer à l’utilisateur final (s’il y en a un) mais permet au service qui fournit les données de savoir à quelle application elle les fournit.

Ressources

Il y a encore pas mal de choses à voir. J’ai volontairement omis de vous parler de la récupération d’un nouveau token d’accès grâce au token de rafraîchissement, par exemple. Voici trois articles expliquant plus en détail le schéma de chaque scénario, les différentes implications techniques et les potentielles failles de sécurité de chaque méthode.

Il y a cet article : Comprendre OAuth 2 par l’exemple – Très clair et complet

Il y a également celui-ci : OAuth 2 logging with facebook – Moins technique, plus conceptuel, néanmoins intéressant

Ou encore celui-là : Comprendre OAuth 2. – Très proche du premier article, les failles y sont plus explicitées et illustrées par l’exemple

Google Analytics 360 x Python : exporter, enrichir, importer

Google Analytics avec Python

Une des problématiques récurrentes pour les web analystes est d’avoir à travailler avec de la donnée pauvre et/ou de mauvaise qualité. Dans certains cas, y compris avec de la donnée Google Analytics, il est possible de rectifier le tir. Plus particulièrement quand Google Analytics est déployé dans sa version Premium, désormais baptisée Google Analytics 360.

Nous allons voir ici comment grâce à deux fonctionnalités particulièrement utiles de GA360 et grâce à un petit peu de processing, il est possible d’enrichir facilement et rapidement sa donnée web. Ceci pourra être utile principalement dans les cas suivants :

    • Palier une lacune dans le marquage actuel du site : vous souhaitez par exemple créer une custom dimension « Auteur » et la valoriser via l’import de données
    • Réaliser une analyse ponctuelle : déployer au sein d’une custom dimension le résultat d’un algorithme de scoring basé sur une ou plusieurs dimensions / statistiques
    • Commencer ses analyses avant la mise en place d’un nouveau marquage: analyser des données existantes en valorisant une custom dimension ou une custom metric avant même son déploiement au sein du marquage.
    • Valoriser de manière rétroactive une dimension récemment intégrée au plan de marquage : une nouvelle dimension a été créée. Celle-ci est correctement alimentée par le nouveau marquage, mais vous souhaitez la valoriser de manière rétroactive

Cas client : classer toutes les URL d’un site par thématique

Je vous propose ici un tutoriel basé sur un cas client concret. La problématique est simple : on souhaite attribuer une thématique à chaque URL d’un site. Pour cela, on va se baser sur les termes contenus dans chaque URL. Cette classification se traduira par la création et la valorisation d’une nouvelle custom dimension au sein de Google Analytics.

Dans un monde parfait, ce type d’implémentation est réalisé en amont de la définition des KPI, des objectifs et des analyses. Mais ici, il n’était pas possible de toucher au plan de marquage et in-fine à l’implémentation. Nous allons donc voir comment enrichir de manière rétroactive environ 700 000 URL en quelques clics et en dix secondes de traitement.

Une fois la nouvelle custom dimension valorisée, il sera possible de l’utiliser au sein de tous les rapports natifs, des custom reports et des requêtes API. On pourra donc la croiser avec l’ensemble des statistiques et dimensions disponibles au sein de l’environnement GA.

J’ai découpé ce tutoriel en trois étapes clefs :

  1. Exporter de la donnée non échantillonnée via un « Unsampled Report». Le but étant de récupérer un CSV contenant un maximum d’URL sur une période donnée. Cette liste d’URL servira de clef de jointure pour notre nouvelle dimension.
  2. Enrichir et nettoyer la donnée en local grâce à Python. L’objectif est de créer une nouvelle colonne au sein de notre CSV dont la valeur de chaque ligne dépendra de l’URL, en fonction des règles qu’on aura établies.
  3. Réimporter la donnée au sein de GA via le Dimension Widening. Une fois notre CSV construit, il faut importer ce dernier au sein de GA pour rendre notre dimension exploitable. Une option spécifique à GA360 sur l’import de données, appelée « Query Time », nous sera particulièrement utile.

J’ai détaillé au maximum les trois parties, mais n’hésitez pas à faire un focus ou à balayer rapidement celles qui vous intéressent particulièrement ou celles que vous maîtrisez déjà.

Etape #1 : Exporter la donnée – L’Unsampled Report à la rescousse

Objectif : récupérer un CSV avec une colonne « Pages » exhaustive.

Un des avantages de Google Analytics 360 est de pouvoir exporter de la donnée non échantillonnée via les « Unsampled Reports ». Au sein d’un site à fort volume d’audience couplé à un nombre de pages indexées élevé, on peut rapidement devoir analyser plusieurs centaines de milliers de pages, rattachées à plusieurs millions de sessions différentes.

L’unsampled report présente deux avantages :

  1. Récupérer de la donnée non échantillonnée, même si le rapport dépasse la limite théorique des 100 millions de sessions. Rappelons que cette limite est de 500 000 sessions sur Google Analytics Standard. Au-delà de ces limites, un sampling est automatiquement appliqué.
  2. Récupérer un nombre de lignes allant jusqu’à 3 millions, contre seulement 5000 pour les custom reports standards. Et c’est cette fonctionnalité qui est à mes yeux de loin la plus puissante. Dans une majorité de cas, on pourra donc récupérer de manière exhaustive toutes les valeurs de n’importe quelle dimension. Attention en revanche au croisement de dimensions qui pourra très rapidement augmenter le nombre de lignes et exploser le quota des 3 millions.

Création du rapport personnalisé

Pour créer un Unsampled Report, il faut commencer par créer un custom report standard.

On va créer un custom report avec une seule dimension « Pages ». On rajoute la statistique « Pages vues » puisqu’un rapport doit contenir à minima une dimension et une statistique. Vous pouvez rajouter d’autres statistiques pour anticiper vos besoins, mais ici elles ne nous seront pas utiles. En revanche, ne rajoutez aucune autre dimension, pour ne pas démultiplier les valeurs de la colonne « Pages ».

Une fois le rapport créé, choisissez un date range suffisamment large pour viser l’exhaustivité sur la colonne « Pages ».

Rapport Google Analytics

Une fois votre rapport prêt, cliquez sur « Exporter » puis « Rapport non échantillonné ».

Rapport explorateur Google Analytics

Vous recevrez un email vous avertissant que le rapport non échantillonné est prêt. Vous pourrez également y accéder via l’onglet du menu dédié :

Rapport non échantillonné Google Analytics 360

Ensuite, il suffit de télécharger le rapport au format CSV. De mon côté, j’ai exporté un rapport contenant « Page » en dimension, « Pages vues » et « Sorties » en statistiques, ce qui donne ça :

Tableau Excel

Pour plus d’informations sur l’extraction de donnée GA non échantillonnée, je vous renvoie vers deux excellents articles de LunaMetrics :

Etape #2 : Enrichir facilement la donnée grâce à Python et la librairie Pandas

Objectif : enrichir le CSV préalablement obtenu avec une nouvelle colonne. Cette colonne contiendra les valeurs qu’on souhaite importer au sein de notre dimension « Thématique ». La jointure se fera grâce à la colonne « Page ».

Prérequis :

  • Avoir suivi l’étape 1 du tutoriel
  • Avoir créé une nouvelle custom dimension « Thématique » au sein de GA 360

A ce stade, vous devriez avoir un CSV dont la première colonne est la dimension « Page », suivie des statistiques que vous avez décidé d’intégrer dans le rapport.

Fichier CSV à trois colonnes

L’objet de l’article n’est pas d’expliquer comment installer un environnement Python. Notons simplement que j’ai réalisé l’ensemble des opérations au sein d’un Jupyter Notebook. Je vais en revanche détailler les différentes étapes du code, qu’on peut découper ainsi :

  1. Chargement des librairies (standards et externes)
  2. Création d’une fonction qui renvoie une thématique en fonction du contenu de l’URL
  3. Importation du CSV en tant que DataFrame
  4. Création d’une nouvelle colonne valorisée grâce à notre fonction précédemment créée
  5. Enregistrement du DataFrame en tant que CSV

Chargement des librairies

Nous allons avoir besoin de trois librairies, dont deux faisant partie de la librairie standard.

  • « time » qui va nous permettre de mesurer le temps d’exécution de notre script.
  • « re » pour réaliser des expressions régulières.
  • « Pandas ». Développée par Wes McKinney, cette librairie a largement contribué au succès de Python en Data Science et a donné toutes les armes au langage pour rivaliser notamment avec R. Dans notre cas, elle va nous permettre d’importer notre CSV sous forme de « DataFrame ». Un DataFrame est un objet Pandas modélisant une matrice à deux dimensions. Les colonnes possèdent des labels, et chaque ligne est indexée.
1
2
3
4
5
# Import des librairies
 
import pandas as pd
import re
import time

Création de notre fonction d’attribution de thématique

C’est ici que tout se joue. Dans notre cas, notre fonction de classement va être très basique. On va simplement chercher des correspondances d’expression régulière au sein de la chaîne de caractères passée en argument. Rien n’empêche en revanche d’imaginer quelque chose de plus complexe, basé sur plusieurs critères.

Afin de préserver la confidentialité du client, j’ai simplifié la fonction, en réduisant notamment le nombre de vérifications. Mais le principal y est. L’idée est de récupérer une URL en paramètre. On teste ensuite plusieurs expressions régulières pour trouver celle qui correspond. Dès qu’une correspondance est trouvée, on renvoie la thématique associée. Si aucune condition n’est trouvée, alors on renvoie une valeur par défaut.

Si cette fonction avait une chance de se retrouver dans la nature, il faudrait la renforcer. En vérifiant notamment que l’argument passé est bel et bien une URL.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# Fonction retournant une thématique en fonction du contenu de l'URL
 
def page_theme(url):
    """ Assignation d'une thématique en fonction du contenu de l'URL """
 
    theme = ""
 
    if (re.search('^/
 
 
<h3>Importation du CSV et création de la nouvelle colonne « Thématique »</h3>
 
 
 
 
<pre lang="python" line="1"># On enregistre l'heure avant de démarrer le processing
startTime = time.time()
 
# On récupère le rapport non échantillonné
gadf = pd.read_csv('Pages.csv', encoding='utf-8')
 
# On garde uniquement la colonne "Pages" On peut également choisir la colonne à l'import
del gadf['Pages vues']
del gadf['Sorties']
 
# Création d'une colonne "Theme". Application de la fonction page_theme()
gadf['Theme'] = list(map(page_theme, gadf.Page))
 
# Affichage du nombre de lignées traitées et du temps d'exécution
print(str(round(time.time() - startTime, 2)) + " secs")
print(str(len(gadf)) + " lines")
 
# Nettoyage du DataFrame
gadfCleanVersion = pd.DataFrame(gadf[list(map(is_clean_page, gadf['Page']))])
 
# Renommage des colonnes
gadfCleanVersion.rename(columns={'Page' : 'ga:pagePath', 'Theme' : 'ga:dimension31'}, inplace=True)
 
# Enregistrement du DataFrame sous forme de fichier CSV
gadfCleanVersion.to_csv(path_or_buf='page_and_theme.csv', index=False, encoding='utf-8')
 
# Affichage des 100 premières lignes du DataFrame
LapeyreCleanPages.head(100)

Output Jupyter-Notebook

Et voilà ! A peine plus de 10 secondes de traitement pour enrichir près de 700 000 URL. Un jeu d’enfant 🙂

Note : si vous souhaitez gagner en temps d’exécution, le code est optimisable assez facilement :

  1. Ne pas utiliser de regex sur les tests de chaînes simples
  2. Compiler une bonne fois pour toute les regex qui vont être testées sur l’ensemble des lignes du DataFrame

J’ai réalisé ces optimisations et je suis tombé à 7 secondes d’exécution. A vous de juger ensuite du meilleur rapport temps d’écriture de code versus temps d’exécution, en fonction de la ré-utilisaton du dit-code et/ou du volume de données à traiter.

Ceci étant dit, revenons sur deux passages en particulier :

Le premier

1
2
# Création d'une colonne "Theme". Application de la fonction page_theme()
gadf['Theme'] = list(map(page_theme, gadf.Page))

En une simple ligne de code…

  • … On crée une nouvelle colonne sur notre DataFrame
  • … On teste plus d’une dizaine d’expressions régulières sur environ 700 000 valeurs différentes
  • … On applique une valeur au sein de la colonne sur les 700 000 lignes

Le second

1
2
# Nettoyage du DataFrame
gadfCleanVersion = pd.DataFrame(gadf[list(map(is_clean_page, gadf['Page']))])

En une simple ligne de code, …

  • … on applique une fonction qui retourne un booléen, en fonction de si l’URL est valide ou non.
  • … on génère un itérateur dont on se sert pour créer une liste, qu’on applique en sélection sur notre premier DataFrame.
  • … on récupère notre sélection au sein d’un nouveau DataFrame qui ne contient que les lignes considérées comme valides.

Le but final étant d’exclure les URL sur lesquelles on ne souhaite pas appliquer de thématique. Cela permet d’alléger le CSV qui servira à l’import.

C’est cette syntaxe extrêmement synthétique qui rend notamment Python pratique et puissant pour traiter de la donnée. Bien qu’on en ait ici qu’un bref aperçu, on peut aussi remercier la librairie Pandas et son objet « DataFrame » très pratique.

Maintenant que notre fichier CSV est prêt, il ne nous reste plus qu’à l’importer au sein de Google Analytics 360.

Etape #3 : Importation de la donnée enrichie au sein de Google Analytics 360

Google Analytics 360 propose deux types d’importation de données :

  • Processing Time Import Mode
  • Query Time Import Mode

Le premier mode d’importation est disponible également sur la version gratuite de GA. Il présente en revanche deux inconvénients rendant la fonctionnalité peu utile, voire même dangereuse à l’utilisation :

  1. Effet non rétro-actif sur la donnée : la donnée importée sera effective uniquement sur les hits récoltés après l’import de votre modèle. Impossible donc d’utiliser cette fonctionnalité dans un but d’analyse antérieure.
  2. Marquage irréversible : votre modèle sera gravé dans le marbre pour tous les hits générés à posteriori.

Attardons-nous plutôt sur le second mode.

Query Time Import Mode

Cette option n’est disponible que sur Google Analytics 360. Espérons qu’elle soit un jour étendue à Google Analytics standard. Le fonctionnement de ce mode est simple : à chaque fois que l’on requête de la donnée Google Analytics via une vue (Rapport natif, rapport personnalisé, requête Core API), Google réalise un processing à la volée pour intégrer la donnée importée.

Cela présente trois avantages non négligeables :

  1. Toute importation est rétro-active de facto, puisque le modèle est généré à la volée lors des requêtes, quelle que soit la date d’analyse.
  2. Vos importations n’ont aucune conséquence sur le schéma de données récoltées et stockées par Google.
  3. Il suffit de supprimer un modèle importé pour qu’il ne soit plus effectif.

L’import se réalise en deux étapes :

  1. Création d’un modèle d’import
  2. Import de la donnée sous forme de CSV respectant le modèle

Création d’un modèle d’import

Rendez-vous dans : Admin => Importation de données => Créer

GA360 : modèle d'import de données

Choisissez ensuite l’option « Import de données relatives au contenu »

GA360 : import de données de type contenu

Puis on choisit le type d’import que l’on souhaite réaliser. On notera la traduction hasardeuse très élégante de « Time Query » par « Heure de la requête ».

Comme vous pouvez le constater, la fonctionnalité est encore en bêta. Jusqu’il y a peu, on rencontrait de sérieux soucis de bugs et d’instabilité lors de son utilisation. Mais depuis le 20 septembre tout semble être rentré dans l’ordre.

GA360 import query time processing

Nommer ensuite votre modèle d’importation et sélectionnez les vues auxquelles il sera rattaché :

Vues rattachées à l'import de données

Enfin, il faut créer à proprement parler le modèle de données. Pour cela, on sélectionne la dimension qui servira de clef de jointure. Dans notre exemple, c’est la dimension « Page » qui endossera ce rôle. Ensuite, on sélectionne les dimensions que l’on souhaite enrichir. Il s’agit d’une custom dimension fraîchement créée, appelée « Thématique » et qui correspond à la Custom Dimension n°31 dans mon cas. On peut en sélectionner plusieurs si nécessaire.

On notera que sur la clef de jointure, il est possible de sélectionner qu’une partie des valeurs à prendre en compte lors de l’import, grâce à une expression régulière. C’est grossomodo le rôle de ma fonction de nettoyage expliquée plus haut, dans le script Python.

Note : si jamais des données importées et des données récoltées cohabitent, ce sont vos données importées qui prendront le dessus.

GA360 - Modèle de données

Maintenant que notre modèle est prêt, il ne nous reste plus qu’à importer le CSV.

GA360 - Accès à la gestion d'import de données

GA360 - Importer un fichier CSV

Et voilà ! Une fois l’importation terminée, il faudra compter une petite heure avant que le set de données soit utilisable au sein des requêtes API et des rapports.

Désormais, vous pouvez croiser votre dimension « Thématique » avec l’ensemble des dimensions et statistiques présentes dans le GA. Attention simplement à respecter la cohérence des scopes.

Les limites

La méthode détaillée dans cet article présente deux limites qui sont les suivantes.

Les valeurs récoltées dans le futur n’auront aucun impact sur l’enrichissement

Toutes les valeurs de la dimension « pagePath » qu’on a exportées ont permis d’enrichir la dimension « Thématique ». Et les analyses pourront être effectuées sur n’importe quelle période. En revanche, si après l’import, des pages vues génèrent de nouvelles URL – inconnues lors de l’export – alors celles-ci n’auront aucune thématique associée.

Ainsi il faudra réaliser régulièrement l’opération d’export / processing / import, afin de maintenir à jour les valeurs pour les futures URL. Il est possible d’automatiser une grande partie de l’opération, mais cela reste fastidieux.

C’est pour cette raison qu’il ne s’agit pas d’une méthode se substituant à l’enrichissement d’un plan de marquage. Ici, le but est plutôt de réaliser une analyse ou un enrichissement de manière ponctuelle, afin de répondre à une question à un instant T. La mise en œuvre de cette méthode doit donc être sous-tendue par un besoin spécifique, urgent ou ponctuel.

Le modèle de données GA au sein de Big Query n’est pas enrichi

Le mode d’importation « Time Query » présente de nombreux avantages de par le requêtage à la volée. En revanche, puisqu’on enrichit uniquement à l’affichage, le modèle de données n’est jamais affecté. Il faudra inéluctablement passer par Google Analytics pour retrouver cette donnée. Il sera donc impossible de retrouver les valeurs importées en Query Time au sein de Big Query.

Si vous souhaitez altérer et enrichir le modèle de données au sein de Big Query, il faudra alors passer par un import de type « Processing time ». L’inconvénient majeur est que ce mode n’affecte que les futurs hits récoltés. Et une fois la récolte commencée, il ne sera pas possible de faire machine arrière pour les hits enregistrés. Restez prudent, donc 🙂

Tous les modèles d’export ne sont pas réalisables en rapport non échantillonné

Il y a plusieurs cas où un rapport non échantillonné montrera ses limites :

  • Exporter tous les hits sur une période donnée
  • Exporter toutes les sessions sur une période donnée
  • Croiser plusieurs dimensions au sein d’un même rapport

Pour les deux premiers exemples, vous aurez besoin de deux custom dimensions : une pour gérer l’identification unique de chaque hit et l’autre de chaque session. Mais au-delà de ça, ces modèles dépasseront rapidement la limite théorique des trois millions de lignes maximales par rapport.

Aller plus loin

Il faut bien retenir que :

  • Grâce aux méthodes de « Dimension widening », le modèle de données Google Analytics n’est pas étanche à la donnée externe.
  • Il est possible de réaliser des traitements de masse sur de la donnée Google Analytics sans nécessairement passer par Big Query.

En restant sur le même schéma, on pourrait imaginer par exemple exporter l’ensemble des User ID / Client ID avec les statistiques qui semblent pertinentes, puis réaliser un algorithme de scoring basé sur les données d’achat. Il suffirait ensuite de réimporter la donnée enrichie au sein d’une dimension dédiée dans Google Analytics. Ou bien encore, pourquoi ne pas imaginer une qualification basée uniquement sur le comportement de navigation et trouver des corrélations avec le comportement d’achat. Les seules limites seront votre imagination et la qualité du socle Analytics de vos actifs digitaux.

Pour conclure

J’ai tenté de décrire ici une méthode simple et efficace pour enrichir sa donnée GA. Il s’agit avant tout de présenter des moyens, à vous ensuite de les adapter pour arriver à vos fins. Certaines notions abordées sont à peine effleurées car infiniment vastes. Mais l’idée est de souligner que les solutions Analytics ne sont pas étanches aux données et aux traitements extérieurs. Et de rappeler qu’un web analyste dispose d’une panoplie de technologies et d’outils à sa disposition permettant de faire face à tout type de contrainte technique. Correctement utilisés, la mise en œuvre de vos analyses et enrichissements de données site-centric seront rendues possibles y compris sur des périmètres complexes et étendus.

Les commentaires sont ouverts pour les remarques et questions.

, url)):
theme = ‘Home’

elif (re.search(‘(fen(e|ê)tre|(baie(.*)vitr(é|e))’, url)):
theme = ‘Fenêtre’

elif (re.search(‘porte.*garage’, url)):
theme = ‘Porte de garage’

elif (re.search(‘(sol|mur|carrelage|parquet|lambri|parement)’, url)):
theme = ‘Sols et murs’

else:
theme = ‘Undefined’

return theme

Importation du CSV et création de la nouvelle colonne « Thématique »


Output Jupyter-Notebook

Et voilà ! A peine plus de 10 secondes de traitement pour enrichir près de 700 000 URL. Un jeu d’enfant 🙂

Note : si vous souhaitez gagner en temps d’exécution, le code est optimisable assez facilement :

  1. Ne pas utiliser de regex sur les tests de chaînes simples
  2. Compiler une bonne fois pour toute les regex qui vont être testées sur l’ensemble des lignes du DataFrame

J’ai réalisé ces optimisations et je suis tombé à 7 secondes d’exécution. A vous de juger ensuite du meilleur rapport temps d’écriture de code versus temps d’exécution, en fonction de la ré-utilisaton du dit-code et/ou du volume de données à traiter.

Ceci étant dit, revenons sur deux passages en particulier :

Le premier


En une simple ligne de code…

  • … On crée une nouvelle colonne sur notre DataFrame
  • … On teste plus d’une dizaine d’expressions régulières sur environ 700 000 valeurs différentes
  • … On applique une valeur au sein de la colonne sur les 700 000 lignes

Le second


En une simple ligne de code, …

  • … on applique une fonction qui retourne un booléen, en fonction de si l’URL est valide ou non.
  • … on génère un itérateur dont on se sert pour créer une liste, qu’on applique en sélection sur notre premier DataFrame.
  • … on récupère notre sélection au sein d’un nouveau DataFrame qui ne contient que les lignes considérées comme valides.

Le but final étant d’exclure les URL sur lesquelles on ne souhaite pas appliquer de thématique. Cela permet d’alléger le CSV qui servira à l’import.

C’est cette syntaxe extrêmement synthétique qui rend notamment Python pratique et puissant pour traiter de la donnée. Bien qu’on en ait ici qu’un bref aperçu, on peut aussi remercier la librairie Pandas et son objet « DataFrame » très pratique.

Maintenant que notre fichier CSV est prêt, il ne nous reste plus qu’à l’importer au sein de Google Analytics 360.

Etape #3 : Importation de la donnée enrichie au sein de Google Analytics 360

Google Analytics 360 propose deux types d’importation de données :

  • Processing Time Import Mode
  • Query Time Import Mode

Le premier mode d’importation est disponible également sur la version gratuite de GA. Il présente en revanche deux inconvénients rendant la fonctionnalité peu utile, voire même dangereuse à l’utilisation :

  1. Effet non rétro-actif sur la donnée : la donnée importée sera effective uniquement sur les hits récoltés après l’import de votre modèle. Impossible donc d’utiliser cette fonctionnalité dans un but d’analyse antérieure.
  2. Marquage irréversible : votre modèle sera gravé dans le marbre pour tous les hits générés à posteriori.

Attardons-nous plutôt sur le second mode.

Query Time Import Mode

Cette option n’est disponible que sur Google Analytics 360. Espérons qu’elle soit un jour étendue à Google Analytics standard. Le fonctionnement de ce mode est simple : à chaque fois que l’on requête de la donnée Google Analytics via une vue (Rapport natif, rapport personnalisé, requête Core API), Google réalise un processing à la volée pour intégrer la donnée importée.

Cela présente trois avantages non négligeables :

  1. Toute importation est rétro-active de facto, puisque le modèle est généré à la volée lors des requêtes, quelle que soit la date d’analyse.
  2. Vos importations n’ont aucune conséquence sur le schéma de données récoltées et stockées par Google.
  3. Il suffit de supprimer un modèle importé pour qu’il ne soit plus effectif.

L’import se réalise en deux étapes :

  1. Création d’un modèle d’import
  2. Import de la donnée sous forme de CSV respectant le modèle

Création d’un modèle d’import

Rendez-vous dans : Admin => Importation de données => Créer

GA360 : modèle d'import de données

Choisissez ensuite l’option « Import de données relatives au contenu »

GA360 : import de données de type contenu

Puis on choisit le type d’import que l’on souhaite réaliser. On notera la traduction hasardeuse très élégante de « Time Query » par « Heure de la requête ».

Comme vous pouvez le constater, la fonctionnalité est encore en bêta. Jusqu’il y a peu, on rencontrait de sérieux soucis de bugs et d’instabilité lors de son utilisation. Mais depuis le 20 septembre tout semble être rentré dans l’ordre.

GA360 import query time processing

Nommer ensuite votre modèle d’importation et sélectionnez les vues auxquelles il sera rattaché :

Vues rattachées à l'import de données

Enfin, il faut créer à proprement parler le modèle de données. Pour cela, on sélectionne la dimension qui servira de clef de jointure. Dans notre exemple, c’est la dimension « Page » qui endossera ce rôle. Ensuite, on sélectionne les dimensions que l’on souhaite enrichir. Il s’agit d’une custom dimension fraîchement créée, appelée « Thématique » et qui correspond à la Custom Dimension n°31 dans mon cas. On peut en sélectionner plusieurs si nécessaire.

On notera que sur la clef de jointure, il est possible de sélectionner qu’une partie des valeurs à prendre en compte lors de l’import, grâce à une expression régulière. C’est grossomodo le rôle de ma fonction de nettoyage expliquée plus haut, dans le script Python.

Note : si jamais des données importées et des données récoltées cohabitent, ce sont vos données importées qui prendront le dessus.

GA360 - Modèle de données

Maintenant que notre modèle est prêt, il ne nous reste plus qu’à importer le CSV.

GA360 - Accès à la gestion d'import de données

GA360 - Importer un fichier CSV

Et voilà ! Une fois l’importation terminée, il faudra compter une petite heure avant que le set de données soit utilisable au sein des requêtes API et des rapports.

Désormais, vous pouvez croiser votre dimension « Thématique » avec l’ensemble des dimensions et statistiques présentes dans le GA. Attention simplement à respecter la cohérence des scopes.

Les limites

La méthode détaillée dans cet article présente deux limites qui sont les suivantes.

Les valeurs récoltées dans le futur n’auront aucun impact sur l’enrichissement

Toutes les valeurs de la dimension « pagePath » qu’on a exportées ont permis d’enrichir la dimension « Thématique ». Et les analyses pourront être effectuées sur n’importe quelle période. En revanche, si après l’import, des pages vues génèrent de nouvelles URL – inconnues lors de l’export – alors celles-ci n’auront aucune thématique associée.

Ainsi il faudra réaliser régulièrement l’opération d’export / processing / import, afin de maintenir à jour les valeurs pour les futures URL. Il est possible d’automatiser une grande partie de l’opération, mais cela reste fastidieux.

C’est pour cette raison qu’il ne s’agit pas d’une méthode se substituant à l’enrichissement d’un plan de marquage. Ici, le but est plutôt de réaliser une analyse ou un enrichissement de manière ponctuelle, afin de répondre à une question à un instant T. La mise en œuvre de cette méthode doit donc être sous-tendue par un besoin spécifique, urgent ou ponctuel.

Le modèle de données GA au sein de Big Query n’est pas enrichi

Le mode d’importation « Time Query » présente de nombreux avantages de par le requêtage à la volée. En revanche, puisqu’on enrichit uniquement à l’affichage, le modèle de données n’est jamais affecté. Il faudra inéluctablement passer par Google Analytics pour retrouver cette donnée. Il sera donc impossible de retrouver les valeurs importées en Query Time au sein de Big Query.

Si vous souhaitez altérer et enrichir le modèle de données au sein de Big Query, il faudra alors passer par un import de type « Processing time ». L’inconvénient majeur est que ce mode n’affecte que les futurs hits récoltés. Et une fois la récolte commencée, il ne sera pas possible de faire machine arrière pour les hits enregistrés. Restez prudent, donc 🙂

Tous les modèles d’export ne sont pas réalisables en rapport non échantillonné

Il y a plusieurs cas où un rapport non échantillonné montrera ses limites :

  • Exporter tous les hits sur une période donnée
  • Exporter toutes les sessions sur une période donnée
  • Croiser plusieurs dimensions au sein d’un même rapport

Pour les deux premiers exemples, vous aurez besoin de deux custom dimensions : une pour gérer l’identification unique de chaque hit et l’autre de chaque session. Mais au-delà de ça, ces modèles dépasseront rapidement la limite théorique des trois millions de lignes maximales par rapport.

Aller plus loin

Il faut bien retenir que :

  • Grâce aux méthodes de « Dimension widening », le modèle de données Google Analytics n’est pas étanche à la donnée externe.
  • Il est possible de réaliser des traitements de masse sur de la donnée Google Analytics sans nécessairement passer par Big Query.

En restant sur le même schéma, on pourrait imaginer par exemple exporter l’ensemble des User ID / Client ID avec les statistiques qui semblent pertinentes, puis réaliser un algorithme de scoring basé sur les données d’achat. Il suffirait ensuite de réimporter la donnée enrichie au sein d’une dimension dédiée dans Google Analytics. Ou bien encore, pourquoi ne pas imaginer une qualification basée uniquement sur le comportement de navigation et trouver des corrélations avec le comportement d’achat. Les seules limites seront votre imagination et la qualité du socle Analytics de vos actifs digitaux.

Pour conclure

J’ai tenté de décrire ici une méthode simple et efficace pour enrichir sa donnée GA. Il s’agit avant tout de présenter des moyens, à vous ensuite de les adapter pour arriver à vos fins. Certaines notions abordées sont à peine effleurées car infiniment vastes. Mais l’idée est de souligner que les solutions Analytics ne sont pas étanches aux données et aux traitements extérieurs. Et de rappeler qu’un web analyste dispose d’une panoplie de technologies et d’outils à sa disposition permettant de faire face à tout type de contrainte technique. Correctement utilisés, la mise en œuvre de vos analyses et enrichissements de données site-centric seront rendues possibles y compris sur des périmètres complexes et étendus.

Les commentaires sont ouverts pour les remarques et questions.