Produktempfehlung

Produktempfehlung ist ein KI-Modell zur Produktempfehlung pro Kunde auf Basis historischer Käufe.
Aus Kaufdaten werden Trainingsbeispiele erzeugt (gekauft = positiv, nicht gekauft = negativ), ein Modell trainiert und anschließend für einen Kunden eine Top-N-Liste empfohlener Produkte berechnet.

Das Modell kann sowohl zeitgesteuert (Training) als auch AdHoc (Vorhersage für eine CustomerId) ausgeführt werden.


Konzept

Datenbasis

Als Quelle dient eine Abfrage (Query) auf Verkaufs-/Belegdaten. Die wichtigsten Felder werden der Modelllogik zugeordnet:

  • CustomerId (Kunde)
  • ProductId (Produkt)
  • ProductFamily (Warengruppe/Produktfamilie)
  • Timestamp (Kaufdatum für Zeitfilter)
  • optional: Industry (Branche)
  • optional: Country (Land)

Die Quelldaten werden in einer Support-DB zwischengespeichert, sodass Training und Aggregationen performant laufen.

Features (Eingangsmerkmale)

Pro (Kunde, Produkt)-Kombination werden folgende Merkmale genutzt:

  1. Kunden-ID (kategorisch, OneHot)
  2. Branche (kategorisch, OneHot)
  3. Land (kategorisch, OneHot)
  4. Produkt-ID (kategorisch, OneHot)
  5. Produktfamilie-ID (kategorisch, OneHot)
  6. CustomerBoughtFamily (bool → float)
    Ob der Kunde diese Familie bereits gekauft hat.
  7. CustomerFamilyPurchaseCount (float)
    Anzahl der Käufe dieser Familie durch den Kunden.

Hinweis: CustomerId und ProductId als OneHot können zu sehr guten Offline-Metriken führen, weil das Modell bekannte Kunden/Produkte “wiedererkennt”. Für realistische Qualitätsmessung sind gruppierte oder zeitbasierte Splits sinnvoll (siehe Abschnitt “Training & Metriken”).

Negative Beispiele (Negativ-Sampling)

Da echte “Nicht-Käufe” in der Regel nicht explizit vorliegen, werden Negativbeispiele synthetisch erzeugt:

  • Popularität: Negative kommen aus häufig gekauften Produkten (gewichtete Ziehung).
  • Assoziierte Produktfamilien: Negative kommen aus Produkten aus assoziierten Familien (Co-Occurrence auf Familienebene), mit Popularität als Fallback.

Einstellbare Parameter / Eigenschaften

Quelldaten

Quelldaten aktualisieren

Wenn aktiv, werden die zwischengespeicherten Quelldaten (model{ID}_sourcedata) beim Ausführen aktualisiert.


Trainingseinstellungen

Verfahren für Negativbeispiele

Steuert, wie Negativbeispiele erzeugt werden:

  • Popularität
    Negatives werden aus den beliebtesten Produkten gezogen.
  • Assoziierte Produktfamilien
    Zusätzlich wird aus Familien-Assoziationen gezogen (Land-spezifisch, sonst global). Kunde kauft aus Familie A und Familie B.

Zeitspanne für die Datenauswahl

Begrenzt die Positivbeispiele (Käufe) auf einen Zeitraum ab heute − Wert in Tagen.
Wenn im Zeitraum keine Daten gefunden werden, erfolgt ein Fallback ohne Zeitfilter.

Maximale Anzahl an Datensätzen für das Trainingsmodell

Maximale Anzahl geladener Positivbeispiele (Käufe) für das Training.
Die Anzahl an Trainingsdaten muss begrenzt sein, damit der Ressourceneinsatz kontrollierbar bleibt und das Ergebnis nicht leidet. Bei 500.000 Käufen und 5 negativen Beispielen ergeben sich 3.000.000 Trainingsdatensätze, was für ein ausgewogenes Trainingsmodell sorgt.

Maximale Anzahl an negativen Beispielen je Kauf

Anzahl Negativbeispiele, die pro Positivbeispiel erzeugt werden.

Poolgröße für populäre Produkte

Größe des Popularitäts-Pools:

  • beeinflusst Negativ-Sampling (PopularPool / Fallback)
  • beeinflusst Kandidaten-Erzeugung für Vorhersage (Auffüllen mit populären Produkten)

Vorhersageeinstellungen

Maximale Anzahl an Vorhersagen

Anzahl der zurückgegebenen Empfehlungen (Top-N). Je nach Datenlage können auch weniger Ergebnisse entstehen.

