Appariement de produits : Similarité sémantique avec score de découverte
Cet article explique comment nous appairons des clusters de requêtes de recherche à des produits, pièces et articles en utilisant la similarité sémantique avec un modèle de score de découverte optionnel qui équilibre la pertinence, le trafic et le classement de page.
Le problème : Trouver la meilleure correspondance
Lorsque les utilisateurs recherchent "mini pc", nous devons déterminer quelle page produit représente le mieux cette requête. Nous avons des milliers de produits, pièces et articles—lequel devrions-nous afficher ?
Le défi est d'équilibrer plusieurs facteurs :
-
Pertinence sémantique : Dans quelle mesure la page correspond-elle au sens de la requête ?
-
Trafic de la requête : Combien de trafic de recherche cette requête génère-t-elle ?
-
Popularité de la page : Combien de trafic la page reçoit-elle déjà ?
Une approche naïve (similarité sémantique pure) pourrait associer "mini pc" à un produit obscur avec une similarité parfaite mais un trafic nul. Une meilleure approche prend en compte les trois facteurs.
Deux modes d'appariement
Nous prenons en charge deux modes d'appariement :
1. Appariement en masse (Original)
Chaque cluster trouve sa meilleure correspondance indépendamment. Plusieurs clusters peuvent correspondre à la même page :
-
Cluster A : "mini pc" → Produit X (similarité 0,95)
-
Cluster B : "petit ordinateur" → Produit X (similarité 0,93)
-
Cluster C : "bureau compact" → Produit X (similarité 0,91)
Cela crée de la redondance mais garantit que chaque cluster obtient sa meilleure correspondance.
2. Routage exclusif itératif (Cartographie 1:1)
Les clusters sont traités par score de trafic (le plus élevé d'abord). Une fois qu'une page est attribuée, elle est retirée du pool :
-
Cluster A (10K trafic) : "mini pc" → Produit X (attribué)
-
Cluster B (5K trafic) : "petit ordinateur" → Produit Y (X indisponible)
-
Cluster C (2K trafic) : "bureau compact" → Produit Z (X, Y indisponibles)
Cela crée des pages de requête uniques avec un repli automatique sur les correspondances suivantes les meilleures.
L'algorithme : Similarité sémantique
Étape 1 : Charger les embeddings
Nous chargeons les embeddings pré-calculés pour :
- Clusters de requêtes : Requête centrale de chaque cluster
- Pages sources : Produits, pièces, articles (depuis l'Étape 0)
Les deux utilisent le même modèle all-mpnet-base-v2, garantissant des embeddings comparables.
Étape 2 : Calculer la similarité
Pour chaque cluster, nous calculons la similarité cosinus avec toutes les pages sources :
similarities = util.cos_sim(cluster_embedding, source_embeddings)[0]
Cela produit un score de similarité (0,0 à 1,0) pour chaque page source.
Étape 3 : Appliquer le score de découverte (Optionnel)
Si le score de découverte est activé, nous combinons trois facteurs :
Modèle de score de découverte 50:30:20 :
discovery_score = (similarity * 0.5) + (query_score * 0.3) + (page_rank * 0.2)
Où :
-
Similarité (50%) : Pertinence sémantique (similarité cosinus)
-
Score de requête (30%) : Trafic de requête normalisé (impressions + clics)
-
Classement de page (20%) : Trafic de page normalisé (échelle logarithmique)
Cela équilibre la pertinence avec le potentiel de trafic.
Étape 4 : Normaliser les scores
Avant de combiner, nous normalisons chaque composante à [0, 1] :
Normalisation du score de requête :
max_query_score = max(cluster.total_score for cluster in clusters)
norm_query_score = query_score / max_query_score
Normalisation du classement de page (logarithmique pour empêcher les pages à fort trafic de dominer) :
max_page_rank = max(traffic_index.values())
norm_page_rank = log1p(page_rank) / log1p(max_page_rank)
La mise à l'échelle logarithmique empêche la page d'accueil (trafic le plus élevé) de dominer tous les appariements.
Étape 5 : Appliquer le bonus châssis (Produits uniquement)
Pour les appariements de produits, nous boostons les scores en fonction du type de châssis :
-
Châssis Treo : +10% (le plus récent, le plus populaire)
-
Châssis S : +5% (format compact, forte demande)
-
Châssis H : Pas de bonus (plus ancien, moins populaire)
if matched_type == "product":
sku = matched_key.replace("/p/", "")
chassis_prefix = sku.split("-")[0]
if chassis_prefix.startswith("Treo"):
similarity *= 1.10
elif chassis_prefix.startswith("S"):
similarity *= 1.05
Cela garantit que les produits plus récents sont priorisés lorsque la similarité est proche.
Étape 6 : Sélectionner la meilleure correspondance
Appariement en masse :
best_idx = similarities.argmax()
if similarities[best_idx] >= threshold:
matches.append(cluster → source_pages[best_idx])
Routage exclusif :
# Trier les clusters par trafic (le plus élevé d'abord)
sorted_clusters = sorted(clusters, key=lambda c: c.total_score, reverse=True)
# ... (détails d'implémentation omis)
Seuil configurable
Le seuil d'appariement détermine la rigueur de l'appariement :
-
0,80 (par défaut) : Rigueur modérée, la plupart des clusters correspondent
-
0,85 : Plus strict, moins de correspondances mais de meilleure qualité
-
0,75 : Plus indulgent, plus de clusters correspondent
Le seuil peut être ajusté sans changement de code via le fichier de configuration.
Mode d'analyse de seuil
Avant d'exécuter le pipeline complet, nous pouvons analyser l'impact du seuil :
python 6_match_source_data.py --analyze-threshold
Cela génère des échantillons à travers des plages de similarité :
-
0,90-1,00 : Correspondances parfaites
-
0,80-0,90 : Correspondances fortes
-
0,70-0,80 : Correspondances modérées
-
0,60-0,70 : Correspondances faibles
-
0,50-0,60 : Correspondances très faibles
-
0,40-0,50 : Mauvaises correspondances
Une interface web affiche ces échantillons pour une revue manuelle. Après avoir sélectionné un seuil, reprenez le pipeline :
python 6_match_source_data.py --resume-after-threshold
Cela charge le seuil depuis la décision de l'interface et complète l'appariement.
Embedding incrémental
Nous mettons en cache les embeddings pour les requêtes et les pages sources. Lorsque de nouvelles données arrivent :
- Charger les embeddings existants
- Embedder uniquement les nouveaux éléments
- Les ajouter au cache
Cela évite de ré-embeder des données inchangées. Voir Stratégie d'embedding pour plus de détails.
Format de sortie
L'appariement produit un fichier JSON avec des statistiques et des correspondances :
{
"stats": {
"threshold": 0.80,
# ... (détails d'implémentation omis)
Les correspondances sont triées par similarité (la plus élevée d'abord).
Pourquoi un score de découverte ?
La similarité sémantique pure a des limites :
Problème 1 : Produits obscurs
-
Requête : "mini pc" (10K trafic)
-
Meilleure correspondance : Produit obscur (similarité 0,98, 0 trafic)
-
Meilleure correspondance alternative : Produit populaire (similarité 0,95, 5K trafic)
Problème 2 : Inadéquation du trafic
-
Requête à fort trafic → Page à faible trafic (opportunité gaspillée)
-
Requête à faible trafic → Page à fort trafic (inutile)
Solution du score de découverte :
-
Équilibre la pertinence (50%) avec le potentiel de trafic (30% + 20%)
-
Les requêtes à fort trafic correspondent aux pages à fort trafic
-
Les requêtes à faible trafic correspondent aux pages de niche
-
Maximise la distribution globale du trafic
Caractéristiques de performance
Sur un serveur typique :
-
Temps de traitement : ~20 minutes pour 12,5K clusters × 5K pages sources
-
Utilisation mémoire : ~1 Go (embeddings + matrice de similarité)
-
Utilisation CPU : Élevée pendant le calcul de similarité
Le processus est limité par le CPU. L'utilisation de NumPy avec l'accélération BLAS accélère significativement les opérations matricielles.
Intégration avec le pipeline SEO
L'appariement de produits est l'Étape 6 du pipeline SEO :
- Étape 0 : Embed Source Data - Produits, pièces, articles
- Étape 1 : Fetch Queries - GSC, Google Ads, live, Algolia
- Étape 2 : Combine Queries - Fusionner toutes les sources
- Étape 3a : Generate Base Phrase Mappings - Filtres initiaux
- Étape 3b : Embed Queries - Convertir en vecteurs
- Étape 4 : Expand Phrase Mappings - Trouver des phrases similaires
- Étape 5 : Cluster Queries - Grouper en pages
- Étape 6 : Match Products ← Vous êtes ici
- Étape 7 : Build Query Pages - Générer du HTML
- Étape 8 : Generate Related Searches - Trouver des requêtes connexes
- Étape 11 : Migrate to Valkey - Charger dans le service de recherche
Voir SEO Pipeline Overview pour le flux complet.
En masse vs Exclusif : Lequel utiliser ?
Appariement en masse (original) :
-
✅ Chaque cluster obtient sa meilleure correspondance
-
✅ Simple, prévisible
-
❌ Pages de requête redondantes (plusieurs clusters → même produit)
-
❌ Potentiel de trafic gaspillé
Routage exclusif (1:1) :
-
✅ Pages de requête uniques (pas de redondance)
-
✅ Repli automatique sur les correspondances suivantes
-
✅ Meilleure distribution du trafic
-
❌ Les clusters à faible trafic peuvent obtenir des correspondances sous-optimales
-
❌ Logique plus complexe
Recommandation : Utiliser le Routage exclusif pour la production. Cela crée des pages de requête uniques et de haute qualité avec une meilleure distribution du trafic.
Index de trafic et mise à l'échelle logarithmique
L'index de trafic suit les pages vues pour toutes les pages sources :
{
"/p/Treo-N100-8-256-2H-W6-11P": 5000,
"/p/S-i5-16-512-2H-W6-11P": 3000,
"/": 50000
}
Nous utilisons la mise à l'échelle logarithmique pour empêcher les pages à fort trafic de dominer :
norm_page_rank = log1p(page_rank) / log1p(max_page_rank)
Sans cela, la page d'accueil (50K trafic) correspondrait à chaque requête. La mise à l'échelle logarithmique compresse la plage, donnant à toutes les pages une chance équitable.
Raisonnement du bonus châssis
Nous boostons les produits des châssis Treo et S car :
-
Treo : Châssis le plus récent, meilleures fonctionnalités, demande la plus élevée
-
Châssis S : Facteur de forme compact, populaire pour les mini PC
-
Châssis H : Plus ancien, en cours de retrait
Lorsque la similarité est proche (par exemple, 0,90 vs 0,89), le bonus garantit que les produits plus récents l'emportent. Cela correspond aux priorités commerciales.
Références
Concepts techniques
-
Semantic Similarity - Wikipedia
-
Cosine Similarity - Wikipedia
-
Logarithmic Scale - Wikipedia
-
NumPy - Documentation officielle
-
BLAS - Wikipedia
Documentation du modèle
-
all-mpnet-base-v2 - Hugging Face
-
Sentence Transformers - Documentation officielle
Articles connexes
-
Embedding Strategy - Comment nous générons les embeddings
-
Query Clustering - Regroupement de requêtes similaires
-
SEO Pipeline Overview - Architecture complète du pipeline
-
Related Search Generation - Trouver des requêtes connexes
-
Embed Source Data - Embedding de produits, pièces, articles
Résumé
Nous appairons des clusters de requêtes à des produits en utilisant la similarité sémantique avec un score de découverte optionnel :
Similarité sémantique :
-
Calculer la similarité cosinus entre les embeddings de requête et de source
-
Appariement basé sur un seuil (par défaut 0,80)
-
Bonus châssis pour Treo (+10%) et S-châssis (+5%)
Score de découverte (50:30:20) :
-
50% pertinence sémantique (similarité cosinus)
-
30% trafic de requête (impressions + clics normalisés)
-
20% classement de page (mise à l'échelle logarithmique)
Deux modes :
-
En masse : Chaque cluster obtient la meilleure correspondance (redondance autorisée)
-
Exclusif : Cartographie 1:1, clusters à fort trafic d'abord (pas de redondance)
Analyse de seuil :
-
Générer des échantillons à travers des plages de similarité
-
Revue manuelle via interface web
-
Reprendre le pipeline avec le seuil sélectionné
Le résultat est un appariement de haute qualité entre requêtes et produits qui équilibre la pertinence sémantique avec le potentiel de trafic, créant des pages de requête optimisées pour le SEO.