Die normale Textkorrektur mit aspell (oder ispell oder hunspell) prüft leider nur einzelne Wörter. Fehler bei der Groß-/Kleinschreibung und Grammatikfehler werden zum Beispiel häufig nicht erkannt: »Die Text ist am Besten.« Das Programm LanguageTool hingegen kann dies, weshalb es sich als Ergänzung oder Ersatz für die Textprüfung lohnt. Da das Programm unter der LGPL entwickelt wird, steht der Quelltext zur Verfügung und somit lässt sich eine eigene Instanz einrichten.

Installation

Für LanguageTool wird die Java-Umgebung benötigt: apt install default-jre-headless oder konkret eine aktuelle Version von OpenJDK apt install openjdk-11-jre-headless. Das Paket mit LanguageTool muss von dessen Webseite geladen und in ein Verzeichnis entpackt werden:

% sudo unzip LanguageTool-4.9.1.zip -d /opt
% sudo mv /opt/LanguageTool-4.9.1 /opt/LanguageTool

Um zu prüfen, ob die Installation funktioniert, kann man das Kommandozeilenprogramm von LanguageTool verwenden und einen einfachen Text überprüfen lassen:

% java -Dfile.encoding=UTF-8 -jar /opt/LanguageTool/languagetool-commandline.jar -c utf8 -l de-DE <<<'Die Text ist am Besten.'
Expected text language: German (Germany)
Working on STDIN...
1.) Line 1, column 1, Rule ID: DE_AGREEMENT
Message: Möglicherweise fehlende grammatische Übereinstimmung des Genus (männlich, weiblich, sächlich - Beispiel: 'der Fahrrad' statt 'das Fahrrad') und Numerus (Einzahl, Mehrzahl - Beispiel: 'das Fahrräder' statt 'die Fahrräder').
Suggestion: Dem Text; Den Text; Der Text; Die Texte
Die Text ist am Besten.
^^^^^^^^

2.) Line 1, column 17, Rule ID: AM_BESTEN[1]
Message: In der Wendung 'am besten' schreibt man 'besten' klein.
Suggestion: besten
Die Text ist am Besten.
                ^^^^^^
More info: https://www.korrekturen.de/beliebte_fehler/am-besten.shtml
Time: 1496ms for 1 sentences (0.7 sentences/sec)

Daten für n-Gramme installieren

Zur Verbesserung der Fehlererkennung gibt es Erweiterungsdaten für n-Gramme. Die Idee dahinter ist, die Korrektheit von Wörtern mithilfe eines, zweier oder mehrerer Nachbarwörter zu prüfen, also ob das Wort in die Wortgruppe passt.

Vorsicht: Diese Daten sind mehrere Gigabyte groß, also darauf achten, ob das Verzeichnis vom Backup erfasst wird.

Die gewünschten Pakete von languagetool.org/download/ngram-data/ laden und in ein Verzeichnis (z. B. /opt/LanguageTool-ngram) entpacken.

Den Unterschied in der Fehlererkennung sieht man an diesem Beispiel:


% java -Dfile.encoding=UTF-8 -jar /opt/LanguageTool/languagetool-commandline.jar -c utf8 -l de-DE <<<'In den christlichen Traditionen gibt es unterschiedliche Anleitungen zur Mediation und Kontemplation.'
Expected text language: German (Germany)
Working on STDIN...
Time: 1458ms for 1 sentences (0.7 sentences/sec)
java -enableassertions -Dfile.encoding=UTF-8 -jar  -c utf8 -l de-DE <<<   usr 15,35s sys 0,41s tot 4,838 698MB pf 0 182680 cs 8453 5425

% java -Dfile.encoding=UTF-8 -jar /opt/LanguageTool/languagetool-commandline.jar -c utf8 -l de-DE --languagemodel /opt/LanguageTool-ngram <<<'In den christlichen Traditionen gibt es unterschiedliche Anleitungen zur Mediation und Kontemplation.'
Expected text language: German (Germany)
Working on STDIN...
1.) Line 1, column 74, Rule ID: CONFUSION_RULE
Message: Rein statistisch ist 'Meditation' (spirituelle Übung) in diesem Kontext wahrscheinlicher als 'Mediation' (Verfahren zur Konfliktlösung). Bitte prüfen.
Suggestion: Meditation
...nen gibt es unterschiedliche Anleitungen zur Mediation und Kontemplation.
                                                ^^^^^^^^^
Time: 1583ms for 1 sentences (0.6 sentences/sec)
java -enableassertions -Dfile.encoding=UTF-8 -jar  -c utf8 -l de-DE   <<<   usr 17,46s sys 0,41s tot 5,355 701MB pf 0 181455 cs 9875 6135

Daten für word2vec einrichten

Es gibt noch eine weitere Erweiterung für die Erkennung von Fehlern, die mit einem Word2vec-Modell für ein neuronales Netzwerk arbeitet. Aktuell (Juli 2020) funktioniert sie, jedoch kümmert sich nicht niemand mehr um den Code.

Ein Beispiel für die verbesserte Erkennung zeigt sich an diesem Text:

