Brouillon auto

AI.DETECT_ANOMALIES : Détecter des anomalies GA4 dans BigQuery

Utiliser la fonction AI.DETECT_ANOMALIES de BigQuery pour tester un dataset GA4

Quand une nouvelle fonction arrive dans BigQuery, je fais toujours la même chose : je lis la doc, je regarde les paramètres, je vérifie les limites, puis je la teste sur un vrai dataset.

C’est exactement ce que j’ai fait avec la fonction BigQuery AI.DETECT_ANOMALIES.

La fonction est simple à comprendre : elle détecte des anomalies dans une série temporelle en s’appuyant sur le modèle TimesFM intégré à BigQuery ML. Je lui donne un historique, une période cible, une colonne numérique et une colonne temporelle. BigQuery calcule une plage attendue, puis me renvoie la valeur observée, les bornes basse et haute, un booléen is_anomaly, une probabilité d’anomalie et un statut technique.

L’intérêt est immédiat. Je peux vérifier si mes données sont cohérentes.

  • Est-ce qu’il manque du trafic ?
  • Est-ce qu’un volume s’effondre brutalement ?
  • Est-ce qu’un pic est plausible ou suspect ?
  • Est-ce qu’un import a cassé ma série ?

Sur ce terrain-là, la fonction a une vraie valeur.

🚀 Maîtrisez SQL pour exploiter pleinement vos données BigQuery !

Découvrez nos formations BigQuery adaptées à tous les niveaux, du débutant à l’expert. Apprenez à interroger, analyser et optimiser vos données avec SQL dans BigQuery, et exploitez toute la puissance du cloud pour des analyses avancées. Du niveau 1, où vous explorerez et visualiserez vos données avec BigQuery et Looker Studio, au niveau 2, qui vous permettra de maîtriser les requêtes SQL pour trier, filtrer et structurer efficacement vos données, jusqu’au niveau 3, dédié aux techniques avancées d’optimisation et d’automatisation. Que vous soyez analyste, data scientist ou développeur, ces formations vous permettront de gagner en autonomie et en efficacité dans le traitement de vos données.🔍📊

Ce que fait réellement la fonction

La syntaxe tient en quelques lignes :

SELECT *
FROM AI.DETECT_ANOMALIES(
TABLE `mydataset.history_table`,
TABLE `mydataset.target_table`,
data_col => 'metric_value',
timestamp_col => 'metric_date'
);

La doc officielle précise les paramètres principaux :

ParamètreObligatoireRôle
history_table ou sous-requêteOuihistorique de référence
target_table ou sous-requêteOuipériode à évaluer
data_colOuicolonne numérique à surveiller
timestamp_colOuicolonne temporelle
modelNonTimesFM 2.0 ou TimesFM 2.5
id_colsNonplusieurs séries en parallèle
anomaly_prob_thresholdNonseuil d’anomalie
context_windowNonlongueur de contexte utilisée par le modèle

BigQuery supporte INT64, NUMERIC, BIGNUMERIC et FLOAT64 pour data_col, et DATE, DATETIME ou TIMESTAMP pour timestamp_col. Si je ne renseigne pas context_window, BigQuery choisit automatiquement la plus petite fenêtre compatible avec la taille de la série.

Le principe de lecture est basique : une valeur est considérée comme anormale si elle passe sous lower_bound ou au-dessus de upper_bound.

Pourquoi la fonction AI.DETECT_ANOMALIES est utile ?

Je ne vois pas cette fonction comme un gadget “IA dans SQL”. Je la vois comme une brique de supervision.

Elle a toute sa place en production pour trois raisons.

La première, c’est la simplicité. Google positionne clairement l’approche TimesFM comme une voie légère, sans création ni maintenance de modèle, contrairement aux approches ARIMA qui demandent plus de pilotage.

La deuxième, c’est l’intégration naturelle dans une stack data. Je peux la lancer dans BigQuery, stocker les résultats, historiser les anomalies, alimenter un dashboard QA, déclencher une alerte, ou enrichir une logique de contrôle avant publication d’un reporting.

La troisième, c’est la couverture fonctionnelle. Dès que j’ai une série temporelle propre, la fonction devient exploitable.

Exemples de cas d’usage sur n’importe quel dataset

Le plus intéressant, ce n’est pas seulement la détection d’anomalies. C’est tout ce qu’on peut bâtir autour.

Cas d’usageCe que je surveilleÀ quoi ça sert
QA de donnéesvolumes journaliers, imports, exportsrepérer un trou ou un pic suspect
Monitoring de pipelineslignes importées, commandes, leads, coûtsvoir si un flux décroche
Contrôle avant dashboardKPIs du jour ou de la semaineéviter de publier un chiffre cassé
Alertes métierventes, CA, taux de conversion, ticketsdétecter vite une rupture
Supervision marketingclics, dépenses, conversionsvoir si un canal s’emballe ou s’effondre
Audit qualitélogs d’anomalies historisésmesurer le bruit et ajuster les seuils

