🚀 Regelbasierte OCR-Nachbearbeitung#

🔔 Feinlernziel(e) dieses Kapitels
Sie können die notwendigen Schritte zur Nachbereitung von OCR-Output aufzählen und die Qualität der Nachbereitung bewerten.

Listen wir einige typische Fehler in unserem Korpus auf:

  • “fie” statt “sie” (Bild und Ergebnis später hinzufügen)

  • “vm”, “vnd” statt “um”, “und”

  • “<” statt “ch”

Einige Dinge sind keine Fehler, sondern Merkmale der historischen Orthographie, die wir für die weitere Verarbeitung mit modernen NLP-Tools normalisieren möchten:

  • “ſ” statt “s”

In vielen Fällen können wir dies mit einigen regulären Such- und Ersetzungsmustern beheben (z.B. jedes <, das nicht von Leerzeichen umgeben ist, in ch umwandeln).

Der Standardweg, solche Muster auf einem Computer auszudrücken und zu implementieren, sind reguläre Ausdrücke. Mehr über reguläre Ausdrücke erfahren Sie hier.

Implementierung von Regeln für typische Fehler mit regulären Ausdrücken#

import re
def post_correct_text(ocr_output):
    cleaner_output = re.sub(r'(\w)<(\w)', '\\1ch\\2', ocr_output)
    cleaner_output = re.sub(r'(\w)5(\w)', '\\1s\\2', cleaner_output)
    cleaner_output = re.sub(r'\bv(m|nd)\b', 'u\\1', cleaner_output)
    cleaner_output = re.sub(r'\bfie\b', 'sie', cleaner_output)
    cleaner_output = cleaner_output.replace('ſ','s')
    cleaner_output = cleaner_output.replace('\n',' ')
    return cleaner_output

Anwendung der Regeln auf die OCR-Ergebnisse #

import pytesseract
from PIL import Image
from auxiliary.measure_ocr_quality import measure_ocr_quality
../_images/grippe.jpeg
ocr_output = pytesseract.image_to_string(Image.open('grippe.jpeg'), lang='frk')
print(ocr_output)
Zie Grippe wüfel weiter

Zunahme der ſchweren Fälle in Berlin.

Die Zahl der Grippefälle iſt in den lezten
beider Tagen auch in Groß-Berlin noH
erf>lig zeftiegen. Die Warenhäuſer und ſon-
Haen aroßen GeſHöäfte, die Krirgs- unh die prie
n Betriebe lagen, daß übermäig viele An«-

. fich 5cben rep? melden müſſen,-und an<
; .“ Loft und 5ei der Straßenbahn iſt der
ſos der Grippelranten bedeuten) gt&

MeB 4 2 8 1
ocr_output_corr = post_correct_text(ocr_output)

Lassen Sie uns sehen, wie sich das Ganze verändert hat:

print(ocr_output_corr)
Zie Grippe wüfel weiter  Zunahme der schweren Fälle in Berlin.  Die Zahl der Grippefälle ist in den lezten beider Tagen auch in Groß-Berlin noH erf>lig zeftiegen. Die Warenhäuser und son- Haen aroßen GesHöäfte, die Krirgs- unh die prie n Betriebe lagen, daß übermäig viele An«-  . fich 5cben rep? melden müssen,-und an< ; .“ Loft und 5ei der Straßenbahn ist der sos der Grippelranten bedeuten) gt&  MeB 4 2 8 1 

Messung der Verbesserung#

Lassen Sie uns sehen, wie sich die regelbasierte Nachkorrektur auf die OCR-Qualitätsmetriken ausgewirkt hat

ground_truth = 'Die Grippe wütet weiter. Zunahme der schweren Fälle in Berlin. Die Zahl der Grippefälle ist in den letzten Tagen auch in Groß-Berlin noch erheblich gestiegen. Die Warenhäuser und sonstigen großen Geschäfte, die Kriegs- und die privaten Betriebe klagen, daß übermäßig viele Angestellte sich haben krank melden müssen und auch bei der Post und bei der Straßenbahn ist der Prozentsatz der Grippekranken deutlich gestiegen.'

Originales (unkorrigiertes) OCR-Ergebnis#

precision, recall, f_score = measure_ocr_quality(ocr_output, ground_truth)
print(f'Precision: {round(precision, 4)}\nRecall: {round(recall, 4)}\nF1-score: {round(f_score, 4)}')
Precision: 0.778
Recall: 0.7932
F1-score: 0.7855

Korrigiertes OCR-Ergebnis#

precision, recall, f_score = measure_ocr_quality(ocr_output_corr, ground_truth)
print(f'Precision: {round(precision, 4)}\nRecall: {round(recall, 4)}\nF1-score: {round(f_score, 4)}')
Precision: 0.8091
Recall: 0.8248
F1-score: 0.8169

Also, unsere F-Measure hat sich etwas verbessert, gut!

(Advanced) Ausführung des regelbasierten OCR-Nachkorrekturverfahrens auf dem gesamten Korpus#

from pathlib import Path
from tqdm import tqdm
pathtxt = Path('../data/txt')

for file in tqdm(pathtxt.iterdir()):
    if file.suffix == '.txt':
        text = file.read_text()
        corrected = post_correct_text(text)
        file.write_text(corrected)