Vorhersagen zwischenspeichern

Wenn aktiv:

  • Vorhersagen werden in model{ID}_predictions gespeichert (Zwischenspeicher und Log)
  • spätere Aufrufe können gespeicherte Vorhersagen wiederverwenden
  • ein erneutes Training löscht zwischengespeicherte Vorhersagen

Quelle für Produktdaten

Optionales Schemaobjekt (Produkt-Stammdaten), um Vorhersagen um zusätzliche Spalten aus dem empfohlenen Produkt anzureichern.

Suche für Produktdaten

Filter (templated), um Produktdetails zu laden.
Der WhereClause kann Platzhalter nutzen, die aus der aktuellen Ergebniszeile ersetzt werden.

Beispiel-Idee: ProductId = '{ProductId}'


Experteneinstellungen

Trainingsdaten speichern

Wenn aktiv, werden Trainings-Samples in model{ID}_sampleslog gespeichert.
Dient Analysezwecken.

Kandidaten speichern

Wenn aktiv, werden Kandidaten pro Vorhersage in model{ID}_candidateslog gespeichert.
Dient Analysezwecken.


Nachverfolgen

Hier können mehrere Syncs ausgewählt werden, die über das Smart-Selling-Widget adhoc durch den Benutzer zu bestimmten Vorhersagen gestartet werden können.
Für eine einfache Konfiguration steht ein Konnektor für Modelle zur Verfügung, der Schemaobjekte je Modelltyp erzeugt. Hier können Syncs konfiguriert werden, die entweder mit einzelnen Vorhersagen oder einer geschachtelten Liste von Vorhersagen ausgeführt werden.

Datenhaltung

Beim ersten Lauf werden folgende Tabellen in der Support-DB erzeugt:

Tabellen

  • model{ID}_sourcedata
    Zwischenspeicher der Quelldaten (Käufe/Belege)

  • model{ID}_modeldata
    Enthält:

    • model_data: serialisiertes Modell
    • model_metrics: Evaluationsmetriken (JSON)
    • model_assoc_json: Hilfsdaten (Assoc + PopularPool + Produkt-Mappings) als JSON
  • model{ID}_sampleslog (nur Log, optional)
    Trainings-Samples (Featurewerte + Label)

  • model{ID}_candidateslog (nur Log, optional)
    Kandidatenliste pro CustomerId

  • model{ID}_predictions (Log + Cache, optional)
    gespeicherte Vorhersagen pro CustomerId

Views (Aggregationen)

  • vmodel{ID}_ProductPopularity
    Produktpopularität (ProductId, Family, Count)

  • vmodel{ID}_CustomerFamilyFeatures
    Familien-Käufe je Kunde (CustomerId, Family, Count)

  • vmodel{ID}_ProductsDistinct
    Distinct ProductId → Family


Ablauf: Training

Das Training wird ausgeführt, wenn der Starttyp nicht AdHoc ist (manuell oder zeitgesteuert).

1) Quelldaten vorbereiten

  • Wenn model{ID}_sourcedata nicht existiert:
    • Tabellen + Views erzeugen
    • Quelldaten importieren
  • Sonst:
    • Schema ggf. erweitern
    • Views neu erzeugen
    • optional Update (UpdateSourceDataOnExecute)

2) Trainingsdaten bauen

Positivbeispiele:

  • Laden von Käufen
  • optionaler Zeitfilter über letzte x Tage
  • Begrenzung über maximale Anzahl

Feature-Aggregate:

  • CustomerFamilyCounts: Familienkäufe je Kunde (nur Kunden aus den Positives)
  • ProductFamilyById: Produkt → Familie
  • ProductsByFamily: Familie → Liste Produkte
  • BoughtProductsByCustomer: Kunde → Set gekaufter Produkte
  • PopularSampler: gewichtete Ziehung aus PopularPool

Negativbeispiele pro Positivem:

  • abhängig von Verfahren
    • Assoziierte Produktfamilien: ziehe erst über Assoziationen (Land → Assoc, sonst global)
    • sonst / Fallback: ziehe über Popularität
  • Negatives werden nur akzeptiert, wenn das Produkt nicht in den Käufen des Kunden ist.

3) Optional: Logging

  • Trainingsdaten in model{ID}_sampleslog

4) Modelltraining (LightGBM)

Pipeline:

  • OneHotEncoding für CustomerId/Industry/Country/ProductId/Family
  • Convert bool/float Features
  • Feature Concatenate
  • LightGBM Binary Classification (Iterations 200, LR 0.05, Leaves 64, MinExamplesPerLeaf 20)

