Das Problem: Strukturierte Daten aus Text extrahieren

Du hast hunderte Geschäftsdokumente, E-Mails oder Berichte und musst daraus systematisch Informationen extrahieren:

  • Firmennamen aus Verträgen
  • Geldbeträge aus Rechnungen
  • Personennamen aus Pressemitteilungen
  • Produktbezeichnungen aus Spezifikationen

Manuell ist das nicht skalierbar. Aber welcher automatisierte Ansatz ist der richtige?


Die 4 NER-Ansätze im Überblick

┌─────────────────────────────────────────────────────────────────┐
│  NER APPROACHES: VON EINFACH BIS KI-POWERED                     │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────────┐     ┌──────────────┐     ┌──────────────┐    │
│  │   REGEX      │────▶│   spaCy      │────▶│   GLiNER     │    │
│  │              │     │              │     │              │    │
│  │ Pattern-     │     │ Rule-based   │     │ Zero-shot    │    │
│  │ Matching     │     │ + Statistical│     │ NER Model    │    │
│  └──────────────┘     └──────────────┘     └──────────────┘    │
│         │                    │                    │             │
│         ▼                    ▼                    ▼             │
│  ┌──────────────┐     ┌──────────────┐     ┌──────────────┐    │
│  │ Schnell,     │     │ Gute Balance │     │ Flexibel,    │    │
│  │ Präzise      │     │ Performance/ │     │ Custom       │    │
│  │ aber rigide  │     │ Genauigkeit  │     │ Entity Types │    │
│  └──────────────┘     └──────────────┘     └──────────────┘    │
│                                                                  │
│                        ┌──────────────┐                         │
│                        │   LLM-based  │                         │
│                        │              │                         │
│                        │ Höchste      │                         │
│                        │ Genauigkeit  │                         │
│                        └──────────────┘                         │
│                               │                                  │
│                               ▼                                  │
│                        ┌──────────────┐                         │
│                        │ Teuer, aber  │                         │
│                        │ versteht     │                         │
│                        │ Kontext      │                         │
│                        └──────────────┘                         │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Ansatz 1: Regex – Der Klassiker

Regex ist perfekt für strukturierte, vorhersehbare Muster.

Beispiel: E-Mail-Adressen und Geldbeträge extrahieren

import re

text = """
Kontakt: max.mustermann@firma.de
Rechnungsbetrag: EUR 12.500,00
Ansprechpartner: anna.schmidt@partner.com
Summe: € 8.750,50
"""

# E-Mail-Adressen
email_pattern = r'[\w.-]+@[\w.-]+\.\w+'
emails = re.findall(email_pattern, text)
print(f"E-Mails: {emails}")
# Output: ['max.mustermann@firma.de', 'anna.schmidt@partner.com']

# Geldbeträge (EUR/€ Format)
money_pattern = r'(?:EUR|€)\s*[\d.,]+'
amounts = re.findall(money_pattern, text)
print(f"Beträge: {amounts}")
# Output: ['EUR 12.500,00', '€ 8.750,50']

Wann Regex verwenden?

Gut für Schlecht für
E-Mail-Adressen Personennamen
Telefonnummern Firmennamen
Datumsformate Kontextabhängige Entitäten
Postleitzahlen Variationen und Tippfehler

Fazit: Regex ist schnell und präzise, aber nur für strukturierte Muster geeignet.


Ansatz 2: spaCy – Der Industriestandard

spaCy bietet trainierte NER-Modelle für Standard-Entitäten.

Installation und Modell laden

pip install spacy
python -m spacy download de_core_news_lg

Beispiel: Entitäten aus Geschäftstext extrahieren

import spacy

nlp = spacy.load("de_core_news_lg")

text = """
Die BMW Group hat heute bekannt gegeben, dass CEO Oliver Zipse
eine Investition von 2,5 Milliarden Euro in das Werk München plant.
Der Aufsichtsrat tagt am 15. März 2026 in Berlin.
"""

doc = nlp(text)

for ent in doc.ents:
    print(f"{ent.text:25}{ent.label_}")

Output:

