LIKYLYMoteur de recommandations

Naviguez, regardez vos recommandations changer

Session · sans compte

Cliquez sur une affiche pour ouvrir sa fiche produit — une vraie page, avec sa propre URL. Le bloc « Vous aimerez aussi » se met à jour à chaque fiche consultée, en fonction de qui navigue (changez de profil en haut à droite).

Persona

Visiteur anonyme qui navigue sur plusieurs fiches produit de votre site pendant sa visite — pas de compte, pas de connexion, juste ce qu'il vient de regarder.

Classement des ventes réelles du catalogue - le vrai critère "populaire".

Cold start — sans profil utilisateur

Content-based

Similarité de contenu (synopsis, genre) et popularité réelle — le nombre d'achats déjà réalisés par l'ensemble de vos clients sur chaque produit. Ce n'est donc pas un classement à l'aveugle : il n'y a simplement pas d'historique personnel pour ce visiteur précis.

Persona

Visiteur anonyme sur une fiche produit — première visite, aucun compte. C'est le cas le plus fréquent sur un site e-commerce : la majorité du trafic n'est pas connectée.

Pourquoi recommande-t-on ces produits ?

Explication content-based

Le moteur compare le synopsis, le genre et les mots-clés du produit consulté à ceux de tout le catalogue. Plus la barre est pleine, plus le contenu se ressemble ; le badge doré signale un genre identique.

Niveau de similarité : Similarité forte ≥ 66 % du meilleur score de cette liste Similarité moyenne 33 à 66 % Similarité faible < 33 %

Le niveau est relatif à la meilleure recommandation trouvée pour cette recherche, pas à une échelle absolue — nécessaire car les scores de contenu, de collaboratif et d'hybride ne vivent pas sur la même échelle numérique.

Filtrage collaboratif — utilisateur connu

ALS · Alternating Least Squares

ALS (Alternating Least Squares) est un algorithme de factorisation matricielle : il apprend, à partir des achats/vues de tous les utilisateurs, des profils de goûts latents — sans jamais regarder le contenu des produits. Deux personnes qui achètent les mêmes choses se retrouvent « proches », même si leurs achats semblent variés à l'œil nu.

Persona

Utilisateur connu : sur votre site, ça signifie un visiteur identifié/loggué, dont vous connaissez l'historique d'achats. Dans cette démo, on simule cela via un profil sélectionnable — mais c'est exactement l'historique qu'un vrai compte client apporterait.

Comment détecte-t-on des goûts similaires ?

Mécanique collaborative

Deux utilisateurs, deux historiques d'achats. Le moteur ne connaît rien du contenu des produits — il repère seulement que les mêmes titres reviennent chez les deux, et en déduit un goût commun.

Détail technique

Sous le capot : la factorisation matricielle ALS

Chaque paire (utilisateur, produit) est résumée par un seul score de confiance : confiance = 3.0 × nb achats + 0.2 × nb vues. Un achat pèse donc 15 fois plus qu'une simple consultation de fiche. L'ensemble forme une matrice creuse R (utilisateurs × produits), très majoritairement composée de zéros — la plupart des utilisateurs n'ont interagi qu'avec une infime fraction du catalogue.

ALS (Alternating Least Squares) cherche à approximer R par le produit de deux matrices bien plus petites : un vecteur de 64 nombres par utilisateur (X) et un vecteur de 64 nombres par produit (Y), tels que R[u, i] ≈ Xu · Yi (produit scalaire). Ces 64 dimensions n'ont pas de sens explicite prédéfini (ce ne sont pas « genre », « année », etc.) — l'algorithme les découvre lui-même en cherchant la meilleure reconstruction possible des interactions observées.

minX, Y   Σu,i cui (rui − Xu · Yi)²  +  λ ( Σu ‖Xu‖² + Σi ‖Yi‖² )

« Alternating » : on fixe Y et on résout X par moindres carrés (solution analytique fermée), puis on fixe X et on résout Y, en alternant sur 20 itérations jusqu'à stabilisation. Le terme λ = 0.01 pénalise les vecteurs trop grands, pour éviter le sur-apprentissage sur les utilisateurs à faible historique.

Une fois entraînés, X et Y permettent de tout calculer : le score d'une recommandation est Xu · Yi, et la vraie proximité entre deux utilisateurs serait le cosinus de l'angle entre Xu et Xv. Sur cette page, on affiche à la place le recoupement direct des achats communs — plus lisible pour expliquer l'intuition, et cohérent avec ce que fait réellement ALS : deux utilisateurs qui achètent souvent les mêmes titres se voient naturellement attribuer des vecteurs proches, puisque c'est exactement ce qui minimise l'erreur de reconstruction pour eux deux.

Hybride — contenu + collaboratif

Pondérable

Mélange les deux signaux avec un poids réglable. Déplacez le curseur pour voir le classement se réorganiser en direct entre similarité de contenu et goûts collaboratifs.

Persona

Utilisateur connu qui consulte une fiche produit précise — on combine ce qu'il regarde maintenant avec ce que son historique dit de lui.

0.5

Comment le moteur est construit

Vue technique

Cette page résume l'architecture qui fait tourner les 6 onglets précédents et le suivi de modèle qui suit celle-ci : comment le moteur est découplé de n'importe quelle interface, comment chaque client est isolé des autres, et quels sont les leviers concrets pour l'améliorer dans le temps.

