Automatisierte Produktklassifizierung & Datenbereinigung

01 Herausforderung

Produktdaten manuell Kategorien zuzuordnen und Beschreibungen einzeln zu überarbeiten, kostet bei größeren Katalogen viel Zeit.

02 Ansatz

Ein Python-Skript liest die Produkte per Pandas ein und lässt ein lokales LLM (gemma3:4b via Ollama) jedes Produkt klassifizieren und seine Beschreibung SEO-optimiert umschreiben.

03 Ergebnis

Ein angereicherter Datensatz mit den neuen Spalten PredictedCategory und new_descriptions, exportiert als CSV – mit wenigen Zeilen Code und ohne Cloud-API.

Stack
PythonPandasOllamagemma3:4b

Ich habe ein kleines, aber nützliches Python-Skript entwickelt, das Produktdaten aus einer CSV-Datei einliest, automatisch einer passenden Kategorie zuordnet und die Beschreibung optimiert. Die Idee dahinter war es, zu testen, wie gut sich Large Language Models (LLMs) wie gemma3:4b für solche Aufgaben eignen.

Das Skript ist kein komplexes KI-System – aber es zeigt, wie sich mit wenigen Zeilen Code manuelle Arbeitsschritte automatisieren lassen, besonders im E-Commerce und bei größeren Produktkatalogen.

Beispielprodukte
20
CSV mit 6 Spalten
Zielkategorien
4
Elektronik · Haushalt · Kleidung · Garten
LLM-Aufgaben
2
Klassifizieren + Umschreiben je Produkt
Inferenz
lokal
Ollama · gemma3:4b

Der technische Ansatz

  1. 01EinlesenCSV-String wird zum DataFrameload_data
  2. 02KlassifizierenLLM ordnet jedes Produkt einer Kategorie zuclassify_product_llm
  3. 03UmschreibenLLM formuliert die Beschreibung SEO-optimiertrewrite_description
  4. 04AnreichernNeue Spalten im DataFrameenrich_data_…
  5. 05ExportErgebnis als CSV-Dateito_csv
Abb. 1 — Verarbeitungskette von der CSV-Datei zum angereicherten Datensatz

1. Daten einlesen

Alles beginnt mit der Funktion, die die CSV-Daten einliest. Mithilfe von Pandas und StringIO verwandle ich einen einfachen CSV-String in ein DataFrame – die Grundlage, um die Produktdaten strukturiert weiterzuverarbeiten.

2. LLM-basierte Produktklassifizierung

Für die Klassifizierung nutze ich das Paket ollama, um das Modell gemma3:4b anzusteuern. In classify_product_llm gibt ein Systemprompt dem Modell klare Anweisungen: Produktname und Beschreibung entgegennehmen und einem vorgegebenen Kategorien-Schema zuordnen – Elektronik, Haushaltswaren, Kleidung oder Gartenartikel.

3. Optimierung der Produktbeschreibung

Parallel dazu optimiert rewrite_description die Produktbeschreibung. Ein zweiter Systemprompt sorgt dafür, dass der Text SEO-optimiert und zugleich ansprechender formuliert wird: kurze Sätze, relevante Keywords ohne Keyword-Stuffing, Bulletpoints bei vielen Vorteilen.

Wichtig war mir die Balance zwischen technischer Präzision und natürlicher, verkaufsfördernder Sprache – und vor allem, dass keine neuen Details erfunden werden. Der Prompt verbietet das ausdrücklich: Der Text soll nur verbessert, nicht ergänzt werden.

4. Datenanreicherung

enrich_data_with_classification iteriert über alle Produkte im DataFrame, wendet Klassifizierung und Textoptimierung an und erweitert den Datensatz um zwei neue Spalten. Im letzten Schritt wird das Ergebnis als classified_products.csv gespeichert.

Eingabe (CSV)

  • ArticleID, Name, Description
  • Manufacturer, Price, Stock
  • Kategorie fehlt
  • Beschreibung im Rohzustand

Ausgabe (angereichert)

  • Alle Originalspalten bleiben erhalten
  • + PredictedCategory
  • + new_descriptions (SEO-optimiert)
  • Export als classified_products.csv

