[Trennmuster] Lang-S: Text-Transformation

Guenter Milde milde at users.sf.net
Fr Jun 13 12:06:46 CEST 2014


Liebe Trennmustler,

da es inzwischen reichlich Diskussion zum langen S gab, will ich versuchen
eine themensortierte Zusammenfassung zu bringen.

Heute: 

=========================================================================
Die automatische s->ſ Transformation von "normal" geschriebenen
Texten in korrekte Orthographie für den Satz mit gebrochenen Schriften.
=========================================================================

geg.: Text in "de-1901" (traditionelle Orthographie für Antiquasatz, rundes S)

      Liste von 470 000 Wörtern mit korrekter Lang-S-Schreibung, 
      davon 190 000 Wörter mit mindestens einem langem ſ
      und 130 000 Wörter mit mindestens einem kleinem runden s.
      
ges.: Text in "de-1901-Latf" (traditionelle Orthographie für den Satz mit
      gebrochenen Schriften (Latin alphabet, Fraktur), rundes und langes S)

Problem: 
      Während die Wandlung "de-1901-Latf" -> "de-1901" eindeutig ist 
      (replace('ſ', 's')), muß jedes 's' im Ausgangstext je nach Lage im
      Wort entweder in 'ſ' gewandelt werden oder als 's' stehenbleiben.
      
Ansatz:
      Ein Programm vergleicht jedes Wort mit der Liste und ersetzt komplette
      Wörter.
      
Implementierungsvarianten:

1 Dictionary
============

1a) Die Wortliste wird in ein "dictionary/assoziatives Array" gelesen::
 
      words = dict()
      for word in open('words_de-1901-Latf'):
         s_word = word.replace(u'ſ', u's')
         words[s_word] = word
    
    Die Wörter werden ersetzt::
    
      for word in text:
	     ...
         word = words[word]
         ...
	 
    Einfach aber ineffizient und problematisch für Wörter die nicht in der
    Liste sind.

1b) Die Wortliste wird in zwei Dictionaries
    gelesen, eines für Wörter mit langem S, das andere für Wörter mit
	rundem S::

      words_lang = dict()
      words_rund = dict()
      for word in open('words_de-1901-Latf'):
         s_word = word.replace(u'ſ', u's')
         if 'ſ' in word:
             words_lang[s_word] = word
         elif 's' in word:
             words_rund[s_word] = word

     Die Wörter werden ersetzt::

      for word in text:
         ...
	     if 's' in word:
                w_Latf = words_lang[word]
		if (w_Latf == word):
		   assert (word in words_rund, "Achtung: Wort unbekannt!")
		    
         ...

     Etwas effizienter. Rückmeldung für nicht erfaßte Wörter.

Auch mit dem komplexeren Ansatz hat die Implementierung mit Dictionary
das entscheidende Problem, daß nur explizit erfaßte Wörter korrekt gewandelt
werden. Neben einem Speicherproblem bedeutet das auch, daß
Neubildungen und "vergessene" Wörter "Handarbeit" erfordern.

Ein nachgeschalteter Test auf Zusammensetzungen bekannter Wörter (ggf. mit
Fugen-s) kann das Problem mindern, aber nicht beheben.

2 *spell Rechtschreibprüfung
============================

Für die Rechtschreibprüfprogramme ispell/aspell/hunspell wurden effektive
Darstellungen gefunden, um aus ca. 371 000 Einträgen der expandierten Liste
(dump) eine kompakte Liste mit 83 000 Einträgen zu generieren.

Rechtschreibprüfprogramme haben bereits die Fähigkeit zum Ersetzen einzelner
Wörter im Text (under Beibehaltung der Satz- und Steuerzeichen).

Mit einem Wörterbuch "de-1901-Latf" könnte (nach vorheriger Prüfung des
Texts mit "de-1901") automatisch die Wandlung in korrekte Lang-S-Schreibung
mittels "alle Fehler ohne Nachfrage korrigieren" erfolgen.

Es bleibt das Problem der nicht erfaßten Wörter bzw. der Einträge in privaten
Wörterbüchern.