BMW Group                 → ORG
Oliver Zipse              → PER
2,5 Milliarden Euro       → MONEY
München                   → LOC
15. März 2026             → DATE
Berlin                    → LOC

spaCy Entity Types

Label Bedeutung Beispiele
PER Person Oliver Zipse, Angela Merkel
ORG Organisation BMW Group, Deutsche Bank
LOC Ort München, Berlin
MONEY Geldbetrag 2,5 Milliarden Euro
DATE Datum 15. März 2026

Wann spaCy verwenden?

Gut für Schlecht für
Standard-Entitäten (PER, ORG, LOC) Domänenspezifische Entitäten
Deutsche/Englische Texte Custom Entity Types
Produktionsumgebungen Zero-Shot ohne Training
Batch-Verarbeitung Seltene Entitätstypen

Ansatz 3: GLiNER – Zero-Shot Custom Entities

GLiNER ist ein Zero-Shot NER-Modell: Du definierst beliebige Entity-Typen, ohne zu trainieren.

Installation

pip install gliner

Beispiel: Custom Entities extrahieren

from gliner import GLiNER

model = GLiNER.from_pretrained("urchade/gliner_multi-v2.1")

text = """
Die Tesla Model 3 Performance erreicht eine Reichweite von 547 km
und beschleunigt in 3,3 Sekunden von 0 auf 100 km/h.
CEO Elon Musk präsentierte das Update auf der CES 2026.
"""

# Custom Entity Types definieren
labels = ["Automodell", "Reichweite", "Beschleunigung", "Person", "Event"]

entities = model.predict_entities(text, labels)

for entity in entities:
    print(f"{entity['text']:30}{entity['label']}")

Output:

Tesla Model 3 Performance      → Automodell
547 km                         → Reichweite
3,3 Sekunden von 0 auf 100 km/h → Beschleunigung
Elon Musk                      → Person
CES 2026                       → Event

GLiNER vs spaCy

Aspekt spaCy GLiNER
Entity Types Vordefiniert Frei definierbar
Training nötig? Für Custom: Ja Nein (Zero-Shot)
Geschwindigkeit Schneller Langsamer
Genauigkeit Hoch für Standard Hoch für Custom
GPU empfohlen? Nein Ja

Wann GLiNER verwenden?

Gut für Schlecht für
Domänenspezifische Entitäten Hohe Batch-Volumen
Prototyping ohne Training Ressourcen-limitierte Umgebungen
Wechselnde Entity-Typen Wenn spaCy ausreicht

Ansatz 4: LLM-basierte Extraktion

LLMs wie GPT-4 oder Claude verstehen Kontext und können komplexe Extraktionen durchführen.

Beispiel mit OpenAI

from openai import OpenAI
import json

client = OpenAI()

text = """
In der Vorstandssitzung vom 12.02.2026 wurde beschlossen, dass
Dr. Maria Weber (CFO) und Thomas Klein (CTO) das Joint Venture
mit Siemens AG im Wert von 450 Mio. EUR federführend verhandeln.
Die Unterzeichnung ist für Q2 2026 geplant.
"""

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[
        {
            "role": "system",
            "content": """Extrahiere strukturierte Informationen aus dem Text.
            Antworte als JSON mit folgenden Feldern:
            - personen: Liste von {name, rolle}
            - organisationen: Liste von Firmennamen
            - geldbetraege: Liste von {betrag, waehrung}
            - termine: Liste von {datum, beschreibung}"""
        },
        {"role": "user", "content": text}
    ],
    response_format={"type": "json_object"}
)

result = json.loads(response.choices[0].message.content)
print(json.dumps(result, indent=2, ensure_ascii=False))

Output:

{
  "personen": [
    {"name": "Dr. Maria Weber", "rolle": "CFO"},
    {"name": "Thomas Klein", "rolle": "CTO"}
  ],
  "organisationen": ["Siemens AG"],
  "geldbetraege": [
    {"betrag": "450 Mio.", "waehrung": "EUR"}
  ],
  "termine": [
    {"datum": "12.02.2026", "beschreibung": "Vorstandssitzung"},
    {"datum": "Q2 2026", "beschreibung": "Geplante Unterzeichnung"}
  ]
}