Learnings

  • Zwei Aufgaben, zwei Prompts: Klassifizierung und Texterstellung haben völlig unterschiedliche Anforderungen an den Output – getrennte Systemprompts halten beide Aufgaben sauber.
  • Guardrails gehören in den Prompt: Das explizite Verbot, Produktdetails zu erfinden, ist bei generierten Shop-Texten unverzichtbar.
  • Lokal reicht für den Test: Ein 4B-Modell über Ollama genügt, um den Workflow ohne Cloud-API auszuprobieren.

Der Code

Im Hauptteil des Programms definiere ich Beispiel-CSV-Daten, lese sie ein und lasse die gesamte Verarbeitungskette durchlaufen. Hier ist das vollständige Python-Skript:

import pandas as pd
from io import StringIO
from ollama import chat

def load_data(csv_data: str) -> pd.DataFrame:
    """
    Liest CSV-Daten aus einem String ein.
    """
    df = pd.read_csv(StringIO(csv_data))
    return df

def classify_product_llm(name: str, description: str) -> str:
    """
    Verwendet das ollama-Paket, um das Modell "gemma3:4b" anzusteuern und
    mithilfe eines Systemprompts sowie des Produkts (Name und Beschreibung)
    eine Kategorie zu bestimmen.
    """
    system_prompt = (
        """
        Du bist ein Experte für Produktklassifizierung. Ordne das Produkt in eine der folgenden Kategorien ein:
        Elektronik: Computer, Smartphones, Fernseher, Audio-Geräte, Kameras, Wearables.
        Haushaltswaren: Küchengeräte, Staubsauger, Bügeleisen, Waschmaschinen, Toaster, Lampen.
        Kleidung: Schuhe, Jacken, T-Shirts, Hosen, Pullover.
        Gartenartikel: Gartengeräte, Pflanzenzubehör, Rasenmäher, Heckenscheren.
        Antworte ausschließlich mit dem Kategorienamen.
        """
    )
   
    user_prompt = f"Produktname: {name}\nBeschreibung: {description}"
   
    # Sende die Nachrichten an das Modell
    response = chat(
        model="gemma3:4b",  # gemma3 referenziert standardmäßig gemma3:4b
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ],
    )
   
    # Extrahiere und bereinige die Antwort
    category = response.message.content.strip()
    return category if category else "Unbekannt"

def rewrite_description(name: str, description: str) -> str:
    """
    Verwendet das ollama-Paket, um das Modell "gemma3:4b" anzusteuern und
    mithilfe eines Systemprompts sowie des Produkts (Name und Beschreibung)
    eine Kategorie zu bestimmen.
    """
    system_prompt = (
        """
        Du bist ein Experte für E-Commerce und SEO-optimierte Produktbeschreibungen.
        Deine Aufgabe ist es, die gegebene Produktbeschreibung zu verbessern, indem du sie:
        Leserfreundlich formulierst.
        Relevante Keywords einbaust (ohne Keyword-Stuffing).
        Eine emotionale und verkaufsstarke Sprache nutzt.
        Erfinde keine Produktdetails – Es dürfen nur die vorhandenen Artikelinformationen angegeben werden, um zu verhindern, dass ausgedachte Details hinzugefügt werden.
        Die Beschreibung leicht verständlich und ansprechend hälst.
        Verwende eine natürliche, aber verkaufsstarke Tonalität, als würde ein professioneller Online-Shop sie schreiben.
        Schreibe in kurzen Sätzen, verwende Bulletpoints bei vielen Vorteilen und formuliere den Text so, dass er die Kaufentscheidung positiv beeinflusst.
        Gib nur die optimierte Beschreibung zurück, ohne weitere Erklärungen.
        """
    )
   
    user_prompt = f"Produktname: {name}\nBeschreibung: {description}"
   
    # Sende die Nachrichten an das Modell
    response = chat(
        model="gemma3:4b",  # gemma3 referenziert standardmäßig gemma3:4b
        messages=[
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": user_prompt},
        ],
    )
   
    # Extrahiere und bereinige die Antwort
    new_description = response.message.content.strip()
    return new_description if new_description else "Unbekannt"

