5.2. 🚀 Regelbasierte OCR-Nachbearbeitung#
5.2.1. Hinweise zur Ausführung des Notebooks#
Dieses Notebook kann auf unterschiedlichen Levels erarbeitet werden (siehe Abschnitt „Technische Voraussetzungen“):
Book-Only Mode
Cloud Mode: Dafür auf 🚀 klicken und z.B. in Colab ausführen.
Local Mode: Dafür auf Herunterladen ↓ klicken und „.ipynb“ wählen.
5.2.2. Übersicht#
In diesem Notebook wird eine regelbasierte OCR-Nachkorrektur entwickelt und angewendet. Ziel ist es, typische Fehler, die beim OCR-Prozess historischer Texte entstehen, automatisch zu beheben und die Verbesserung messbar zu machen.
Dafür werden folgende Schritte durchgeführt:
Identifikation typischer OCR-Fehler im Korpus (z.B.
<stattch,fiestattsie,ſstatts)Implementierung von Korrekturregeln mit regulären Ausdrücken
Anwendung der Regeln auf ein Beispielbild mittels Tesseract-OCR
Messung der Verbesserung anhand von Precision, Recall und F1-Score im Vergleich mit einem Ground-Truth-Text
(Advanced) Anwendung der Korrekturregeln auf das gesamte Korpus
Show code cell content
# 🚀 Install libraries
import sys
if 'google.colab' in sys.modules:
!sudo apt install tesseract-ocr
!sudo apt install tesseract-ocr-frk
!pip install pytesseract pillow Levenshtein
Requirement already satisfied: pytesseract in /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages (0.3.10)
Requirement already satisfied: pillow in /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages (10.3.0)
Requirement already satisfied: Levenshtein in /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages (0.25.0)
Requirement already satisfied: packaging>=21.3 in /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages (from pytesseract) (24.0)
Requirement already satisfied: rapidfuzz<4.0.0,>=3.1.0 in /opt/hostedtoolcache/Python/3.11.15/x64/lib/python3.11/site-packages (from Levenshtein) (3.7.0)
Show code cell content
import re
import pytesseract
from PIL import Image
from pathlib import Path
from tqdm import tqdm
5.2.3. Typische Fehler#
Im Folgenden 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.
5.2.4. Implementierung von Regeln für typische Fehler mit regulären Ausdrücken#
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
5.2.5. Anwendung der Regeln auf die OCR-Ergebnisse #
Show code cell content
!wget https://raw.githubusercontent.com/quadriga-dk/Text-Fallstudie-1/refs/heads/main/assets/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)
Lass 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
5.2.6. Messung der Verbesserung#
Show code cell content
# only for colab users, to download the auxiliary file with the function to measure the quality of the OCR output
import sys
if 'google.colab' in sys.modules:
import os
os.makedirs('auxiliary', exist_ok=True)
!wget -q -O auxiliary/measure_ocr_quality.py https://raw.githubusercontent.com/quadriga-dk/Text-Fallstudie-1/main/ocr_post_correction/auxiliary/measure_ocr_quality.py
Show code cell content
# 🚀 create folder and get the auxiliary python script to run in Colab
aux_dir = Path("auxiliary")
if not aux_dir.exists():
aux_dir.mkdir(parents=True)
Show code cell content
from auxiliary.measure_ocr_quality import measure_ocr_quality
Lass 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
beiden Tagen auch in Groß-Berlin noch
erheblich gestiegen. Die Warenhäuser und son-
stigen großen Geschäfte, die Kriegs- und die pri-
vaten Betriebe klagen, daß übermäßig viele An-
gestellte sich haben krank melden müssen und auch
bei der Post und bei der Straßenbahn ist der
Prozentsatz der Grippekranken bedeutend ge-
stiegen."""
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.7864
Recall: 0.8418
F1-score: 0.8132
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.8045
Recall: 0.8613
F1-score: 0.832
Also, unsere F-Score hat sich etwas verbessert, gut!
5.2.7. (Advanced) Ausführung des regelbasierten OCR-Nachkorrekturverfahrens auf dem gesamten Korpus#
pathtxt = Path('../data/txt')
if not pathtxt.exists():
pathtxt.mkdir(parents=True)
for file in tqdm(pathtxt.iterdir()):
if file.suffix == '.txt':
text = file.read_text()
corrected = post_correct_text(text)
file.write_text(corrected)