5) Testsplit & Metriken

  • Stratified Split: 20% der Positives und 20% der Negatives als Test
  • Evaluate:
    • AreaUnderRocCurve wird in der UI als Kennzahl ausgegeben (gerundet)

Hinweis zur Interpretation:
Der Split ist sample-basiert. CustomerIds/Products können in Train und Test vorkommen. Das kann Evaluations-Metriken deutlich “optimistischer” machen als ein echter Online-Betrieb.

6) Speichern

  • Modell wird serialisiert und in model{ID}_modeldata.model_data gespeichert
  • Metriken als JSON in model_metrics
  • Hilfsdaten (Assoc/PopularPool/Mappings) als JSON in model_assoc_json

Zusätzlich werden beim Training alte Vorhersagen/Kandidaten gelöscht:

  • TRUNCATE model{ID}_predictions
  • TRUNCATE model{ID}_candidateslog

Ablauf: Vorhersage / Empfehlung

Vorhersage kann auf zwei Arten passieren:

  • AdHoc-Start:
    • erwartet Parameter CustomerId
    • setzt intern SavePredictions = true
    • ruft Recommend(customerId, MaxPredictions) auf
  • Datenabruf über Widget
    • kann gespeicherte Vorhersagen verwenden (SavePredictions)
    • erzeugt ansonsten neue Vorhersagen via Recommend

1) Modell + Hilfsdaten laden

  • LoadModelBundle() lädt Modell und Hilfsdaten (aux JSON) aus modeldata
  • Falls Hilfsdaten fehlen: Fallback lädt PopularPool + Mappings aus Views

2) Kundenprofil laden

  • LoadCustomerProfileForRecommend(customerId):
    • liest bis zu 20.000 Käufe des Kunden
    • setzt Industry/Country aus erster Zeile
    • baut Sets:
      • BoughtProducts
      • BoughtFamilies
  • Zusätzlich: LoadCustomerFamilyCountsForCustomer(customerId) lädt Familienkaufzähler für Feature-Berechnung.

3) Kandidatenliste erzeugen

Ziel: Liste möglicher Produkte, die bewertet werden.

  • maxCandidates = max(500, maxRecommendations * 120)

3a) Kandidaten über assoziierte Familien (nur wenn NegativesType = AssociatedFamilies)

  • Bestimme AssocModel: zuerst land-spezifisch, sonst global
  • Für gekaufte Familien (FamilyA) werden assoziierte Familien (FamilyB) gesammelt
  • Pro FamilyB werden zufällig Produkte gezogen (perFamilyBLimit = 12)
  • Bereits gekaufte Produkte werden ausgeschlossen

3b) Auffüllen über Popularität

  • Populäre Produkte werden hinzugefügt, bis maxCandidates erreicht ist
  • Bereits gekaufte Produkte werden ausgeschlossen

Optional: LogCandidateData speichert Kandidaten in model{ID}_candidateslog.

4) Scoring (ML-Scoring pro Kandidat)

Für jeden Kandidaten wird ein RecommendationSample aufgebaut und via PredictionEngine bewertet. Es wird die Probability verwendet.

Interpretation Probability

  • Probability ist die kalibrierte Ausgabe des Binary-Classifiers für die “positive Klasse” (Label = gekauft).
  • Aufgrund synthetischer Negatives ist sie keine echte Kaufwahrscheinlichkeit, sondern ein Ranking-Score zur Sortierung der Kandidaten.

5) Erklärung (Explanation)

Wenn NegativesType = AssociatedFamilies und Assoc-Daten verfügbar sind:

  • Es wird eine Begründung über die beste passende Familien-Assoziation erzeugt:
    • „Kunden, die Familie A kaufen, kaufen häufig auch Familie B …“

Wenn keine passende Assoziation gefunden wird oder PopularOnly:

  • Erklärung basiert auf Score bzw. Popularität.

6) Ergebnis & Speichern

  • Top-N nach Probability
  • Probability wird gerundet: Math.Round(x.Prob, 2)
  • Wenn SavePredictions aktiv:
    • Ergebnisse werden in model{ID}_predictions geschrieben (Cache + Log)

Ausgabe / Ergebnis-Spalten

Standardmäßig werden ausgegeben:

  1. ProductId
  2. ProductFamily
  3. Probability
  4. Explanation

Zusätzliche Spalten können über eine eigene Seite ausgewählt werden.
Wenn die Produktsuche gesetzt wurde, werden Produktstammdaten je Ergebniszeile zusätzlich nachgeladen und angehängt.