def enrich_data_with_classification(df: pd.DataFrame) -> pd.DataFrame:
    """
    Durchläuft die Produktliste und ruft für jeden Artikel die LLM-basierte Klassifizierung ab.
    Das Ergebnis wird in der neuen Spalte 'PredictedCategory' gespeichert.
    """
    predicted_categories_list = []
    new_descriptions_list = []
    for idx, row in df.iterrows():
        name = row.get("Name", "")
        description = row.get("Description", "")
        category = classify_product_llm(name, description)
        new_description = rewrite_description(name, description)
        
        print(f"Produkt '{name}' -> Vorhergesagte Kategorie: {category}")
        predicted_categories_list.append(category)
        new_descriptions_list.append(new_description)

    df["PredictedCategory"] = predicted_categories_list
    df["new_descriptions"] = new_descriptions_list
    return df

def main():
    # Beispiel CSV-Daten als String
    csv_data = """
        ArticleID,Name,Description,Manufacturer,Price,Stock
        1,Smartphone,"Modernes Smartphone mit 6.5 Zoll Display und 128GB Speicher",TechCorp,699.99,50
        2,T-Shirt,"Bequemes Baumwoll-T-Shirt in verschiedenen Farben",FashionCo,19.99,200
        3,Kaffeemaschine,"Automatische Kaffeemaschine mit 12 Tassen Kapazität",HomeBrew,129.99,80
        4,Gartenschere,"Hochwertige Gartenschere für präzises Schneiden",GardenPro,24.99,150
        5,LED-Fernseher,"50 Zoll LED-Fernseher mit 4K Auflösung und Smart TV Funktionen",ElectroMax,499.99,30
        6,Notebook,"Leistungsstarkes Notebook mit Intel i7 und 16GB RAM",CompuWorld,1299.99,20
        7,Lederjacke,"Hochwertige Lederjacke aus echtem Leder",FashionCo,199.99,35
        8,Toaster,"2-Schlitz-Toaster mit einstellbarer Bräunung",HomeBrew,34.99,100
        9,Rasenmäher,"Elektrischer Rasenmäher mit 40cm Schnittbreite",GardenPro,299.99,40
        10,Smartwatch,"Wasserdichte Smartwatch mit Fitness-Tracking",TechCorp,199.99,60
        11,Hoodie,"Kapuzenpullover aus weichem Fleece-Material",FashionCo,39.99,120
        12,Mikrowelle,"800W Mikrowelle mit Auftaufunktion",HomeBrew,89.99,75
        13,Heckenschere,"Akku-Heckenschere für präzises Schneiden",GardenPro,179.99,50
        14,Kopfhörer,"Kabellose Over-Ear-Kopfhörer mit Noise Cancelling",TechCorp,149.99,90
        15,Winterjacke,"Gefütterte Winterjacke mit wasserabweisendem Material",FashionCo,129.99,45
        16,Staubsauger,"Leistungsstarker Staubsauger mit HEPA-Filter",HomeBrew,199.99,55
        17,Gartenlampe,"Solarbetriebene Gartenlampe mit Bewegungssensor",GardenPro,39.99,100
        18,Bluetooth-Lautsprecher,"Wasserdichter Bluetooth-Lautsprecher mit 360° Sound",ElectroMax,79.99,85
        19,Sneaker,"Bequeme Laufschuhe mit atmungsaktivem Material",FashionCo,89.99,150
        20,Espressomaschine,"Hochwertige Espressomaschine mit Milchaufschäumer",HomeBrew,249.99,30
    """
    # Daten laden
    df = load_data(csv_data)
    print("Originale Daten:")
    print(df, "\n")
   
    # LLM-basierte Klassifizierung durchführen
    df = enrich_data_with_classification(df)
   
    print("\nDaten mit vorhergesagten Kategorien:")
    print(df)
   
    # Ergebnis optional in CSV speichern
    output_file = "classified_products.csv"
    df.to_csv(output_file, index=False)
    print(f"\nErgebnis wurde in '{output_file}' gespeichert.")

if __name__ == "__main__":
    main()