Je peux l’utiliser sur des ventes quotidiennes, des données CRM, des dépenses média, des volumes de tickets support, des données produit, des métriques IoT, des imports backend ou des événements applicatifs. Tant que j’ai une table avec une date et une valeur, je peux tester.

Principaux paramètres de la fonction AI.DETECT_ANOMALIES

Tous les paramètres n’ont pas le même poids dans la pratique.

ParamètreCe qu’il change concrètement
id_colsje surveille plusieurs séries segmentées au lieu d’un total global
anomaly_prob_thresholdje rends la détection plus ou moins sensible
modelje choisis TimesFM 2.0 ou TimesFM 2.5 selon la profondeur d’historique
context_windowje contrôle combien de points récents le modèle utilise

Google documente les fenêtres supportées : TimesFM 2.0 supporte jusqu’à 2 048 points, TimesFM 2.5 jusqu’à 15 360 points. En revanche, seuls les 1 024 points les plus récents sont évalués pour les anomalies. C’est un détail important pour les longues séries.

Réponse de la fonction AI.DETECT_ANOMALIES

Voici les colonnes vraiment utiles à exploiter :

ColonneUtilité
time_series_timestampdate ou timestamp observé
time_series_datavaleur observée
lower_boundborne basse attendue
upper_boundborne haute attendue
is_anomalydrapeau principal
anomaly_probabilityintensité du signal
ai_detect_anomalies_statusstatut technique

En clair, je peux non seulement savoir qu’un point est anormal, mais aussi mesurer à quel point il s’écarte du cadre attendu.

Premier exemple : contrôle simple sur un dataset générique

Prenons un cas classique : des ventes quotidiennes.

SELECT *
FROM AI.DETECT_ANOMALIES(
TABLE `sales.history_daily_sales`,
TABLE `sales.target_daily_sales`,
data_col => 'units_sold',
timestamp_col => 'sales_date'
);

Lecture type :

DateVentesBorne basseBorne hauteAnomalie
2026-04-01420360510false
2026-04-02438355505false
2026-04-03190350500true

Dans ce cas, je m’en sers pour vérifier un trou potentiel avant analyse. Est-ce une rupture de stock ? Un bug d’import ? Un incident logistique ? Une baisse réelle ? Peu importe à ce stade : la fonction m’a signalé qu’il faut regarder.

Deuxième exemple : plusieurs séries en parallèle

C’est souvent là que la fonction devient vraiment utile.

SELECT *
FROM AI.DETECT_ANOMALIES(
TABLE `marketing.history_daily_revenue`,
TABLE `marketing.target_daily_revenue`,
data_col => 'revenue',
timestamp_col => 'date',
id_cols => ['channel'],
anomaly_prob_threshold => 0.90
);

Lecture type :

DateCanalRevenueAnomalie
2026-04-10organic8 500false
2026-04-10paid_search12 900false
2026-04-10email1 050true

Sans id_cols, le total global peut masquer le problème. Avec id_cols, je vois immédiatement quel segment décroche.

Pourquoi le test sur un export GA4 est intéressant

Un export GA4 dans BigQuery est un très bon dataset de test.

Il est riche, granulaire, parfois bruité, sensible aux changements de tracking, aux effets marketing, aux variations de consentement et aux incidents de collecte. Bref, il ressemble à la vraie vie.

Google rappelle d’ailleurs que l’export GA4 alimente des tables quotidiennes events_YYYYMMDD, et recommande d’interroger ces tables plutôt que events_intraday_YYYYMMDD lorsqu’on veut un dataset stable sur la journée.

La conséquence est simple : si je veux exploiter AI.DETECT_ANOMALIES proprement sur un export GA4, je pars d’abord sur des agrégats stables.

Ce que je surveille dans un dataset GA4

Je ne branche pas la fonction directement sur events_*. Je construis d’abord des séries lisibles.

Les plus utiles sont souvent celles-ci :

Série GA4Usage
sessions par jourvérifier la stabilité globale de la collecte
achats par jourrepérer un incident checkout ou tracking
revenu par jourdétecter une rupture e-commerce
leads par joursurveiller les formulaires et tunnels
sessions par canalrepérer un décrochage acquisition
revenu par canaldétecter une chute masquée dans le total
événements critiquessurveiller add_to_cart, begin_checkout, purchase, generate_lead

Exemple GA4 1 : sessions quotidiennes

Les requêtes GA4 officielles montrent bien comment récupérer ga_session_id dans event_params.

Je peux donc construire une table de sessions quotidiennes comme ceci :

