🚀 Analyse 2: Keyword in Context (KWIC)#
🔔 Feinlernziel(e) dieses Kapitels
Sie können die Darstellungsmethode Keywords in Context beschreiben, Wörter zur Anzeige auswählen und diese anzeigen lassen.
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.
Übersicht#
Im Folgenden werden die annotierten Dateien (CSV-Format) analysiert. Unser Ziel ist es, den annotierten Korpus zu nutzen, um KWIC-Ausgaben zu erzeugen.
Dafür werden folgendene Schritte durchgeführt:
Einlesen des Korpus, der Metadaten und der Grippe-Wortliste
Extraktion und Darstellung der Wortkontexte durch KWIC
Informationen zum Ausführen des Notebooks – Zum Ausklappen klicken ⬇️
Voraussetzungen zur Ausführung des Jupyter Notebooks
- Installieren der Bibliotheken
- Pfad zu den Daten setzen
- Laden der Daten (z.B. über den Command `wget` (s.u.))
Show code cell content
# 🚀 Install libraries
! pip install pandas bokeh
Show code cell content
import re
from pathlib import Path
import pandas as pd
import requests
## for interactivity in jupyter books
from bokeh.io import output_notebook, show
from bokeh.layouts import column, layout
from bokeh.models import ColumnDataSource, DataTable, DateFormatter, TableColumn
# Ensure Bokeh output is displayed in the notebook
output_notebook()
1. Einlesen der Daten, Metadaten#
1.1 Einlesen des Korpus (CSV-Dateien)#
Informationen zum Ausführen des Notebooks – Zum Ausklappen klicken ⬇️
Zuerst wird der Ordner angelegt, in dem die CSV-Dateien gespeichert werden. Der Einfachheit halber wird die gleich Datenablagestruktur wie in dem GitHub Repository, in dem die Daten gespeichert sind, vorausgesetzt. Danach werden alle CSV-Dateien im Korpus heruntergeladen und gespeichert. Dafür sind folgende Schritte nötig:- Es wird eine Liste erstellt, die die URLs zu den einzelnen CSV-Dateien beinhaltet.
- Die Liste wird als txt-Datei gespeichert.
- Alle Dateien aus der Liste werden heruntergeladen und in dem Ordner ../data/csv gespeichert.
Show code cell content
# 🚀 Create data directory path
corpus_dir = Path("../data/csv")
if not corpus_dir.exists():
corpus_dir.mkdir(parents=True)
Show code cell content
# 🚀 Create download list
github_api_txt_dir_path = "https://api.github.com/repos/dh-network/quadriga/contents/data/csv"
txt_dir_info = requests.get(github_api_txt_dir_path).json()
url_list = [entry["download_url"] for entry in txt_dir_info]
# 🚀 Write download list as txt file
url_list_path = Path("github_csv_file_urls.txt")
with url_list_path.open('w') as output_txt:
output_txt.write("\n".join(url_list))
Show code cell content
# ⚠️ Only execute, if you haven't downloaded the files yet!
# 🚀 Download all csv files – this step will take a while (ca. 7 minutes)
! wget -i github_csv_file_urls.txt -P ../data/csv
Setzen des Pfads:
# set the path to csv files to be processed
csv_dir = Path(r"../data/csv")
# Create dictionary to save the corpus data (filenames and tables)
corpus_annotations = {}
# Iterate over csv files
for file in csv_dir.iterdir():
# check if the entry is a file, not a directory
if file.is_file():
# check if the file has the correct suffix csv
if file.suffix == '.csv':
# read the csv table to a data frame
data = pd.read_csv(file)
# save the data frame to the dictionary, key=filename (without suffix), value=dataframe
corpus_annotations[file.name] = data
1.2 Einlesen der Metadaten#
Informationen zum Ausführen des Notebooks – Zum Ausklappen klicken ⬇️
Zuerst wird der Ordner angelegt, in dem die Metadaten-Datei gespeichert wird. Wieder wird die gleich Datenablagestruktur wie in dem GitHub Repository vorausgesetzt. Der Text wird aus GitHub heruntergeladen und in dem Ordner ../data/metadata/ abgespeichert. Der Pfad kann in der Variable metadata_path angepasst werden. Die einzulesende Datei muss die Endung `.csv` haben.Show code cell content
# 🚀 Create metadata directory path
metadata_dir = Path("../data/metadata")
if not metadata_dir.exists():
metadata_dir.mkdir()
Show code cell content
# 🚀 Load the metadata file from GitHub
! wget https://raw.githubusercontent.com/dh-network/quadriga/refs/heads/main/data/metadata/QUADRIGA_FS-Text-01_Data01_Corpus-Table.csv -P ../data/metadata
# set path to metadata file
metadata_path = '../data/metadata/QUADRIGA_FS-Text-01_Data01_Corpus-Table.csv'
# read metadata file to pandas dataframe and set index
corpus_metadata = pd.read_csv(metadata_path, sep=';')
corpus_metadata = corpus_metadata.set_index('DC.identifier')
Kombinieren von tokenisierten Texten und deren Metadaten für KWIC-Suche#
def get_date_metadata(txtname, corpus_metadata):
date = corpus_metadata.loc[txtname, 'DC.date']
date = str(date)
year = date[:4]
month = date[:7]
day = date
return year, month, day
for filename, annotated_text in corpus_annotations.items():
txtname = filename.replace('.csv', '')
if txtname in corpus_metadata.index:
year, month, day = get_date_metadata(txtname, corpus_metadata)
annotated_text['month'] = month
annotated_text['filename'] = filename
search_df = pd.concat(corpus_annotations.values())
search_df = search_df.reset_index()
search_df["Token"] = search_df["Token"].astype(str)
print(f'The KWIC-search will be over a corpus of {search_df.shape[0]} word occurences')
The KWIC-search will be over a corpus of 33192061 word occurences
1.3 Einlesen der Wortliste (Semantisches Feld “Grippe”)#
Show code cell content
# 🚀 Create word list directory path
wordlist_dir = Path("../data/wordlist")
if not wordlist_dir.exists():
wordlist_dir.mkdir()
Show code cell content
# 🚀 Load the wordlist file from GitHub
! wget https://raw.githubusercontent.com/dh-network/quadriga/refs/heads/main/data/wordlist/grippe.txt -P ../data/wordlist
path_to_wordlist = Path("../data/wordlist/grippe.txt")
word_list = path_to_wordlist.read_text().split("\n")
Wie sieht die Wortliste aus?
word_list
['Influenza',
'Grippe',
'Grippeepidemie',
'Grippewelle',
'Grippekranke',
'Grippepandemie',
'Lungenentzündung',
'Krankheitswelle',
'Seuchenzug',
'Krankheitsausbruch',
'Fieberanfall',
'Schüttelfrost',
'Atemnot',
'Körpererschöpfung',
'Genesungszeit',
'Ansteckungsgefahr',
'Seuchenschutz',
'Desinfektionsmittel',
'Schutzmaske',
'Krankenstation',
'Isolationsstation',
'Sanitätsdienst',
'Krankheitsverlauf',
'Todesopfer',
'Krankheitssymptom',
'Erkrankungsfall',
'Lungeninfektion',
'']
2. Extraktion und Darstellung der Wortkontexte durch KWIC#
Show code cell content
class ContextViewer:
def __init__(self, search_df):
self.full_df = search_df
print(f'Searching in a corpus of {self.full_df.shape[0]} word occurences')
def show_kwic_output(self, search_terms, n_words):
contexts_df = self.get_context_words(search_terms, n_words)
# Convert DataFrame to ColumnDataSource
source = ColumnDataSource(contexts_df)
# Create Table Columns
columns = [TableColumn(field=col, title=col) for col in contexts_df.columns]
# Create DataTable
data_table = DataTable(source=source, columns=columns)
# Display DataTable
output_notebook() # Use this to render in Jupyter Notebook
show(layout([data_table]))
def get_context_words(self, search_terms, n_words):
#search_terms = input('Insert a word to search, split by comma if more than one: ')
if len(search_terms) == 0:
search_terms = word_list
if isinstance(search_terms, str):
search_terms = search_terms.split(',')
search_terms = [x.strip() for x in search_terms]
indices = self.full_df.query(f'Lemma.isin({search_terms})').index
#print(indices)
left_contexts = []
this_words = []
right_contexts = []
months = []
for indice in indices:
left = self.full_df.iloc[indice-n_words:indice-1, ]["Token"]
leftс = left[~left.str.contains('\n')]
right = self.full_df.iloc[indice+1:indice+n_words, ]["Token"]
rightс = right[~right.str.contains('\n')]
left_contexts.append(' '.join(leftс))
right_contexts.append(' '.join(rightс))
this_words.append(self.full_df.iloc[indice, ]["Token"])
months.append(self.full_df.iloc[indice, ]["month"])
newdf = pd.DataFrame()
newdf['left_context'] = left_contexts
newdf['word'] = this_words
newdf['right_context'] = right_contexts
newdf['month'] = months
return newdf
kwic = ContextViewer(search_df)
Searching in a corpus of 33192061 word occurences
Worteingabe für die Suche und KWIC-output (für Cloud Mode und Local Mode)#
Show code cell content
text_input = input("Geben Sie die zu suchenden Wörter ein und trennen Sie sie durch Kommas, wenn es mehrere sind:")
# Convert the input to a list by splitting the input by comma
search_terms = [x.strip() for x in text_input.split(',')]
Show code cell content
kwic.show_kwic_output(search_terms, n_words=5)