Gestion des données produits unifiée

Le PIM nouvelle génération basé sur graphe de connaissances

01

📊 Contexte et enjeux

Les données produits sont le cœur de l'entreprise moderne. Pourtant, elles sont souvent éparpillées entre ERP, PIM, CMS, Excel, fournisseurs, canaux de vente. Résultat : incohérences, doublons, mauvaise qualité, et une expérience client dégradée.

30%
des données produits sont erronées
8+
sources différentes par produit
20%
de chiffre d'affaires perdu par mauvaise qualité
50%
du temps en nettoyage de données
💡 L'opportunité : Un graphe de connaissances unifie toutes les sources en une seule vue cohérente, avec des relations sémantiques entre produits, fournisseurs, catégories, attributs.
02

❌ Le défi : données produits en silos

🏭 ERP
Prix, stock, fournisseurs
📦 PIM
Descriptions, attributs, médias
🌐 CMS
Contenu web, SEO, landing pages
📊 Excel
Données marketing, promotions
🏷️ GDSN
Données fournisseurs externes
🛒 Marketplace
Amazon, Cdiscount, eBay
⚠️ Problèmes concrets :
  • Le même produit a des noms différents selon les canaux ("iPhone 13" vs "Apple iPhone 13 128GB")
  • Les attributs techniques sont incohérents (cm vs pouces, kg vs livres)
  • Les relations produits (compatibilité, accessoires, substituts) sont implicites
  • Les mises à jour produit prennent des jours (changer un prix dans 8 systèmes)
  • Impossible de répondre à "quels produits sont compatibles avec X ?"
03

🧠 Solution : PIM sémantique sur graphe

🏗️ Architecture du PIM sémantique :

┌─────────────────────────────────────────────────────────┐
│ SOURCES (hétérogènes) │
│ ERP │ PIM legacy │ Excel │ Fournisseurs │ API externes │
└─────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ COUCHE D'INTÉGRATION │
│ Mapping │ Transformation │ Déduplication │ Enrichissement │
└─────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ GRAPHE DE CONNAISSANCES PRODUITS │
│ Ontologie produit │ Relations │ Inférences │ Traçabilité │
└─────────────────────────────────────────────────────────┘

┌──────────┬──────────┼──────────┬──────────┐
▼ ▼ ▼ ▼ ▼
Site web App mobile Marketplaces API Dashboard

Ontologie produit universelle

@prefix : <http://product.example.org/ontology#> .
@prefix schema: <https://schema.org/> .
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .

# Classes principales
:Produit a owl:Class ;
    rdfs:subClassOf schema:Product .

:Catégorie a owl:Class ;
    rdfs:subClassOf skos:Concept .

:Attribut a owl:Class .
:ValeurAttribut a owl:Class .
:Fournisseur a owl:Class .
:Marque a owl:Class .
:Accessoire a owl:Class ; rdfs:subClassOf :Produit .

# Relations
:appartientÀCatégorie a owl:ObjectProperty ;
    rdfs:domain :Produit ;
    rdfs:range :Catégorie .

:aPourAttribut a owl:ObjectProperty ;
    rdfs:domain :Produit ;
    rdfs:range :Attribut .

:estCompatibleAvec a owl:ObjectProperty ;
    rdfs:domain :Produit ;
    rdfs:range :Produit ;
    owl:symmetric true .

:estSubstitutDe a owl:ObjectProperty ;
    rdfs:domain :Produit ;
    rdfs:range :Produit .

:estAccessoireDe a owl:ObjectProperty ;
    rdfs:domain :Accessoire ;
    rdfs:range :Produit .

:estFourniPar a owl:ObjectProperty ;
    rdfs:domain :Produit ;
    rdfs:range :Fournisseur .

# Règle : Compatibilité transitive
[ (:estCompatibleAvec ?a ?b), (:estCompatibleAvec ?b ?c) -> (:estCompatibleAvec ?a ?c) ]

# Règle : Si produit compatible, ses accessoires le sont aussi
[ (:estAccessoireDe ?a ?p), (:estCompatibleAvec ?p ?q) -> (:estCompatibleAvec ?a ?q) ]
04

⚙️ Architecture technique

Pipeline d'intégration multi-sources

