Module 6 — Matérialisation et fraîcheur
Le magasin en ligne ne se remplit pas tout seul. Un processus régulier lit les sources, calcule les valeurs et pousse la dernière capture par entité. C'est la matérialisation — l'opération la plus coûteuse d'un magasin en production, et celle dont la fréquence choisit implicitement la qualité du modèle.
Qu'est-ce qu'on matérialise
Reprenons nb_transactions_24h. La source est une table Parquet des transactions, mise à jour en permanence par le processeur de paiement. Le calcul, exprimé une fois dans la définition, est :
SELECT card_id_hash,
COUNT(*) AS nb_transactions_24h
FROM transactions
WHERE event_timestamp > NOW() - INTERVAL '24 hours'
GROUP BY card_id_hash
À chaque exécution, le moteur balaie les 24 dernières heures, produit une ligne par porteur, et :
- écrit dans le magasin hors ligne un enregistrement daté
(card_id_hash, valid_at, nb_transactions_24h)— un point de plus dans l'historique ; - écrase dans le magasin en ligne la ligne courante du porteur avec cette dernière valeur.
Les deux magasins reçoivent la même valeur au même instant. C'est la clé de la cohérence.
Deux régimes de matérialisation
Par lots. Un ordonnanceur (Airflow, Dagster, cron) déclenche l'exécution à intervalle fixe : toutes les 5 minutes, toutes les heures, une fois par jour. Adapté aux variables qui ne changent pas plus vite que l'intervalle : montant_moyen_7j bouge lentement, une matérialisation quotidienne suffit. Simple à opérer, testable, réutilise l'infrastructure batch existante.
En flux. Un processus consomme un flux d'événements (Kafka, Kinesis) en continu, met à jour la valeur au fil de l'eau, et pousse dans le magasin en ligne à chaque événement (ou par micro-lots). Adapté aux variables très volatiles : nb_transactions_derniere_minute ne peut pas attendre une exécution horaire. Coûteux en infrastructure, plus fragile — mais nécessaire quand la latence de la variable est comparable à la latence de la décision.
En pratique, on mélange les deux régimes dans un même magasin. Les variables 24 h et 7 j sont batch (rafraîchies toutes les heures) ; les variables 1 h et 5 min sont en flux. Feast, Tecton et Databricks Feature Store gèrent la coexistence.
La fraîcheur mesurée
Une variable a une fraîcheur : le temps écoulé entre l'événement le plus récent qui a influencé sa valeur et l'instant où elle est lue. On mesure la fraîcheur en trois points, à ne pas confondre.
- Fraîcheur de la source — délai entre l'occurrence d'un événement et sa disponibilité dans la source (typique : 100 ms en Kafka, 5 min à 30 min dans un entrepôt batch).
- Fraîcheur du calcul — délai entre l'événement dans la source et sa prise en compte dans la valeur calculée (dicté par la fréquence de matérialisation).
- Fraîcheur de service — délai entre le calcul de la valeur et sa mise à disposition dans le magasin en ligne (typique : quelques secondes après l'écriture Redis).
La somme de ces trois délais est la fraîcheur de bout en bout, mesurée par un tableau de bord toujours visible :
from feast import FeatureStore
store = FeatureStore(".")
for view in store.list_feature_views():
stats = store.get_feature_view(view.name).materialization_intervals
if stats:
derniere_fin = max(s[1] for s in stats)
age = (datetime.utcnow() - derniere_fin).total_seconds() / 60
print(f"{view.name}: dernière matérialisation il y a {age:.1f} min")
Un décrochage brutal (par exemple, d'un coup 3 h de retard alors que l'intervalle est de 5 min) indique une panne du pipeline — à surveiller autant que les erreurs HTTP du service.
Choisir la fréquence
Il n'y a pas de bon intervalle universel : il y a un arbitrage entre qualité et coût.
- Une matérialisation trop fréquente sur une variable stable gaspille du calcul.
- Une matérialisation trop espacée sur une variable volatile fait dériver le modèle.
La règle pratique : la fréquence de matérialisation doit être inférieure ou égale à la moitié de la fenêtre d'agrégation. nb_transactions_1h sur une matérialisation horaire n'a plus qu'un point utile ; il faut matérialiser toutes les 15 à 30 min. montant_moyen_30j matérialisé chaque semaine est raisonnable.
Une seconde règle : la fenêtre de fraîcheur (ttl) de la vue doit dépasser l'intervalle de matérialisation. Sinon, un porteur inactif verra sa variable expirer entre deux calculs et être renvoyée à NULL en production alors qu'elle avait une valeur légitime.
Coût, budget, décisions
Sur un scoreur de fraude à 100 millions de transactions par jour, la matérialisation représente typiquement 60 à 80 % du coût de calcul du magasin. Trois leviers pour la réduire.
Matérialisation incrémentale. Recalculer les 24 dernières heures à chaque exécution horaire fait 24× le travail nécessaire. Un moteur bien réglé lit uniquement les événements nouveaux et met à jour l'état par différence. Feast le fait via des stream feature views ; sur BigQuery, on écrit un MERGE incrémental.
Filtrage sur les entités actives. Sur 10 millions de porteurs, 200 000 sont actifs sur une fenêtre d'une heure. Recalculer les 9,8 millions restants gaspille 98 % du coût. La règle est : ne matérialiser une variable que pour les entités impliquées dans un événement récent.
Partition par fraîcheur. Séparer physiquement les variables très fréquentes des variables lentes évite qu'une matérialisation coûteuse ralentisse le tout. En pratique, deux ou trois profils de fréquence suffisent.
La chute silencieuse d'un pipeline de matérialisation est le mode de défaillance le plus coûteux d'un magasin. Une alerte sur la fraîcheur qui dépasse trois fois l'intervalle nominal se lève avant que la performance du modèle ne diverge, là où une alerte sur la métrique aval arrive trop tard.
En résumé
- La matérialisation applique la définition, écrit un point historique dans le hors ligne et écrase la ligne courante en ligne — les deux magasins restent synchrones.
- Deux régimes : par lots pour les variables lentes, en flux pour les variables volatiles ; les deux cohabitent dans un même magasin.
- La fraîcheur est mesurée en trois points ; sa somme borne la latence effective de la variable.
- Le coût dominant se réduit par matérialisation incrémentale, filtrage sur les entités actives et partition par fraîcheur.
Module suivant : Feast en pratique — le dépôt, apply, l'entraînement et le service, sur le fil rouge de la fraude, avec Parquet et Redis en local.