Allerdings ist ein solches Wörterbuch auch für die Kontrolle vorhandener oder
selbst mit Langem-S erstellter Texte äußerst wünschenswert.


Was ist dafür noch nötig?
-------------------------

* Prüfen und ggf. Auszeichnung und Aufnahme von ca. 700 Wörtern, die in
  der kompakten aspell-Wortliste, aber nicht in unserer Wortliste sind.
  (sowieso sinnvoll)
  
* Prüfen der ca. 400 Wörter und Abkürzungen mit weniger als 4 Buchstaben.
  
  Problem: es gibt viele Ausnahme für Abkürzungen, da diese so
  geschrieben werden wie die Langform, z.B.  "und ſo weiter" -> "uſw."

* Skript zum Übertragen der Lang-S-Schreibung auf die kompakte Liste

* Kontakt zu Björn Jacke, dem Maintainer der deutschen *spell-Listen.


3 patgen-generierte Muster
==========================

Die von Frank Liang entwickelte Datenstruktur "packed trie" ist äußerst
effizient für die Aufgabe, in Zeichenketten an durch Beispiele bestimmte
Stellen (Trenn-) Zeichen einzufügen.

Ein wesentlicher Vorteil der patgen-Muster ist ihre "Assoziativität": da die
Bildungsgesetze und Reglemäßigkeiten natürlicher Sprachen gut mit dem
Kompressionsalgorithmus von patgen zusammenpassen, ist für die Mehrzahl von
nicht explizit angelernten Wörtern die Ausgabe der Trennstellen korrekt.

Da die Lang-S schreibung hauptsächlich auf der Grundannahme
  
  langes S im Wort
  rundes S am Wort- und Silbenende
  
beruht, können wir patgen für die oben gestellte Aufgabe der automatischen
Textkonversion nutzen:

1. Mustererstellung

   Aus der Liste von 470 000 Wörtern mit korrekter Lang-S-Schreibung,
   wird durch die zweistufige Transformation
   
      "s"  ->  "s-"  # am Wortende "s"
      "ſ"  ->  "s"
      
   eine Pseudo-Trennliste erzeugt, welche nur Trennstellen enthält, die auf
   ein Rund-S folgen:
   
      Aachen
      ...
      Aals
      Aalschokker
      Aals-meer
      Aalst
      ...
      aus-drucks-stark
      ...

   Diese Liste wird mit "patgen" zu einem Mustersatz komprimiert.
   
2. Konversion auf Basis des "Lang-S-Mustersatzes"

   Mit dem "TeX hyphenation algorithm" (oder einer der Portierungen auf
   Perl, Ruby, Python, PHP, ...) werden für die Wörter des Textes
   "Lang-S-Trennstellen" bestimmt::
   
       for word in text:
           word = hyphenate_word(word, trie="de-1901-Lang-S")
	   
   Damit hätten wir für "ausdrucksstark" wieder "aus-drucks-stark".

   Nun erfolgt die Rückwandlung in ein "Lang-S-Wort"::
   
           word = word[:-1].replace('s', 'ſ') + word[-1:] # Schlußbuchstabe bleibt
	   word = word.replace('ſ-', 's')
	   
   Das wäre dann wieder "ausdrucksſtark".
   
   Abkürzungen mit "ſ" am Wortende müssen über eine Ausnahmeliste
   abgefangen werden. (Ein S am Ende eines "Halbworts" wie in »Aus-
   und Weiterbildung« wird immer rund geschrieben.)
   

Vorteile dieses Ansatzes sind die Effizienz und die Behandlung von nicht
erfaßten Wörtern über die Generalisierung der verarbeiteten Stichprobe.

Was ist dafür noch nötig?
-------------------------

* Extraktionsskript für die "Lang-S-Pseudo-Trennliste"

* Make target

* Anwenderprogramm, z.B. als Python-Skript, Texteditor-Plug-in oder
  LuaTeX-Paket.



Ich hoffe das bringt etwas Klarheit.

Viele Grüße

Günter



Mehr Informationen über die Mailingliste Trennmuster