class ProductKnowledgeGraph:
    def __init__(self, kg, llm, embedding_model):
        self.kg = kg
        self.llm = llm
        self.embedder = embedding_model
    
    def integrate_product(self, source_data, source_type):
        """Intègre un produit depuis n'importe quelle source"""
        
        # 1. Normalisation et nettoyage
        normalized = self.normalize(source_data, source_type)
        
        # 2. Recherche de correspondance (déduplication)
        existing = self.find_matching_product(normalized)
        
        if existing:
            # Fusion avec données existantes
            product_id = existing['id']
            self.merge_product(product_id, normalized)
        else:
            # Création nouveau produit
            product_id = self.create_product(normalized)
        
        # 3. Enrichissement automatique
        self.enrich_product(product_id)
        
        # 4. Détection des relations
        self.discover_relations(product_id)
        
        return product_id
    
    def normalize(self, data, source_type):
        """Normalisation selon source"""
        mapping = {
            'erp': self.map_erp_to_ontology,
            'pim': self.map_pim_to_ontology,
            'excel': self.map_excel_to_ontology,
            'supplier': self.map_supplier_to_ontology
        }
        return mapping[source_type](data)
    
    def find_matching_product(self, product):
        """Détection de doublons par similarité sémantique + règles"""
        # Recherche par identifiant unique (EAN, SKU)
        if product.get('ean'):
            existing = self.kg.query(f"""
                SELECT ?p WHERE {{
                    ?p :aPourEAN "{product['ean']}" .
                }}
            """)
            if existing:
                return existing[0]
        
        # Recherche par similarité du nom
        product_embedding = self.embedder.encode(product['name'])
        candidates = self.vector_db.similarity_search(product_embedding, k=5)
        
        for candidate in candidates:
            score = self.calculate_match_score(product, candidate)
            if score > 0.85:
                return candidate
        
        return None
    
    def enrich_product(self, product_id):
        """Enrichissement via LLM et sources externes"""
        product = self.kg.get_product(product_id)
        
        # Génération de description SEO
        seo_desc = self.llm.generate(f"""
            Génère une description SEO pour ce produit (150-160 caractères):
            Nom: {product['name']}
            Catégorie: {product['category']}
            Attributs: {product['attributes']}
        """)
        
        # Classification automatique dans catégories
        categories = self.llm.classify(product['name'], self.kg.get_categories())
        
        # Mise à jour du graphe
        self.kg.insert(f"""
            :{product_id} :aPourDescriptionSEO "{seo_desc}" ;
                :appartientÀCatégorie :{categories[0]} .
        """)
    
    def discover_relations(self, product_id):
        """Détection automatique des relations produits"""
        product = self.kg.get_product(product_id)
        
        # Compatibilité technique (via attributs)
        compatible = self.kg.query(f"""
            SELECT ?other WHERE {{
                ?other a :Produit .
                ?other :aPourAttribut ?attr .
                FILTER(?attr IN ({product['technical_attrs']}))
                FILTER(?other != :{product_id})
            }}
        """)
        
        for comp in compatible:
            self.kg.insert(f":{product_id} :estCompatibleAvec :{comp['id']}")
        
        # Accessoires suggérés
        accessories = self.llm.suggest_accessories(product['name'], product['category'])
        for acc in accessories:
            self.kg.insert(f":{acc} :estAccessoireDe :{product_id}")
05

🎯 Cas d'usage concrets

🔍 Scénario 1 : Unification cross-canal
Problème : Le même produit a des prix différents sur site web, app mobile, et marketplaces.
Solution : Le graphe centralise la référence produit unique. Une mise à jour de prix se propage à tous les canaux en temps réel.
Résultat : Fin des incohérences, +15% de confiance client.
🔧 Scénario 2 : Compatibilité produits
Problème : "Quels câbles sont compatibles avec mon téléviseur ?"
Solution : Le graphe navigue les relations de compatibilité (connectique, puissance, version).
Résultat : Recommandation précise en millisecondes, +25% de panier moyen.
🏷️ Scénario 3 : Enrichissement automatique
Problème : 50 000 produits avec descriptions incomplètes.
Solution : LLM + graphe génèrent descriptions SEO, attributs manquants, catégories.
Résultat : 100% des produits enrichis en 2 jours (vs 6 mois manuellement).
📊 Scénario 4 : Analyse de gamme
Problème : "Quels produits sont en doublon avec les fournisseurs ?"
Solution : Requête SPARQL détecte les produits identiques de fournisseurs différents.
Résultat : Optimisation du sourcing, -12% de coût d'achat.
🔄 Scénario 5 : Gestion de cycle de vie
Problème : "Quels produits sont remplacés par quelles nouvelles références ?"
Solution : Propriété :remplacéPar dans le graphe.
Résultat : Site web suggère automatiquement les nouveaux produits, stock épuisé redirigé.
06

💰 Bénéfices et ROI

-90%
temps de mise à jour produit
+35%
panier moyen (recommandations)
-50%
erreurs catalogue
6 mois
amortissement
📈 Cas réel : Distributeur électronique (100 000 produits)
  • Avant : 12 équipes, 8 systèmes, 3 semaines pour lancer un produit
  • Après (graphe unifié) : 1 équipe, 1 vue, 2 jours pour lancer un produit
  • Réduction des coûts : -60% sur la gestion catalogue
  • Augmentation CA : +18% grâce aux recommandations compatibilité
  • ROI : 520% la première année
🏆 Autres bénéfices :
  • ✅ Vue 360° du produit (toutes sources en un lieu)
  • ✅ Détection automatique des anomalies (prix, stock, attributs)
  • ✅ Traçabilité des modifications (qui, quand, pourquoi)
  • ✅ Interopérabilité avec partenaires (API standard)
  • ✅ Base pour IA recommandation / recherche sémantique
07

💬 Témoignage client

🎤 Boulanger - Directrice des Données Produits
"Nous avions 15 sources de données produits différentes, avec des incohérences massives. Le graphe de connaissances a unifié le tout en 6 mois. Aujourd'hui, un changement de prix se propage en 5 secondes sur tous nos canaux. Et nos clients bénéficient de recommandations compatibilité ultra-précises."