51. pepsi-detect-language¶
Eine Nachricht so klassifizieren, wie es die Pipeline täte — offline, zur Diagnose und zum Tuning.
51.1. Rolle¶
pepsi-detect-language ist ein Diagnose- und Tuning-Werkzeug, keine Stage. Es liest eine einzelne Nachricht aus einer Datei oder von der Standardeingabe, lässt die eigene Klassifikation von pepsi-stage-detect-language darüber laufen und gibt den resultierenden Wert state.language — und sonst nichts — auf der Standardausgabe aus.
Es öffnet nie die Datenbank und braucht keinen pepsi.workqueue-Datensatz, sodass eine im Produktivbetrieb falsch klassifizierte Nachricht an einer gespeicherten Kopie untersucht werden kann, auf jedem Host, so oft Sie mögen. Referenz: pepsi-detect-language(1).
Es ist dieselbe ausführbare Datei wie pepsi-stage-detect-language, als zweiter Name dafür installiert: Die beiden teilen sich den gesamten Klassifikationspfad — sodass das, was das Werkzeug meldet, das ist, was die Pipeline getan hat, und keine Neuimplementierung, die auseinanderdriften kann — sowie die statisch gelinkten Sprachmodelle, weshalb sie auch im selben (eigenen) Paket ausgeliefert werden.
51.2. Eine Fehlklassifikation diagnostizieren¶
--explain schreibt jeden Zwischenschritt auf die Standardfehlerausgabe und lässt die Standardausgabe unberührt:
pepsi-detect-language --explain message.eml >/dev/null
Es zeigt, wie die Eingabe eingerahmt wurde, welche Kandidatensprachen im Spiel waren und woher diese Menge stammte, den extrahierten Nachrichtentext, die nach dessen Filterung verbliebene Prosa — der mit Abstand nützlichste Block, denn diese und nicht der extrahierte Text ist das, was dem Detektor übergeben wurde — und die Konfidenz jeder Kandidatensprache mit angewandten Top-drei- und 5-%-Regeln.
51.3. Warum es zwei Textblöcke gibt¶
Die Stage klassifiziert den Nachrichtentext nicht so, wie er extrahiert wurde. Sie entfernt zuerst alles, was kein Wort sein kann: URLs, E-Mail-Adressen, Base64-Schlüssel, DNS-Einträge, Bezeichner. Das ist keine Ordnungsliebe: belässt man diese Tokens, entscheiden sie die Antwort, und eine Benachrichtigungs-E-Mail, ein Dump von DNS-Einträgen oder ein Spam-Nachrichtentext aus zwei nackten URLs wird anhand seines Maschinentexts als eine Sprache klassifiziert, in der niemand darin geschrieben hat.
Die Stage betreibt lingua im Modus voller Genauigkeit. Dessen Modus geringer Genauigkeit sucht nach einem N-Gramm, das für eine Kandidatensprache eindeutig ist, bevor überhaupt bewertet wird, und gibt diese Sprache mit Wahrscheinlichkeit 1 zurück, wenn genau eine passt — sodass ein einziges Nichtwort — eine Adresse in einer zitierten Zuschreibungszeile, ein Base64-Schlüssel, eine IPv6-Adresse — die gesamte Nachricht mit voller Konfidenz entscheiden würde, ohne dass der Rest des Nachrichtentexts betrachtet wird.
Wenn eine Klassifikation also falsch aussieht, lesen Sie den zweiten Block. Ist die Prosa dort die Nachricht, die ein Mensch lesen würde, und die Antwort dennoch falsch, ist die Kandidatenmenge das Nächste, was zu versuchen ist (unten). Sagt der zweite Block, es gebe keine Prosa, dann enthielt der Nachrichtentext tatsächlich keine — ein Massenversender, dessen Textteil zwei nackte URLs sind — und keine Sprache ist die richtige Antwort.
51.4. Tuning von LANGUAGES¶
Die übliche Ursache einer selbstsicheren falschen Antwort ist die Kandidatenmenge: Eine Sprache, die im Verkehr nie vorkommt, konkurriert dennoch um Wahrscheinlichkeit, und bei kurzen Texten gewinnt sie. --languages überschreibt die konfigurierte Menge (und überspringt das Lesen der Konfiguration gänzlich), sodass eine Menge ausprobiert werden kann, bevor sie konfiguriert wird:
pepsi-detect-language --languages "en de" message.eml
* wählt jede unterstützte Sprache, genau wie in der Option — was der Assistent von pepsi-setup konfiguriert, sofern der Operator sie nicht einengt, und damit die Menge, gegen die zu vergleichen ist, wenn eine Klassifikation im Produktivbetrieb falsch aussieht:
pepsi-detect-language --languages '*' message.eml
Ohne --languages stammt die Kandidatenmenge aus der Konfiguration: aus dem einen [stage-*]-Abschnitt, der pepsi-stage-detect-language ausführt. Enthält eine Konfiguration mehrere, benennen Sie den zu verwendenden mit --stage NAME; enthält sie keinen, wird die eingebaute Standardmenge der Stage verwendet, und eine Warnung sagt das.
Über einen Korpus:
for m in ~/Maildir/cur/*; do
printf '%s\t%s\n' "$(pepsi-detect-language --languages "en de" "$m")" "$m"
done | sort | uniq -c
51.5. Eingabe¶
mbox, RFC 5322 oder ein nackter Nachrichtentext — alle drei werden angenommen, und es wird erkannt, welcher davon übergeben wird. Eine führende mbox-
From_-Trennzeile wird entfernt (mit rückgängig gemachtem mboxrd->From-Quoting); ein nackter Nachrichtentext wird in ein minimalesContent-Typegehüllt. Ein Header-Block wird nur dann erkannt, wenn jede Zeile vor der ersten Leerzeile ein Feld oder eine gefaltete Fortsetzung ist, sodass ein Nachrichtentext, der mitRe: the meetingbeginnt, nicht dafür gehalten wird;--body-onlyerzwingt diese Lesart.Header bleiben erhalten und werden nie klassifiziert. Header-Text erreicht den Detektor nicht — die Stage extrahiert nur eingebettete Teile des Nachrichtentexts —, aber
Content-Type,charsetundContent-Transfer-Encodingentscheiden, was der Nachrichtentext ist. Sie zu verwerfen würde eine Quoted-Printable-, Base64- oder HTML-Nachricht anhand ihrer Kodierung statt anhand ihrer Prosa klassifizieren, was einer der Fehler ist, die das Werkzeug finden soll.Die Nur-Text-Alternative gewinnt, sofern sie kein Stummel ist. Bei einem
multipart/alternativeist dertext/plain-Teil das, was ein Absender geschrieben hat, und wird daher vorgezogen. Enthält er überhaupt keine Prosa — die Massenversender-Form, zwei nackte URLs dort, wo die Nachricht stehen sollte —, wird stattdessen das HTML-Geschwisterteil verwendet, und--explainsagt das.Zeilenenden werden auf CRLF normalisiert, wie es pepsi-ingress tut, sodass eine aus einer Datei gelesene Nachricht genau so klassifiziert wird wie die eingereihte Kopie.
51.6. Ausgabe¶
Eine Zeile: die Zeichenkette im Stil von Accept-Language, z. B. en;q=1, de;q=0.45. Wenn die Stage keine Sprache festhalten würde — kein eingebetteter Text, zu wenig davon, oder nichts über der Konfidenzschwelle —, ist die Standardausgabe leer und der Grund geht auf die Standardfehlerausgabe. Das ist das eigene Verhalten der Stage, kein Fehler.
51.7. Siehe auch¶
pepsi-stage-detect-language, pepsi-stage-block-language, pepsi-detect-language(1), pepsi.state(7).