CREATE OR REPLACE TABLE `project.dataset.ga4_sessions_daily` AS
SELECT
PARSE_DATE('%Y%m%d', event_date) AS date,
COUNT(DISTINCT CONCAT(
user_pseudo_id,
CAST((SELECT value.int_value
FROM UNNEST(event_params)
WHERE key = 'ga_session_id') AS STRING)
)) AS sessions
FROM `project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260101' AND '20260331'
GROUP BY 1
ORDER BY 1;

Puis je lance la détection :

SELECT *
FROM AI.DETECT_ANOMALIES(
(SELECT date, sessions
FROM `project.dataset.ga4_sessions_daily`
WHERE date < DATE '2026-03-01'),
(SELECT date, sessions
FROM `project.dataset.ga4_sessions_daily`
WHERE date >= DATE '2026-03-01'),
data_col => 'sessions',
timestamp_col => 'date'
);

Lecture typique :

DateSessionsAnomalieLecture
2026-03-0218 240falsenormal
2026-03-0318 510falsestable
2026-03-0411 980truetrou à vérifier

Ici, la fonction me sert d’abord à valider mes données avant analyse.

Exemple GA4 2 : achats quotidiens

CREATE OR REPLACE TABLE `project.dataset.ga4_purchases_daily` AS
SELECT
PARSE_DATE('%Y%m%d', event_date) AS date,
COUNTIF(event_name = 'purchase') AS purchases
FROM `project.analytics_123456789.events_*`
WHERE _TABLE_SUFFIX BETWEEN '20260101' AND '20260331'
GROUP BY 1
ORDER BY 1;
SELECT *
FROM AI.DETECT_ANOMALIES(
(SELECT date, purchases
FROM `project.dataset.ga4_purchases_daily`
WHERE date < DATE '2026-03-01'),
(SELECT date, purchases
FROM `project.dataset.ga4_purchases_daily`
WHERE date >= DATE '2026-03-01'),
data_col => 'purchases',
timestamp_col => 'date',
anomaly_prob_threshold => 0.90
);

Lecture type :

DatePurchasesAnomalieLecture possible
2026-03-05412falsehabituel
2026-03-06398falsenormal
2026-03-07137trueincident possible sur le tunnel ou la collecte

Exemple GA4 3 : revenu par canal

CREATE OR REPLACE TABLE `project.dataset.ga4_revenue_by_channel_daily` AS
SELECT
PARSE_DATE('%Y%m%d', event_date) AS date,
CONCAT(collected_traffic_source.manual_source, ' / ', collected_traffic_source.manual_medium) AS source_medium,
SUM(ecommerce.purchase_revenue) AS revenue
FROM `project.analytics_123456789.events_*`
WHERE event_name = 'purchase'
AND _TABLE_SUFFIX BETWEEN '20260101' AND '20260331'
GROUP BY 1, 2
ORDER BY 1, 2;
SELECT *
FROM AI.DETECT_ANOMALIES(
(SELECT date, source_medium, revenue
FROM `project.dataset.ga4_revenue_by_channel_daily`
WHERE date < DATE '2026-03-01'),
(SELECT date, source_medium, revenue
FROM `project.dataset.ga4_revenue_by_channel_daily`
WHERE date >= DATE '2026-03-01'),
data_col => 'revenue',
timestamp_col => 'date',
id_cols => ['source_medium'],
model => 'TimesFM 2.5',
anomaly_prob_threshold => 0.90
);

Lecture type :

DateCanalRevenueAnomalie
2026-03-08google / organic8 420false
2026-03-08google / cpc13 980false
2026-03-08email / newsletter1 120true

C’est typiquement le genre de contrôle que j’aime brancher en QA ou en alerte.

Comment je l’exploite réellement

Le vrai usage ne s’arrête pas à la requête. Je m’en sers pour bâtir des dispositifs simples.

DispositifCe que je fais
Log QAj’enregistre toutes les anomalies dans une table
Alertej’envoie un Slack ou un email sur les cas critiques
Contrôle avant dashboardj’affiche un warning si un KPI est suspect
Revue hebdoje compare anomalies détectées et incidents réels
Supervision de trackingje surveille les événements clés
Supervision businessje surveille ventes, leads, revenus, coûts

Dit autrement, AI.DETECT_ANOMALIES n’est pas seulement une fonction d’analyse. C’est une brique de supervision data.

Je trouve cette fonction vraiment utile.

Elle ne remplace pas le métier, elle ne remplace pas une lecture humaine, et elle ne remplace pas la qualité des données. Mais elle ajoute quelque chose de très concret : un moyen simple, natif et SQL-first de détecter des écarts dans une série temporelle avant de bâtir une analyse ou un reporting dessus.

C’est valable sur des ventes, du CRM, des coûts, des tickets, des capteurs, des pipelines, et particulièrement sur des séries reconstruites à partir d’un export GA4 dans BigQuery. Sur ce terrain-là, la fonction n’est pas juste intéressante. Elle est directement exploitable.

Retour en haut
Formations Analytics