51. pepsi-detect-language¶
Classifier un message comme le ferait le pipeline — hors ligne, pour le diagnostic et l’ajustement.
51.1. Rôle¶
pepsi-detect-language est un outil de diagnostic et d’ajustement, pas une étape. Il lit un unique message depuis un fichier ou l’entrée standard, y exécute la classification propre de pepsi-stage-detect-language, et écrit la valeur state.language résultante — et rien d’autre — sur la sortie standard.
Il n’ouvre jamais la base de données et n’a besoin d’aucune ligne pepsi.workqueue, de sorte qu’un message mal classifié en production peut être examiné sur une copie sauvegardée, sur n’importe quel hôte, aussi souvent que vous le souhaitez. Référence : pepsi-detect-language(1).
C’est le même exécutable que pepsi-stage-detect-language, installé sous un second nom : les deux partagent tout le chemin de classification — de sorte que ce que rapporte l’outil est ce qu’a fait le pipeline, et non une réimplémentation susceptible de dériver — ainsi que les modèles de langue liés statiquement, raison pour laquelle ils sont livrés dans le même paquet (distinct).
51.2. Diagnostiquer une erreur de classification¶
--explain écrit chaque étape intermédiaire sur la sortie d’erreur standard, laissant la sortie standard intacte
pepsi-detect-language --explain message.eml >/dev/null
Il montre comment l’entrée a été encadrée, quelles langues candidates étaient en jeu et d’où venait cet ensemble, le texte de corps extrait, la prose restant après filtrage — le bloc de loin le plus utile, puisque c’est elle, et non le texte extrait, qui a été donnée au détecteur — et la confiance de chaque candidate, avec les règles des trois premières et des 5 % appliquées.
51.3. Pourquoi il y a deux blocs de texte¶
L’étape ne classifie pas le corps tel qu’il a été extrait. Elle retire d’abord tout ce qui ne peut pas être un mot : URL, adresses e-mail, clés base64, enregistrements DNS, identifiants. Ce n’est pas de la coquetterie : laissés en place, ces jetons décident de la réponse, et un e-mail de notification, un vidage d’enregistrements DNS ou un corps de spam fait de deux URL nues est classifié, d’après son texte machine, dans une langue que personne n’y a écrite.
L’étape exécute lingua en mode pleine précision. Son mode basse précision cherche un n-gramme propre à une seule langue candidate avant d’évaluer quoi que ce soit et renvoie cette langue avec la probabilité 1 si exactement une correspond, de sorte qu’un seul non-mot — une adresse dans une ligne d’attribution citée, une clé base64, une adresse IPv6 — déciderait de tout le message, avec une confiance totale et sans que le reste du corps soit examiné.
Aussi, lorsqu’une classification paraît fausse, lisez le second bloc. Si la prose qui s’y trouve est le message qu’un humain lirait et que la réponse reste fausse, l’ensemble de candidates est la chose suivante à essayer (ci-dessous). Si le second bloc dit qu’il n’y a pas de prose, c’est que le corps n’en contenait véritablement pas — un expéditeur de masse dont la partie texte brut est deux URL nues — et « aucune langue » est la bonne réponse.
51.4. Ajuster LANGUAGES¶
La cause habituelle d’une réponse fausse et assurée est l’ensemble de candidates : une langue que le trafic ne contient jamais concourt tout de même pour la probabilité, et c’est sur les textes courts qu’elle l’emporte. --languages redéfinit l’ensemble configuré (et saute entièrement la lecture de la configuration), de sorte qu’un ensemble peut être essayé avant d’être configuré
pepsi-detect-language --languages "en de" message.eml
* sélectionne toutes les langues prises en charge, exactement comme dans l’option — ce que configure l’assistant de pepsi-setup à moins que l’opérateur ne le restreigne, et donc l’ensemble auquel se comparer lorsqu’une classification en production paraît fausse
pepsi-detect-language --languages '*' message.eml
Sans --languages, l’ensemble de candidats provient de la configuration : l’unique section [stage-*] exécutant pepsi-stage-detect-language. Lorsqu’une configuration en compte plusieurs, nommez celle à utiliser avec --stage NAME ; lorsqu’elle n’en compte aucune, l’ensemble par défaut intégré à l’étape est utilisé et un avertissement le signale.
Sur un corpus
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. Entrée¶
mbox, RFC 5322 ou un corps nu — les trois sont acceptés, et lequel lui est donné est détecté. Une ligne de séparation mbox
From_en tête est retirée (et l’échappement mboxrd>Fromest annulé) ; un corps nu est enveloppé dans unContent-Typeminimal. Un bloc d’en-têtes n’est reconnu que lorsque chaque ligne avant la première ligne vide est un champ ou une continuation repliée, de sorte qu’un corps commençant parRe: the meetingne soit pas pris pour tel ;--body-onlyforce cette lecture.Les en-têtes sont conservés, et jamais classifiés. Le texte des en-têtes n’atteint pas le détecteur — l’étape n’extrait que les parties de corps en ligne — mais
Content-Type,charsetetContent-Transfer-Encodingdécident de ce qu”est le corps. Les jeter classifierait un message quoted-printable, base64 ou HTML d’après son encodage plutôt que d’après sa prose, ce qui est l’un des échecs que l’outil sert à trouver.L’alternative en texte brut l’emporte, sauf si c’est un talon. Pour un
multipart/alternative, la partietext/plainest ce qu’un expéditeur a écrit : elle est donc préférée. Lorsqu’elle ne contient aucune prose — la forme de l’expéditeur de masse, deux URL nues là où devrait être le message — la partie HTML sœur est utilisée à la place, et--explainle dit.Les fins de ligne sont normalisées en CRLF comme le fait pepsi-ingress, de sorte qu’un message lu depuis un fichier se classifie exactement comme l’a fait la copie mise en file.
51.6. Sortie¶
Une ligne : la chaîne de style Accept-Language, par exemple en;q=1, de;q=0.45. Lorsque l’étape ne noterait aucune langue — pas de texte en ligne, trop peu de texte, ou rien au-dessus du seuil de confiance —, la sortie standard est vide et la raison va sur la sortie d’erreur standard. C’est le comportement propre de l’étape, pas une erreur.
51.7. Voir aussi¶
pepsi-stage-detect-language, pepsi-stage-block-language, pepsi-detect-language(1), pepsi.state(7).