Rezept-Zuordnung: ein Eigenschaftswort frisst keinen Artikelnamen mehr

Gefunden bei der Probe, ob ein Embedding-Modell die Zuordnung besser
hinbekommt: Die Sperrliste der Eigenschaftswoerter lief als eine einzige
Liste mit Praefix-Vergleich. "Frischkaese" fing mit "frisch" an, galt
damit als blosse Eigenschaft und fiel aus dem Vergleich - die Zutat
"Kaese" fand den Frischkaese deshalb NIE. Ebenso "Biomilch" (bio),
"Rohrzucker" (roh), "Kleingebaeck" (klein), "Ganzkornbrot" (ganz),
"Grobgriess" (grob).

Unsichtbar, weil kein falscher Treffer entstand, sondern ein richtiger
ausblieb - die Zutat stand einfach als "nicht zugeordnet" da.

Jetzt zwei Toepfe statt einem. Stammformen wie "getrock" oder "vegan"
vergleichen weiter ueber den Wortanfang, weil Deutsch beugt und diese
Stuecke keine Lebensmittelnamen anfangen. Kurze Alltagswoerter wie
"frisch", "bio", "roh", "klein" zaehlen nur noch als Eigenschaft, wenn
hoechstens eine Beugungsendung dranhaengt: "frische" ja, "frischkase"
nein.

Gegenprobe im Test: "frische Hefe" findet die "Frischen Kraeuter"
weiterhin nicht - die Sperre ist praeziser geworden, nicht schwaecher.

7 neue Tests, Suite bei 494.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-02 14:01:56 +02:00
co-authored by Claude Opus 5
parent 8072e7f566
commit fe6327c913
2 changed files with 80 additions and 11 deletions
+38 -11
View File
@@ -145,29 +145,56 @@ def _stamm(text: str) -> str:
# „veganer Lime Curd" auf „Vegane Mühlen-Schnitzel". Geteilt wird dort nur die
# Eigenschaft, nicht die Sache.
#
# Als Wortanfänge aufgeführt, weil Deutsch beugt: „vegan", „vegane", „veganer",
# „veganes" sollen alle gemeint sein. Verglichen wird gegen die zusammengezogene
# Form aus ``_stamm`` (ae/oe/ue schon aufgelöst).
_NUR_EIGENSCHAFT = (
"vegan", "vegetar", "bio", "biologisch", "frisch", "roh",
# Verglichen wird gegen die zusammengezogene Form aus ``_stamm`` (ae/oe/ue schon
# aufgelöst) - die Listen unten stehen deshalb ebenfalls in dieser Form.
#
# Zwei Toepfe, weil es zwei Sorten Wort sind. Die Trennung ist nicht Kosmetik:
# Als EINE Liste mit Praefix-Vergleich hat sie ganze Artikelnamen verschluckt.
# 'Frischkaese' begann mit 'frisch', galt damit als blosse Eigenschaft und fiel
# aus dem Vergleich - die Zutat 'Kaese' fand den Frischkaese deshalb NIE. Ebenso
# 'Biomilch' (bio), 'Rohrzucker' (roh), 'Kleingebaeck' (klein), 'Ganzkornbrot'
# (ganz). Der Fehler war unsichtbar: kein falscher Treffer, nur ausbleibende
# richtige.
#
# 1. Stammformen, die in JEDER Beugung gemeint sind. Praefix-Vergleich, weil
# Deutsch beugt: 'getrock' deckt getrocknet/getrocknete/getrocknetes ab.
# Diese Stuecke fangen keine Komposita an, die ein Lebensmittel benennen.
_EIGENSCHAFT_STAMM = (
"vegan", "vegetar", "biologisch",
"gekocht", "gebacken", "geschmolz", "gesalz", "ungesalz", "gezuckert",
"getrock", "gefror", "gerieb", "gewurf", "geschnitt", "geschal", "gehackt",
"gemahl", "gepresst", "zimmertemperatur", "lauwarm",
"klein", "gross", "mittel", "fein", "grob", "ganz",
"oder", "sowie", "etwa", "circa", "nach", "ohne", "optional", "evtl",
"block", "stueck", "stuck", "gehauft", "gestrich",
"gemahl", "gepresst", "zimmertemperatur", "lauwarm", "gehauft", "gestrich",
"optional",
)
# 2. Kurze Alltagswoerter, die AUCH am Anfang echter Namen stehen. Hier zaehlt
# nur das Wort selbst, hoechstens mit einer Beugungsendung dran: 'frische'
# ja, 'frischkase' nein.
_EIGENSCHAFT_WORT = (
"bio", "frisch", "roh", "klein", "gross", "mittel", "fein", "grob", "ganz",
"oder", "sowie", "etwa", "circa", "nach", "ohne", "evtl",
"block", "stueck", "stuck",
)
# Deutsche Beugungsendungen. Was laenger ist, ist keine Endung mehr, sondern ein
# zweites Wort - und genau das soll den Namen retten.
_BEUGUNG = ("", "e", "er", "es", "en", "em", "ene", "enes", "ener", "enen")
def _nur_eigenschaft(wort: str) -> bool:
return wort.isdigit() or wort.startswith(_NUR_EIGENSCHAFT)
if wort.isdigit() or wort.startswith(_EIGENSCHAFT_STAMM):
return True
return any(
wort.startswith(w) and wort[len(w):] in _BEUGUNG
for w in _EIGENSCHAFT_WORT
)
def _woerter(text: str) -> list[str]:
"""Bedeutungstragende Wörter einer Zutat.
Weg fallen sehr kurze („1 TL"), reine Zahlen und alles, was die Zutat nur
beschreibt (siehe ``_NUR_EIGENSCHAFT``). Übrig bleibt, was sie IST: „Mehl",
beschreibt (siehe ``_nur_eigenschaft``). Übrig bleibt, was sie IST: „Mehl",
„Apfel", „Butter", „Joghurt".
"""
return [