Tipps & Hinweise

Performance

  • Kandidatenanzahl (maxCandidates) ist ein zentraler Hebel für Vorhersage-Laufzeit.

Qualität / Metriken

  • Offline-Metriken können zu optimistisch sein, da CustomerId/ProductId in Train und Test vorkommen.

Reset

Über die Oberfläche können Views und Tabellen gelöscht werden:

  • Views: vmodel{ID}_ProductPopularity, vmodel{ID}_CustomerFamilyFeatures, vmodel{ID}_ProductsDistinct
  • Tabellen: model{ID}_sourcedata, model{ID}_modeldata, model{ID}_sampleslog, model{ID}_candidateslog, model{ID}_predictions

Damit wird ein kompletter Neuaufbau (Import + Training) erzwungen.


Einrichtung

Folgender Ablauf richtet Ihr Modell ein und führt das Training aus.

  • Wechseln Sie in den Bereich KI
  • Klicken Sie auf Neu / Modell und wählen Sie den Typ Produktempfehlung aus.
  • Definieren Sie einen Konnektor für das Abrufen der Käufe (positive Beispiele). Der Konnektor muss Abfragen unterstützen.
  • Wechseln Sie in den Bereich Features auswählen.
  • Definieren Sie die Abfragen. Mit der Verwendung von Platzhaltern können Sie eine kontinuierliche Übertragung von neuen Verkaufsdaten erreichen. Hierfür sollten die relevanten Felder in der Kategorie Quelldaten. festgelegt werden.
  • Die Abfrage sollte auch verfälschende Verkäufe, wie Versandkosten, ausschließen.
  • Nachdem Sie das Schema abgerufen haben, ordnen Sie den Feldern eine Bedeutung zu.
  • Als letzten Schritt kann noch die Darstellung im SmartSelling Widget angepasst werden.
  • Mit einer manuellen oder zeitgesteuerten Ausführung werden die Quelldaten geladen und das Modell trainiert.
  • Mit dem Widget oder einer Adhoc-Ausführung wird eine Vorhersage berechnet.

Interpretation der Ergebnisse

Die ROC-Kurve misst die Trennschärfe / Ranking-Fähigkeit des Modells.

  • 0,5 : Zufall
  • 0,7-0,8 : brauchbar
  • 0,8-0,9 : gut
  • > 0,9 : sehr gut

Beispiel: Fläche unter der ROC-Kurce = 0,9915

Wenn du zufällig ein positives (gekauft) und ein negatives (nicht gekauft) Beispiel nimmst, dann ordnet das Modell das positive in ~99,15% der Fälle höher ein als das negative.

Die Wahrscheinlichkeit ist keine echte Kaufwahrscheinlichkeit, da die Negativbeispiele synthetisch hergestellt werden. Die Aussage ist dadurch eher:

Wie stark glaubt das Modell, dass der Kandidat im Training ein Positivbeispiel gewesen wäre.

Für Empfehlungen zählt meistens die Sortierung (Top N) und nicht die absolute Zahl.

Was kann man aus einer maximalen Wahrscheinlichkeit von 84% konkret ableiten?

  • Wenn innerhalb eines Kunden die Top-Produkte z.B. 0,84, 0,62, 0,41… haben, ist das ein gutes Zeichen: das Modell hat Konfidenz-Unterschiede.
  • Wenn fast alle Kandidaten nur 0,01–0,05 haben und Top ist 0,06, dann ist das Modell zwar evtl. gut im Ranking, aber insgesamt “unsicher” → oft ein Kandidaten-Thema.
  • 84% als Maximum bedeutet schlicht: “Das Modell ist bei den besten Kandidaten ziemlich überzeugt, aber nicht ‘100% sicher’.” Das ist in Empfehlungssystemen üblich und ein normaler bis guter Wert.
  • Das Modell kann aus plausiblen Kandidaten (assoziierte Familien) konsistent die besseren nach oben sortieren.

Wie beurteilt man, ob das wirklich gut ist?

Für Empfehlungsmodelle ist der bessere Realitätscheck die Verteilung in den Top N Empfehlungen.

Wenn man häufig sowas siehst:

  • Top 1 ~ 0.84
  • Top 20 ~ 0.20–0.40

Modell hat klaren “Spread” und kann gut ranken.

Wenn eher:

  • Top 1 ~ 0.10
  • Top 20 ~ 0.06

Kandidaten sind für den Kunden kaum unterscheidbar oder Features fehlen.