5.4. 🚀 Analyse syntaktischer N-Gramme#
5.4.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.4.2. Übersicht#
Im Folgenden wird das Korpus mithilfe syntaktischer n-Gramme analysiert. Ziel dieser Analyse ist es, wiederkehrende grammatische Muster (insbesondere adjektivische Modifikationen von Substantiven) über Zeit zu untersuchen und damit über rein lexikalische Häufigkeiten hinauszugehen. Im Unterschied zur Analyse semantischer Felder stehen hier strukturierte, syntaktisch motivierte Wortkombinationen im Fokus, die auf Abhängigkeitsbeziehungen basieren.
Konkret wird untersucht, wie häufig bestimmte syntaktische Konstruktionen (z. B. Adjektiv → Substantiv-Relationen) im Korpus auftreten und wie sich deren Vorkommen zeitlich entwickelt. Dies erlaubt es, stilistische und diskursive Entwicklungen sichtbar zu machen, etwa Veränderungen in der Beschreibung bestimmter Konzepte über längere Zeiträume hinweg.
Dazu werden die folgenden Schritte durchgeführt:
Einlesen des Korpus, der Metadaten sowie der bereits erzeugten spaCy-Annotationen
Auswahl relevanter Dependency-Relationen zur Bildung syntaktischer n-Gramme
Extraktion syntaktischer n-Gramme auf Basis der vorhandenen Abhängigkeitsinformationen
Identifikation von Ausreißertexten, die auffällige Peaks in den Zeitreihen (mit-)verursachen
KWIC-/Kontextansicht ausgewählter Belegstellen aus diesen Texten zur qualitativen Einordnung der syntaktischen Muster
Diskussion der Ergebnisse
5.4.3. Import der Bibliotheken#
Laden des spaCy-Modells
5.4.4. Laden der Annotationen#
In diesem Schritt werden die zuvor erzeugten spaCy-Annotationen aus dem Dateisystem eingelesen. Die gespeicherten DocBin-Dateien werden zu vollständigen spaCy.Doc-Objekten rekonstruiert und in einer Datenstruktur abgelegt, die eine weitere Analyse erlaubt.
# Bei Verwendung eines anderen Korpus hier den Verzeichnisnamen anpassen
annotation_dir = Path("../data/spacy")
if not annotation_dir.exists():
print("The directory does not exist, please check the path again.")
5.4.5. Metadaten einlesen#
Anschließend werden die zugehörigen Metadaten geladen und auf diejenigen Texte beschränkt, für die Annotationen vorliegen. Die zeitlichen Angaben werden in ein geeignetes Datumsformat überführt, um spätere zeitbasierte Aggregationen und Visualisierungen zu erleichtern.
metadata_df = pd.read_csv("../metadata/metadata_corpus-german_language_fiction_1820-1900_50-per-decade.csv")
# metadata_df = metadata_df[metadata_df['ID'].isin(annotated_docs.keys())]
# Datentyp der Datumsspalte für eine einfachere Weiterverarbeitung ändern
metadata_df['year'] = pd.to_datetime(metadata_df['year'], format="%Y")
show(metadata_df)
| Loading ITables v2.6.1 from the internet... (need help?) |
metadata_df_alt = pd.read_csv("../metadata/metadata_corpus-german_language_fiction_1820-1900_50-per-decade_ALT.csv")
# metadata_df_alt = metadata_df_alt[metadata_df_alt['ID'].isin(annotated_docs.keys())]
# Datentyp der Datumsspalte für eine einfachere Weiterverarbeitung ändern
metadata_df_alt['year'] = pd.to_datetime(metadata_df_alt['year'], format="%Y")
show(metadata_df_alt)
| Loading ITables v2.6.1 from the internet... (need help?) |
5.4.6. Syntaktische N-Gramme extrahieren#
In einem weiteren Schritt können wir die Adjektive extrahieren, die mit dem Nomen Luft in Verbindung stehen. Wir machen dabei Gebrauch von den Dependenzstrukturen, die sich durch das spaCy-eigene Doc einfach navigieren lassen.
noun = "Luft"
adj_df, top_adjs = extract_dependent_adjective_list(annotated_docs, metadata_df, noun, top_n=10)
adj_df_alt, top_adjs_alt = extract_dependent_adjective_list(annotated_docs, metadata_df_alt, noun, top_n=10)
5.4.7. Laden gespeicherter Ergebnisse (Optional)#
Falls die Ergebnisse bereits extrahiert und als CSV gespeichert wurden, können sie hier geladen werden, anstatt die Extraktion erneut durchzuführen.
5.4.8. Analyse und Visualisierung#
Korpusweite Häufigkeiten adjektivischer Modifikatoren#
Zunächst betrachten wir die Gesamtverteilung der adjektivischen Modifikatoren. Bevor zeitliche Entwicklungen analysiert werden, ist es sinnvoll, einen Überblick darüber zu gewinnen, welche Adjektive im gesamten Korpus am häufigsten als syntaktische Modifikatoren der untersuchten Substantive auftreten. Diese aggregierte Betrachtung erlaubt es, dominante Beschreibungs- und Bewertungsmuster zu identifizieren und dient zugleich als Ausgangspunkt für die nachfolgenden diachronen Analysen.
Sample 1:#
totals = plot_top_adjective_ranking(adj_df, top_n=20, noun_input=noun, metric="count")
show_top_adjectives_table(adj_df)
Sample 2:#
totals_alt = plot_top_adjective_ranking(adj_df_alt, top_n=20, noun_input=noun, metric="count")
show_top_adjectives_table(adj_df_alt)
Diachrone Analyse adjektivisch-substantivischer Konstruktionen#
Im nächsten Schritt wird die Analyse um eine diachrone Perspektive erweitert. Anstatt ausschließlich korpusweite Gesamthäufigkeiten zu betrachten, wird nun untersucht, wie sich die Verwendung der zuvor identifizierten adjektivischen Modifikatoren im Zeitverlauf entwickelt. Die zeitliche Aggregation erlaubt es, Verschiebungen in Beschreibungs- und Bewertungsmustern nachzuzeichnen und diese mit historischen Prozessen in Beziehung zu setzen.
Sample 1#
# yearly lineplots + moving average
yearly_1, moving_1 = plot_adjective_trends_moving_avg_plotly(
adj_df, top_adjs, noun_input=noun, window_years=10, n_plot=8
)
Sample 2:#
# NEW: yearly lineplots + moving average
yearly_2, moving_2 = plot_adjective_trends_moving_avg_plotly(
adj_df_alt, top_adjs_alt, noun_input=noun, window_years=10, n_plot=8
)
Ausreißertexte und Kontextanalyse#
Welche konkreten Texte sind für die Ausschläge in den Zeitreihen verantwortlich?
Um diese Frage transparent zu beantworten, identifizieren wir sogenannte „Ausreißertexte“ (aber nicht über einen komplexen statistischen Test, sondern über eine nachvollziehbare Zähl- und Ranking-Logik). Für jedes Werk zählen wir (1) noun_count, also wie oft das Lemma Luft im Text vorkommt, und (2) count, also wie oft ein bestimmtes Adjektiv (z.B. frisch) in der Dependenzannotation als attributiver Modifikator von Luft erscheint (ADJ → Luft, z.B. frische Luft). Daraus berechnen wir pro Text eine normalisierte Kennzahl rel_freq = (count / noun_count) * 100, also den Anteil der Luft-Vorkommen, die mit diesem Adjektiv modifiziert werden.
Anschließend bestimmen wir für jedes Adjektiv zunächst die Dekaden, in denen der Durchschnitt dieser relativen Häufigkeit besonders hoch ist (Peak-Dekaden), und listen innerhalb dieser Zeitfenster die Texte mit den höchsten rel_freq-Werten (Top-k) als „Ausreißertexte“ auf. Um instabile Extremwerte zu vermeiden, filtern wir Texte mit sehr wenigen Luft-Belegen (z.B. noun_count < 5) aus. Ergänzend berechnen wir pro Dekade den Anteil eines einzelnen Textes an allen Adjektiv→Luft-Treffern (share_of_adj_count_in_decade), um sichtbar zu machen, ob ein Ausschlag der Zeitreihe vor allem von wenigen Werken getragen wird. Diese identifizierten Texte werden anschließend mithilfe von KWIC- bzw. Satzkontexten qualitativ überprüft, um die semantische Funktion der jeweiligen Konstruktionen genauer einzuordnen.
Die folgende Tabelle listet die identifizierten Ausreißertexte für die jeweiligen Adjektiv–Nomen-Konstruktionen auf, also jene Werke, die maßgeblich zu den beobachteten Ausschlägen in den Zeitreihen beitragen (in Sample 1).
show(outliers_table_1)
| Loading ITables v2.6.1 from the internet... (need help?) |
Die KWIC-Ansicht zeigt ausgewählte Satzkontexte der Adjektiv–Nomen-Konstruktionen aus diesen Ausreißertexten und ermöglicht eine qualitative Einordnung ihrer semantischen Verwendung.
show(kwic_table_1)
| Loading ITables v2.6.1 from the internet... (need help?) |
Die folgende Tabelle listet die identifizierten Ausreißertexte für die jeweiligen Adjektiv–Nomen-Konstruktionen auf, also jene Werke, die maßgeblich zu den beobachteten Ausschlägen in den Zeitreihen beitragen (in Sample 2).
show(outliers_table_2)
| Loading ITables v2.6.1 from the internet... (need help?) |
Die KWIC-Ansicht zeigt ausgewählte Satzkontexte der Adjektiv–Nomen-Konstruktionen aus diesen Ausreißertexten und ermöglicht eine qualitative Einordnung ihrer semantischen Verwendung.
show(kwic_table_2)
| Loading ITables v2.6.1 from the internet... (need help?) |
5.4.9. Diskussion der syntaktischen N-Gramm-Analyse#
Die syntaktische N-Gramm-Analyse verschiebt den Blick von der bloßen Häufigkeit des Begriffs Luft hin zur Frage, wie über Luft gesprochen wird – also welche Adjektive als Modifikatoren in Konstruktionen wie frische Luft, reine Luft oder freie Luft auftreten. Damit rückt nicht nur das Thema, sondern auch die semantische Rahmung in den Fokus (z.B. Luft als Naturerlebnis vs. Luft als „Qualität“ im hygienischen/medizinischen Sinn).
Über beide Stichproben hinweg zeigt sich, dass einige Modifikatoren sehr stabil und dominant sind – insbesondere frisch (und in Teilen auch frei). Das spricht dafür, dass bestimmte Formulierungen im 19. Jahrhundert als relativ feste sprachliche Muster etabliert sind. Gleichzeitig treten zeitweise stärkere Ausschläge einzelner Adjektive (z.B. klar, rein, leer oder still) auf. Solche Peaks können als Hinweis auf zeitgebundene Konjunkturen bestimmter Redeweisen gelesen werden, sollten jedoch nicht vorschnell historisch „übererklärt“ werden.
Denn es gibt mehrere Deutungs- und Einschränkungsansätze:
Einfluss einzelner Texte / Ausreißer:
Die hier dargestellte relative Häufigkeit wird pro Text normalisiert (Anzahl der Adjektiv-Nomen-Konstruktionen im Verhältnis zu allen Vorkommen von Luft) und anschließend pro Jahr gemittelt. In Zeitfenstern mit wenigen Texten oder mit wenigen Luft-Belegen pro Text können einzelne Werke die Kurven deutlich beeinflussen. Entsprechend haben wir im Anschluss an die Zeitreihenanalyse Ausreißertexte identifiziert, also jene Werke, die innerhalb der Peak-Zeitfenster besonders hohe Werte aufweisen und die Ausschläge der Kurven (teilweise) tragen.Mehrdeutigkeit der Konstruktionen (Kontextabhängigkeit):
Dieselbe Oberfläche kann in sehr unterschiedlichen Kontexten auftreten (z.B. Naturbeschreibung, Wetter/Temperatur, Hygiene/Atmung, Metaphern der Stimmung oder räumliche Wendungen wie „in freier Luft“). Daher wurden exemplarische KWIC- bzw. Satzkontexte aus den Ausreißertexten herangezogen, um sichtbar zu machen, welche semantischen Funktionen die jeweiligen Adjektiv–Nomen-Konstruktionen in konkreten Textstellen erfüllen (z.B. phraseologische Wendungen, naturpoetische Beschreibungen oder metaphorische Verwendungen wie „leere Luft“).Operationalisierung und Modellgrenzen:
Die Extraktion basiert auf syntaktischen Abhängigkeiten (Adjektive als Modifikatoren von Luft). Parserfehler, Lemmatisierung und die Beschränkung auf eine Konstruktion (Adjektiv → Nomen) können dazu führen, dass relevante Stellen übersehen werden (z.B. komplexere Umschreibungen, ironische oder indirekte Thematisierung von Luftqualität). Außerdem kann die Normalisierung bei sehr wenigen Luft-Belegen pro Text zu instabilen relativen Werten führen, weshalb entsprechende Mindestschwellen (z.B.noun_count) sinnvoll sind.
Insgesamt deuten die Ergebnisse darauf hin, dass Literatur des 19. Jahrhunderts Luft häufig in Form einiger wiederkehrender Qualifizierungen rahmt (besonders frisch und frei), während andere Attribute phasenweise stärker werden und potenziell mit Gattungen, Themenfeldern oder historischen Diskursen (Natur, Hygiene, Urbanität) zusammenhängen könnten. Die ergänzende Ausreißertext- und KWIC-Auswertung hilft dabei, die Kurven zu „erden“: Sie zeigt, ob Peaks eher breit über viele Texte verteilt sind (stabile Muster) oder ob einzelne Werke/Genre-Kontexte den Ausschlag geben, und sie macht anhand konkreter Belegstellen sichtbar, ob eine Konstruktion eher wörtlich-physisch, naturpoetisch oder metaphorisch gebraucht wird. Für weitergehende, belastbarere Interpretationen wäre als Anschluss besonders sinnvoll, die KWIC-Belege systematischer zu kategorisieren (z.B. Natur/Wetter vs. Hygiene/Atmung vs. Metapher) und die Kontexte gezielt zwischen Peak- und Nicht-Peak-Phasen zu kontrastieren.