Ich glaube, das der Spieleabend gut besucht sein wir, da wir fiel Werbung gemacht haben. Was machst du den da? Ab wann seit ihr in der Uni? Ich bin gerade ihm Copyshop.

Ob die Erkennung funktioniert, lässt sich mit folgendem kleinen Beispiel prüfen:

% java -Dfile.encoding=UTF-8 -jar /opt/LanguageTool/languagetool-commandline.jar \
  -c utf8 -l de-DE --languagemodel /opt/LanguageTool-ngram \
  --word2vecmodel /opt/LanguageTool-word2vec <<<'Was machst du den da?'
Expected text language: German (Germany)
Working on STDIN...
1.) Line 1, column 15, Rule ID: DE_den_VS_denn_NEURALNETWORK
Message: Unser neuronales Netz sagt, dass 'denn' hier korrekt sein könnte statt 'den'. Bitte prüfen.
Suggestion: denn
Was machst du den da?
              ^^^
Time: 1341ms for 1 sentences (0.7 sentences/sec)

Bessere Spracherkennung mit Fasttext

Es gibt noch ein Modul für bessere Spracherkennung, aber deren Sinn hat sich mir nicht so richtig erschlossen. Bei gemischtsprachigen Texten war die Erkennung auch nicht besser und sonst gebe ich immer die Sprache an. Vielleicht ist es für Texte, bei denen keine Sprache angegeben wurde.

Die Datenbank lid.176.bin muss man von der Seite fastText laden und beim Aufruf des Kommandozeilenprogramms gibt man --fasttextbinary … mit dem Dateinamen an.

Der Dienst, wie er im Abschnitt über Systemd genutzt wird, muss mit einer Konfigurationsdatei genutzt werden. Eine Kommandozeilenoption des Serverdienstes für Fasttext habe ich nicht gefunden.

Systemd einrichten

Die Einrichtung des Servers gemäß Wiki ist recht einfach, jedoch sollte bedacht werden, dass der Prozess im Betrieb auf eine Größe von 2,5 Gigabyte RAM anwächst. Der Prozess ist ein HTTP-Server (ohne SSL) und kann nur auf dem Standardport 8081 betrieben werden, da die Firefox-App nur diesen Port unterstützt.

Wie immer lässt sich ein solcher Dienst leicht mit Systemd einrichten: sudo systemctl edit --force --full languagetool.service:


[Unit]
Description=LanguageTool server
Documentation=https://languagetool.org/
Documentation=http://wiki.languagetool.org/http-server

[Service]
ExecStart=/usr/bin/java -cp /opt/LanguageTool/languagetool-server.jar org.languagetool.server.HTTPServer --allow-origin * --languageModel /opt/LanguageTool-ngram --word2vecModel /opt/LanguageTool-word2vec
LockPersonality=yes
NoNewPrivileges=yes
Restart=on-failure
RestrictNamespaces=yes
ProtectHome=yes
ProtectSystem=full
SystemCallArchitectures=native
SystemCallFilter=@system-service
User=daemon
Group=daemon

[Install]
WantedBy=multi-user.target

Danach den Dienst aktivieren und gleich starten sudo systemctl enable --now languagetool.service und mit einer einfach Abfrage prüfen:


% curl -s --data "language=de-DE&text=Eine erster Versuch" http://localhost:8081/v2/check |jq .
{
  "software": {
    "name": "LanguageTool",
    "version": "4.9.1",
    "buildDate": "2020-04-27 15:56",
    "apiVersion": 1,
    "premium": false,
    "premiumHint": "You might be missing errors only the Premium version can find. Contact us at supportlanguagetoolplus.com.",
    "status": ""
  },
  "warnings": {
    "incompleteResults": false
  },
  "language": {
    "name": "German (Germany)",
    "code": "de-DE",
    "detectedLanguage": {
      "name": "German (Germany)",
      "code": "de-DE",
      "confidence": 0.9999903
    }
  },
  "matches": [
    {
      "message": "Möglicherweise fehlende grammatische Übereinstimmung von Kasus, Numerus oder Genus. Beispiel: 'mein kleiner Haus' statt 'mein kleines Haus'",
      "shortMessage": "Möglicherweise keine Übereinstimmung von Kasus, Numerus oder Genus",
      "replacements": [],
      "offset": 0,
      "length": 19,
      "context": {
        "text": "Eine erster Versuch",
        "offset": 0,
        "length": 19
      },
      "sentence": "Eine erster Versuch",
      "type": {
        "typeName": "Other"
      },
      "rule": {
        "id": "DE_AGREEMENT",
        "description": "Kongruenz von Nominalphrasen (unvollständig!), z.B. 'mein kleiner(kleines) Haus'",
        "issueType": "uncategorized",
        "category": {
          "id": "GRAMMAR",
          "name": "Grammatik"
        }
      },
      "ignoreForIncompleteSentence": true,
      "contextForSureMatch": 6
    }
  ]
}

Firefox-Addon

