85.1.28. pepsi-stage-detect-language¶
detect the human language of a message body
- Handbuchabschnitt:
1
85.1.28.1.1. Name¶
pepsi-stage-detect-language - die Spracherkennungs-Stage der Pepsi-Pipeline.
85.1.28.1.2. Übersicht¶
pepsi-stage-detect-language [GLOBAL-OPTIONS] worker
85.1.28.1.3. Beschreibung¶
pepsi-stage-detect-language ist ein Stage-Programm, das von pepsi-dispatch(1) als persistenter Worker ausgeführt wird, der Nachrichten-IDs von der Standardeingabe liest. Es lädt diesen pepsi.workqueue-Datensatz (und weigert sich zu handeln, sofern sein status nicht running ist), liest seinen [stage-<stage>]-Abschnitt, identifiziert die im Nachrichtentext verwendete(n) menschliche(n) Sprache(n) und hält sie unter state.language fest, bevor es die Nachricht zu NEXT_STAGE weiterschaltet. Diese Stage verwirft, bounct oder pausiert eine Nachricht nie und bewahrt den Rest von state.
Die Stage extrahiert den eingebetteten Nachrichtentext mit einem vollständigen MIME-Parser (gemeinsame Logik in pepsi-common): text/plain-Teile werden wörtlich genommen und text/html-Teile auf Klartext reduziert, jeweils von ihrer Content-Transfer-Encoding und ihrem deklarierten Zeichensatz nach UTF-8 dekodiert. Anhänge (einschließlich Text-Anhänge) werden ignoriert, ebenso verschlüsselte oder anderweitig undurchsichtige Nachrichtentexte (zum Beispiel multipart/encrypted oder application/pkcs7-mime), die keinen lesbaren Text tragen. Bei einem multipart/alternative wird die Klartext-Alternative der HTML-Variante vorgezogen — außer wenn sich zeigt, dass diese Klartext-Alternative überhaupt keine Prosa enthält, die Form, die ein Massenversender erzeugt, wenn er zwei nackte URLs dorthin setzt, wo die Nachricht stehen sollte; dann wird stattdessen das HTML-Geschwisterteil genommen.
85.1.28.1.3.1. Prosafilterung¶
Der extrahierte Text wird anschließend auf denjenigen Teil reduziert, der Prosa ist, und nur dieser wird klassifiziert. Ein statistischer Detektor modelliert, wie Menschen Wörter schreiben, und der Nachrichtentext einer E-Mail ist voll von Dingen, die keine Wörter sind: URLs, Adressen, Base64-Schlüssel, DNS-Einträge, hexadezimale Bezeichner. Ungefiltert wird ein Nachrichtentext, der überwiegend aus Maschinentext besteht, aus dem Maschinentext klassifiziert: Eine DNS-Eintrags-Benachrichtigung oder ein Spam-Nachrichtentext aus zwei nackten URLs erhält ein selbstsicheres Urteil für eine Sprache, in der niemand darin geschrieben hat, selbst wenn jedes Wort, das ein Mensch dort geschrieben hat, Englisch ist.
Zwei Filter laufen, in dieser Reihenfolge:
Tokens, die keine Wörter sein können, werden verworfen — alles, was
@, einen Schrägstrich oder Backslash oder einen innenliegenden Punkt enthält, alles, was mithttpoderwww.beginnt, alles mit weniger als der Hälfte Buchstaben, alles mit einer Ziffer, alles länger als 30 Zeichen und alles, dessen Groß-/Kleinschreibung innerhalb des Wortes wechselt (CamelCase, Base64);Zeilen, denen weniger als 15 Buchstaben bleiben oder in denen Buchstaben nicht die Mehrheit bilden, werden verworfen — was Filter eins von einem DNS-Dump oder einer Tabelle übrig lässt, ist eine Streuung nackter Feldnamen, und das ist in keiner Sprache Prosa.
Die Regeln kennen Schriften, die Wörter nicht durch Leerzeichen trennen (Han, Kana, Hangul, Thai, Khmer, Laotisch, Birmanisch, Tibetisch): Dort trifft ein ganzer Satzteil als ein Token ein, sodass die Längen-, Ziffern-, Punkt- und Großschreibungsregeln darauf nicht angewandt werden und Zeilen danach beurteilt werden, wie viele Buchstaben sie enthalten, statt wie viele Wörter. Ohne das würde eine chinesische oder thailändische Nachricht vollständig gelöscht.
85.1.28.1.3.2. Klassifikation¶
Die verbliebene Prosa wird mit dem statistischen Detektor lingua klassifiziert, gebaut aus den von der LANGUAGES-Option benannten Kandidatensprachen. Der Detektor liefert eine Wahrscheinlichkeit für jede Kandidatensprache; die wahrscheinlichsten höchstens drei Sprachen, deren Wahrscheinlichkeit mindestens 5 % beträgt, werden festgehalten.
Höchstens die ersten 20 000 Zeichen dieser Prosa werden klassifiziert. Der Detektor bewertet jede Kandidatensprache über den gesamten Text, seine Kosten sind also die Länge des Textes mal die Zahl der Kandidatensprachen — und mit LANGUAGES = * sind das 75 davon, gegenüber einer in Megabyte gemessenen Nachrichtengrößen-Grenze. Eine Sprache entscheidet sich in den ersten paar Kilobyte; den Rest einer langen Nachricht zu klassifizieren würde den Worker nur beschäftigen. Dafür gibt es keine Option: Es ist eine Obergrenze für die Arbeit, keine Richtlinie.
Hat die Nachricht keinen brauchbaren eingebetteten Text, ist nichts von diesem Text Prosa, oder gibt es zu wenig Prosa (weniger als 20 Zeichen), um zuverlässig zu klassifizieren, überspringt die Stage die Klassifikation: Die Nachricht schaltet unverändert weiter, ohne dass ein language-Schlüssel hinzugefügt wird. Nichts festzuhalten ist Absicht — ein Nachrichtentext, der nur aus URLs besteht, hat keine Sprache, und aus einem URL-Slug eine zu raten ist der Weg, auf dem eine Nachricht selbstsicher mit einer Sprache markiert wird, in der sie niemand geschrieben hat.
85.1.28.1.4. Ausgabeformat¶
state.language ist eine Zeichenkette in der Syntax eines HTTP-Accept-Language-Headers: eine durch Kommas getrennte Liste von code;q=quality-Elementen, von der wahrscheinlichsten zur unwahrscheinlichsten geordnet. Jeder code ist der ISO-639-1-Code der Sprache und jede quality ihre Erkennungswahrscheinlichkeit im Bereich 0–1 (nachgestellte Nullen abgeschnitten, sodass eine sichere einzelne Sprache q=1 lautet). Zum Beispiel könnte eine überwiegend englische Nachricht mit etwas Deutsch festgehalten werden als:
en;q=1, de;q=0.45
Der Detektor ist teuer zu konstruieren, daher baut ihn jeder Worker-Prozess einmal (je verschiedenem Kandidatensprachensatz) und verwendet ihn für jede Nachricht wieder. Er wird mit der vollen Genauigkeit von lingua gebaut; der Modus geringer Genauigkeit der Bibliothek wird bewusst nicht genutzt. Dieser Modus kürzt ab — er liefert eine Sprache mit Wahrscheinlichkeit 1, sobald genau eine Kandidatensprache ein irgendwo im Text vorkommendes N-Gramm besitzt, ohne den Rest zu betrachten —, sodass eine einzige Adresse in einer zitierten Zuschreibungszeile oder ein Base64-Schlüssel über die Sprache von Kilobytes an Prosa entscheiden kann. Bei gefilterter Prosa ist er auch nicht billiger: Die Abkürzungssuche wird bezahlt und dann verworfen, und er lädt zusätzliche N-Gramm-Zählmodelle vorab, sodass er nichts einbringt.
85.1.28.1.5. Konfiguration¶
Die Optionen liegen im eigenen [stage-<name>]-Abschnitt der Stage (PROGRAM = pepsi-stage-detect-language): ein NEXT_STAGE und die Kandidaten-LANGUAGES-Menge. Sie sind in pepsi.conf(5) dokumentiert.
85.1.28.1.6. State¶
Eingaben: keine aus state; die Stage liest den gespeicherten Nachrichtentext.
Ausgaben: Wenn mindestens eine Sprache erkannt wird, führt die Stage language (die Accept-Language-artige Zeichenkette) in state zusammen und schaltet weiter — eine Aktualisierung, die den Datensatz zu NEXT_STAGE bewegt und den Schlüssel einmischt; andernfalls bleibt state unberührt und der Datensatz schaltet einfach weiter. Das State-Layout wird in pepsi.state(7) beschrieben.
Übergänge: schaltet immer zu NEXT_STAGE weiter, ob eine Sprache erkannt wurde oder nicht. Es gibt keine Verzweigung; die Stage pausiert nie, schlägt nie fehl, teilt nie auf und schließt nie ab. Eine Nachricht, deren Inhalt den Klassifikator in Panik versetzt, wird ohne Sprache weitergeschaltet, mit einer Warnung im Log: Eine Wiederholung würde nur erneut eine Panic auslösen, und nichts nachgelagert benötigt eine Sprache.
85.1.28.1.7. Befehle¶
- worker
Läuft als persistenter pepsi-dispatch(1)-Worker, der Nachrichten-IDs von der Standardeingabe liest.
85.1.28.1.8. Globale Optionen¶
- -c FILE, –config FILE
Liest die Konfiguration aus FILE, statt die Standardorte zu durchsuchen.
- -L LOGLEVEL, –log LOGLEVEL
Setzt die Log-Ausführlichkeit (Standardwert
info).- -v, –verbose
Zeigt Log-Meldungen aus allen Quellen.
- -h, –help; -V, –version
Gibt eine Verwendungsübersicht / die Version aus und beendet sich.
85.1.28.1.9. Exit-Status¶
- 0
Die Nachricht wurde verarbeitet (weitergeschaltet, mit oder ohne festgehaltene Sprache).
- 1
Ein Fehler ist aufgetreten (Nachricht nicht gefunden oder nicht
running, oder eine adressbezogene Einstellung, die den Abschnitt der Stage kaputt macht — etwa ein ungültiger LANGUAGES-Code). Der Grund wird in das Log geschrieben.Ein Fehler des Hosts (die Datenbank, eine Vorlage oder ein Helfer, die sich nicht verwenden lassen) wird nicht als Fehlschlag gemeldet: Die Nachricht wird pausiert und erneut versucht, wie unter Stage-Fehler in pepsi-dispatch(1) beschrieben. Ein Abschnitt, der sich nicht parsen lässt, lässt den Worker den Start verweigern (Status 78), statt eine Nachricht nach der anderen fehlschlagen zu lassen. Ebenso eine fehlende NEXT_STAGE.
85.1.28.1.10. Diagnose und Tuning¶
pepsi-detect-language(1) ist das Offline-Gegenstück dieser Stage: dieselbe ausführbare Datei unter einem zweiten Namen, die eine aus einer Datei oder von der Standardeingabe gelesene Nachricht klassifiziert und nur ausgibt, was diese Stage festgehalten hätte, ohne der Datenbank nahezukommen. Verwenden Sie es, um eine Fehlklassifikation aus einer gespeicherten Nachricht nachzustellen (--explain zeigt den extrahierten Text, die nach der Filterung verbliebene Prosa und die Konfidenz jeder Kandidatensprache) und um Kandidatensätze auszuprobieren, bevor Sie einen konfigurieren (--languages).
85.1.28.1.11. Beispiele¶
Eine Nachricht von Hand klassifizieren (die ID muss einen running-Datensatz benennen):
echo 42 | pepsi-stage-detect-language -c /etc/pepsi/pepsi.conf worker
Ein Pipeline-Abschnitt, der die Sprache des Nachrichtentexts vor der Prüfung der weißen Liste kennzeichnet:
[stage-detect-language]
PROGRAM = pepsi-stage-detect-language
NEXT_STAGE = check-whitelist
LANGUAGES = en de fr es
85.1.28.1.12. Siehe auch¶
pepsi-detect-language(1), pepsi-config(1), pepsi-stage-check-whitelist(1), pepsi-dispatch(1), pepsi.conf(5), pepsi.state(7), pepsi-setup(1)
85.1.28.1.13. Fehler¶
Melden Sie Fehler an den Pepsi-Issue-Tracker.