Cette démo en est la preuve : la page que vous utilisez ne parle jamais directement au code Python — elle appelle uniquement le SDK JavaScript/TypeScript, qui appelle l'API par HTTP. N'importe quel autre front (site e-commerce, application mobile, outil interne) peut brancher le même SDK, ou l'un des deux autres (PHP, Python), sans jamais toucher au moteur lui-même.

Site e-commercecette démo
Application mobileiOS / Android
Backend internebatch, autre outil
↓
SDK PHPComposer
SDK JS / TypeScriptzéro dépendance
SDK Pythonsync + async
↓
API REST (FastAPI)1 point d'entrée · clé API → client_id
↓
Moteur de recommandationCold start · Collaboratif (ALS) · Hybride · Session
↓
PostgreSQLcatalogue, utilisateurs, événements, embeddings (pgvector)

L'intérêt commercial de cette séparation : on peut refaire entièrement l'interface (ou en brancher une nouvelle, dans un autre langage) sans toucher au moteur ; on peut faire évoluer le moteur (nouvel algorithme, nouveau modèle) sans casser les intégrations existantes, tant que le contrat de l'API ne change pas.

Cas d'usage Signal utilisé Historique requis Voir la page
Cold start Contenu du produit consulté : mots partagés (TF-IDF) + similarité sémantique (embeddings pgvector) Aucun « Pourquoi ? »
Session Contenu, pondéré par récence, sur les derniers produits vus Session en cours seulement « En direct »
Collaboratif Comportement croisé de tous les utilisateurs (ALS) Compte identifié « Utilisateurs similaires »
Hybride Contenu + comportement, mélangés avec un poids réglable Compte identifié « Hybride »

Une seule API et une seule infrastructure servent tous les clients, mais rien n'est partagé entre eux : chaque client a ses propres lignes en base (scoped par client_id), son propre modèle ALS entraîné sur ses seules données (model/client_{id}/*.npz), et ses propres embeddings sémantiques (colonne vector dans PostgreSQL via pgvector, filtrée par client_id) — pas un index vectoriel séparé à gérer par client.

Une seule API, une seule infrastructure
↓
Client A
PostgreSQLlignes client_id = A
Modèle ALSmodel/client_A/*.npz
Embeddings pgvectorcolonne vector, client_id = A
Client B
PostgreSQLlignes client_id = B
Modèle ALSmodel/client_B/*.npz
Embeddings pgvectorcolonne vector, client_id = B

Le cycle est le même que pour n'importe quel moteur collaboratif : plus les clients de votre client achètent/consultent de produits, plus le modèle a de signal pour apprendre. La différence ici : un nouveau modèle n'est jamais mis en production seul sur la base de son entraînement — il est d'abord mesuré, comparé à la version actuellement active, et rejeté automatiquement s'il est moins bon.

Achats & vuesévénements
→
Matrice de confiancePostgreSQL
→
Entraînement + évaluationprecision@10 sur un lot de test
→
Comparaison au modèle actifpromu seulement si meilleur ou égal
→
Recommandations servies/getRec/*

↺ Déclenchement automatique dès que 50 nouvelles interactions s'accumulent depuis le dernier entraînement — plus besoin d'appeler /generateModel à la main.

Déjà en place
  • Ré-entraînement déclenché automatiquement par volume d'interactions (50 nouvelles depuis la dernière version), pas par un cron aveugle.
  • Chaque nouvelle version est évaluée (precision@10 sur un lot mis de côté) et n'est promue en production que si elle égale ou dépasse la version active — sinon elle reste archivée, visible dans « Suivi du modèle ».
  • Historique complet des versions par client et par catalogue, avec hyperparamètres et score, versionné en fichier (pas d'écrasement) - onglet « Suivi du modèle ».
  • Suivi MLflow auto-hébergé (métriques, artefacts, registre de modèle avec alias production) en complément, pour l'inspection interne.
  • Repli automatique sur la popularité quand un produit n'a ni contenu ni historique exploitable.
  • Similarité de contenu hybride texte + sémantique : TF-IDF (mots partagés, explicable) mélangé à des embeddings pgvector (SentenceTransformer, capte aussi les synopsis reformulés différemment) - calculés une fois à l'ingestion, pas à chaque requête.
  • Remplacer le suivi des jobs en mémoire par un stockage partagé (base/Redis) - utile seulement au-delà d'un seul process/worker, pas nécessaire à l'échelle actuelle.
  • Mesurer un vrai indicateur business (clics/achats sur les recommandations) en plus de la précision hors-ligne.
  • Ajouter un index ANN (HNSW) sur les embeddings pgvector si un catalogue client grossit assez pour que la recherche exacte devienne lente.

Suivi du modèle dans le temps

Gouvernance & versions

Chaque réentraînement est mesuré avant d'être mis en production : une nouvelle version n'est jamais servie si elle est moins bonne que celle déjà active. Voici l'historique réel des versions du modèle collaboratif (films), avec leur score de précision et leurs hyperparamètres — pas une maquette, ces données viennent de la même API que le reste de cette démo.

Version Entraîné le Facteurs Régularisation Itérations Precision@10 Statut