Wann LLM-basierte Extraktion verwenden?

Gut für Schlecht für
Komplexe, kontextabhängige Extraktion Hohe Volumen (Kosten!)
Strukturierte JSON-Ausgaben Latenz-kritische Anwendungen
Relationen zwischen Entitäten Datenschutz-sensible Daten
Unstrukturierte Dokumente Wenn einfachere Methoden reichen

Vergleich: Welcher Ansatz für welchen Use Case?

Performance-Vergleich

Ansatz Geschwindigkeit Genauigkeit (Standard) Genauigkeit (Custom) Kosten
Regex ⚡⚡⚡⚡⚡ ⚡⚡⚡⚡⚡ (für Pattern) Gratis
spaCy ⚡⚡⚡⚡ ⚡⚡⚡⚡ ⚡⚡ (Training nötig) Gratis
GLiNER ⚡⚡ ⚡⚡⚡ ⚡⚡⚡⚡ Gratis
LLM ⚡⚡⚡⚡⚡ ⚡⚡⚡⚡⚡ €€€

Entscheidungsbaum

┌─────────────────────────────────────────────────────────────────┐
│  WELCHER NER-ANSATZ?                                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  Sind die Entitäten strukturiert (E-Mail, Datum, PLZ)?          │
│  │                                                               │
│  ├── JA → Regex                                                 │
│  │                                                               │
│  └── NEIN ↓                                                     │
│                                                                  │
│  Sind es Standard-Entitäten (Person, Ort, Organisation)?        │
│  │                                                               │
│  ├── JA → spaCy                                                 │
│  │                                                               │
│  └── NEIN ↓                                                     │
│                                                                  │
│  Hast du Zeit/Daten für Training?                               │
│  │                                                               │
│  ├── JA → spaCy Custom Training                                 │
│  │                                                               │
│  └── NEIN ↓                                                     │
│                                                                  │
│  Ist Latenz/Kosten kritisch?                                    │
│  │                                                               │
│  ├── JA → GLiNER                                                │
│  │                                                               │
│  └── NEIN → LLM-basiert                                         │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Kombinierter Ansatz: Das Beste aus allen Welten

In der Praxis kombinierst du oft mehrere Ansätze:

import re
import spacy
from gliner import GLiNER

def hybrid_extraction(text):
    results = {}

    # 1. Regex für strukturierte Daten
    results["emails"] = re.findall(r'[\w.-]+@[\w.-]+\.\w+', text)
    results["phone"] = re.findall(r'\+?[\d\s-]{10,}', text)

    # 2. spaCy für Standard-Entitäten
    nlp = spacy.load("de_core_news_lg")
    doc = nlp(text)
    results["persons"] = [ent.text for ent in doc.ents if ent.label_ == "PER"]
    results["organizations"] = [ent.text for ent in doc.ents if ent.label_ == "ORG"]

    # 3. GLiNER für domänenspezifische Entitäten
    gliner = GLiNER.from_pretrained("urchade/gliner_multi-v2.1")
    custom_entities = gliner.predict_entities(text, ["Produktname", "Technologie"])
    results["products"] = [e["text"] for e in custom_entities if e["label"] == "Produktname"]

    return results

Fazit: Der richtige Ansatz für dein Projekt

Quick Summary

Du brauchst… Verwende…
E-Mails, Telefonnummern, PLZ Regex
Personen, Orte, Organisationen spaCy
Custom Entities ohne Training GLiNER
Komplexe, kontextabhängige Extraktion LLM
Alles zusammen Hybrid-Ansatz

Meine Empfehlung

  1. Starte mit spaCy – deckt 80% der Fälle ab
  2. Ergänze mit Regex – für strukturierte Muster
  3. Nutze GLiNER für Prototypen – schnell Custom Entities testen
  4. LLM nur wenn nötig – wenn Kontext entscheidend ist

Die beste NER-Lösung ist die, die zu deinem Use Case passt – nicht die technisch aufwändigste.


Ressourcen


Du möchtest Entity Extraction oder NLP in deinem Unternehmen einsetzen? Dann schreib mir einfach auf LinkedIn oder buche direkt einen kostenlosen Call.