Für den Browser Firefox, aber auch für Chrome, gibt es ein Addon, damit während der Eingabe die Rechtschreibkontrolle von LanguageTool genutzt wird. An vielen Stellen ist dies praktisch, aber bei Chats nervt es zum Teil, da man dort nicht immer exaktes Deutsch schreibt. Weiterhin hat die Erweiterung den Nachteil, dass die Korrekturvorschläge mit einem Links-Klick und nicht mit der rechten Maustaste erscheinen und somit die Menütaste an der Tastatur nicht genutzt werden kann. Die Prüfung mit LanguageTool ist auch nicht so schnell wie die eingebaute Rechtschreibprüfung, weshalb man oft Tippfehler erst einige Worte später angezeigt bekommt und dann zurück zum Wort laufen muss und dann wieder an die Tippposition.

Vorsicht ist auch bei der Erweiterung geboten, da man zum Teil sensible Texte (auch Passwörter z. B. bei /join #channel key bei IRC und Matrix) eingibt, die dann an einen Server übertragen werden. Die Erweiterung sollte also nur mit einem eigenen Server genutzt werden.

Den Server kann man in den Einstellungen zum Addon unter Experimental settings (only for advanced users) auf Local server (localhost) umschalten.

Emacs-Mode langtool für Servernutzung

Für Emacs gibt es das Melpa-Paket langtool, mit dem man einen LanguageTool-Server nutzen kann. Aber auch hier ist die Warnung wie beim Firefox-Addon: Es sollte nur ein vertrauenswürdiger Server genutzt werden, da alle Texte dorthin gesandt werden.

Die Installation ist recht leicht über M-x package-list-packages und die Konfiguration in der init.el ist übersichtlich kurz:

(setq
 langtool-http-server-host "localhost"
 langtool-http-server-port 8081
 langtool-mother-tongue "de-DE"
 langtool-default-language "de-DE"
 )

Nutzen lässt sich die Textprüfung mit M-x langtool-check, womit der aktive Bereich oder die gesamte Datei geprüft werden. Fehler werden dann hervorgehoben und können mit M-x langtool-correct-buffer schrittweise bearbeitet werden. Die Textprüfung kann mit M-x langtool-check-done abgeschlossen werden, wodurch die Hervorhebungen verschwinden.

Nützlich ist es, mit M-h den aktuellen Absatz als Region vor der Prüfung zu markieren.

Wenn man mit langtool-correct-buffer die Fehlerstellen durchgeht, kann man mit

  • der Leertaste auch Fehler überspringen
  • i ein Wort im gesamten Dokument ignorieren
  • e den Text direkt bearbeiten, wobei man mit C-M-c (Strg+Alt+c) die Bearbeitung beenden kann.

Emacs-Mode languagetool für lokale Nutzung

Den ersten Versuch habe ich mit dem Melpa-Paket languagetoool (Installation über M-x package-list-packages) unternommen, welches den Vorteil hat, dass es LanguageTool als Prozess aufruft und über eine Standardein- und -ausgabe kommuniziert. Da ich dann aber auch das Firefox-Addon genutzt habe, brauchte ich die Servervariante und bin daher auf das Emacs-Paket langtool umgestiegen.

(setq
 languagetool-language-tool-jar (expand-file-name
   "/opt/LanguageTool/languagetool-commandline.jar")

 languagetool-java-arguments '("-Dfile.encoding=UTF-8")
 languagetool-default-language "de-DE"
 languagetool-mother-tongue "de-DE"
 languagetool-language-tool-arguments '("--languagemodel"
   (expand-file-name "/opt/LanguageTool-ngram"))
 )

Die Prüfung des Textes kann man mit M-x languagetool-check vornehmen, ggf. zuvor mit M-h den Paragraph markieren. Fehler und Statusmeldungen findet man im Puffer *LanguageTool Output*.

Beispiele für Fehlererkennung

Im Leben lernt der Mensch als erstes ["Erstes" scheint hier ein Nomen zu sein und muss dann großgeschrieben werden.] das Gehen und Sprechen. Später lernt er still zu sitzen [Wenn der erweiterte Infinitv von dem Verb 'stillsitzen' abgeleitet ist, sollte er zusammengeschrieben werden.] und den Mund zu halten.

Weitere Informationen

Bei LWN gibt es den Beitrag »Tools to improve English text«, der auch LanguageTool als hilfreich erwähnt, aber noch weitere Programme aufführt. Das Ziel des Artikels sind die Dokumentation von Software, weshalb auch recht spezielle Programme genannt werden:

  • Codespell sucht nach typischen Fehlern in Quelltext. Der Vorteil ist, dass es zwischen Programmcode und Dokumentation unterscheiden kann.
  • Vale ist wie ein Coding-Style-Prüfer nur eben für Texte. Man kann ein Regelwerk verfassen, um eine Einheitlichkeit in den Texten zu erreichen. Das ist hilfreich, wenn unterschiedliche Leute (durch Patches) an einem Text schreiben.
  • RedPen scheint ähnlich wie LanguageTool eine umfassendere Prüfung vorzunehmen, u. a. werden auch wiederholte Wortvorkommen geprüft. Es gibt eine Online-Demo jedoch ohne Deutsch.