Inhalt
Aktueller Ordner:
/.ipynb (pretty JSON)
{
"metadata": {
"kernelspec": {
"name": "python",
"display_name": "Python (Pyodide)",
"language": "python"
},
"language_info": {
"codemirror_mode": {
"name": "python",
"version": 3
},
"file_extension": ".py",
"mimetype": "text\/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8"
}
},
"nbformat_minor": 5,
"nbformat": 4,
"cells": [
{
"cell_type": "markdown",
"source": "Das linguistische Korpus in diesem Beispiel: Die Worte des Korpus sind durch Leerzeichen getrennt. Die Worte des Korpus sind Kategorien, die bei einer qualitativen Interpretation des Transkriptes eines Verkaufsgespräches den wechselnden Interakten von Käufer und Verkäufer zugeordnet 1993, 1994 wurden. Die Tondateien, die Transkripte, die Interpretationen und die erstellten Quellcodes (Induktor Scheme, Parser Pascal, Transduktor Lisp sind an dem Ort zum download frei verfügbar, an dem sich diese Jupyter Notebook Datei befindet).",
"metadata": [],
"id": "0344631d-246f-4f4b-960e-6e422dc756cb"
},
{
"cell_type": "markdown",
"source": "Das Programm liest den Korpus aus einer Datei ein und extrahiert die Terminalsymbole, indem es alle Substrings sucht, die mit \"K\" oder \"V\" beginnen und aus mindestens einem Großbuchstaben bestehen. Die vorangestellten \"K\" oder \"V\" werden aus den Terminalsymbolen entfernt, um die Nonterminalsymbole zu erhalten. Dann werden die Regelproduktionen erstellt, indem für jedes Nonterminalsymbol alle Terminalsymbole gesammelt werden, die diesem Symbol entsprechen. Schließlich gibt das Programm die Grammatikregeln und das Startsymbol aus.",
"metadata": [],
"id": "40855371-260a-4813-a9e2-ccc2762641a7"
},
{
"cell_type": "code",
"source": "import re\n\n# Lesen des Korpus aus einer Datei\n#with open(\"VKGKORPUS.TXT\", \"r\") as f:\n# korpus = f.read()\nkorpus = \"KBG VBG KBBD VBBD KBA VBA KAE VAE KAA VAA KBBD VBBD KBA VBA KBBD VBBD KBA VBA KBBD VBBD KBA VBA KAE VAE KAA VAA KAV VAV\"\n# Extrahieren der Terminalsymbole aus dem Korpus\nterminals = re.findall(r\"[KV][A-Z]+\", korpus)\n\n# Entfernen der vorangestellten K- oder V-Zeichen aus den Terminalsymbolen\nnon_terminals = list(set([t[1:] for t in terminals]))\n\n# Erzeugen der Regelproduktionen\nproductions = []\nfor nt in non_terminals:\n rhs = [t for t in terminals if t[1:] == nt]\n productions.append((nt, rhs))\n\n# Ausgabe der Grammatikregeln\nprint(\"Regeln:\")\nfor nt, rhs in productions:\n print(nt + \" -> \" + \" | \".join(rhs))\n\n# Ausgabe der Startsymbol\nprint(\"Startsymbol: VKG\")",
"metadata": {
"trusted": true
},
"execution_count": 5,
"outputs": [
{
"name": "stdout",
"text": "Regeln:\nAV -> KAV | VAV\nBG -> KBG | VBG\nAA -> KAA | VAA | KAA | VAA\nAE -> KAE | VAE | KAE | VAE\nBA -> KBA | VBA | KBA | VBA | KBA | VBA | KBA | VBA\nBBD -> KBBD | VBBD | KBBD | VBBD | KBBD | VBBD | KBBD | VBBD\nStartsymbol: VKG\n",
"output_type": "stream"
}
],
"id": "614d8b37-eb96-4274-b931-9e842a996905"
},
{
"cell_type": "code",
"source": "",
"metadata": [],
"execution_count": null,
"outputs": [],
"id": "ba6f9fcf-15a4-4bbb-9fbb-f9f63fcceb01"
},
{
"cell_type": "markdown",
"source": "Die Nonterminalsymbole sind hier jeweils die ersten Buchstaben der Terminalsymbole ohne das vorangestellte \"K\" oder \"V\". Die Startregel ist 'VK', was bedeutet, dass der Verkäufer (V) die Konversation beginnt und der Käufer (K) antwortet. Beachten Sie, dass die Produktionsregeln in beide Richtungen funktionieren, da die Konversation zwischen Verkäufer und Käufer wechselseitig ist.",
"metadata": [],
"id": "bb35d468-1591-4795-a215-b9a72be478d1"
},
{
"cell_type": "code",
"source": "import re\nfrom collections import defaultdict\n\ncorpus = \"KBG VBG KBBD VBBD KBA VBA KAE VAE KAA VAA KBBD VBBD KBA VBA KBBD VBBD KBA VBA KBBD VBBD KBA VBA KAE VAE KAA VAA KAV VAV\"\n\n# Erstellen eines Wörterbuchs, um die Anzahl der Vorkommen von Terminalsymbolden zu zählen.\nvocab = defaultdict(int)\nfor word in corpus.split():\n vocab[word] += 1\n\n# Entfernen von Präfixen K und V von Terminalsymbolen.\nterminals = list(set([re.sub(r'^[KV]', '', w) for w in vocab.keys()]))\n\n# Erstellen der Produktionen für die Grammatik.\nproductions = []\nfor w in vocab.keys():\n if re.match(r'^K', w):\n lhs = 'K'\n elif re.match(r'^V', w):\n lhs = 'V'\n else:\n lhs = re.sub(r'^[KV]', '', w)\n rhs = w\n productions.append((lhs, [rhs]))\n\n# Erstellen der Startregel der Grammatik.\nstart = 'VK'\n\n# Ausgabe der Grammatik.\nprint(f'Start: {start}')\nfor lhs, rhs in productions:\n print(f'{lhs} -> {\" \".join(rhs)}')\n",
"metadata": {
"trusted": true
},
"execution_count": 6,
"outputs": [
{
"name": "stdout",
"text": "Start: VK\nK -> KBG\nV -> VBG\nK -> KBBD\nV -> VBBD\nK -> KBA\nV -> VBA\nK -> KAE\nV -> VAE\nK -> KAA\nV -> VAA\nK -> KAV\nV -> VAV\n",
"output_type": "stream"
}
],
"id": "12dee38e-2feb-471c-b739-0100a81c036b"
},
{
"cell_type": "markdown",
"source": "Das Programm liest das gegebene Korpus ein und extrahiert die nicht-terminalen Symbole, indem es alle Symbole entfernt, die mit \"K\" oder \"V\" beginnen. Dann iteriert es über das Korpus und zählt die Produktionsregeln, indem es für jedes Vorkommen eines nicht-terminalen Symbols den nachfolgenden Terminalsymbol zählt. Schließlich berechnet es die Wahrscheinlichkeiten der Produktionsregeln, indem es die Häufigkeit jedes rechten Seiten eines nicht-terminalen Symbols durch die Gesamtanzahl der Vorkommen des linken Symbols dividiert.\n\nDas Programm gibt dann die induzierte Grammatik aus, wobei die Wahrscheinlichkeiten der Produktionsregeln angezeigt werden.",
"metadata": [],
"id": "1e48196c-dabe-45cd-ac23-6506b2358106"
},
{
"cell_type": "code",
"source": "from collections import defaultdict\nimport random\n\n# define the grammar production rules\ngrammar = defaultdict(list)\n\n# read in the corpus\ncorpus = \"KBG VBG KBBD VBBD KBA VBA KAE VAE KAA VAA KBBD VBBD KBA VBA KBBD VBBD KBA VBA KBBD VBBD KBA VBA KAE VAE KAA VAA KAV VAV\".split()\n\n# get the non-terminal symbols\nnonterminals = set([symbol[1:] for symbol in corpus if symbol.startswith(\"K\") or symbol.startswith(\"V\")])\n\n# iterate over the corpus and count the production rules\nfor i in range(1, len(corpus)):\n curr_symbol = corpus[i]\n prev_symbol = corpus[i-1]\n if prev_symbol.startswith(\"K\") or prev_symbol.startswith(\"V\"):\n grammar[prev_symbol[1:]].append(curr_symbol)\n\n# calculate the probabilities for the production rules\nfor lhs in grammar.keys():\n productions = grammar[lhs]\n total_count = len(productions)\n probabilities = defaultdict(float)\n for rhs in productions:\n probabilities[rhs] += 1.0\n for rhs in probabilities.keys():\n probabilities[rhs] \/= total_count\n grammar[lhs] = probabilities\n\n# print the grammar\nprint(\"Grammar:\")\nfor lhs in grammar.keys():\n print(lhs + \" ->\")\n for rhs in grammar[lhs].keys():\n print(\" \" + rhs + \" : \" + str(grammar[lhs][rhs]))\n",
"metadata": {
"trusted": true
},
"execution_count": 7,
"outputs": [
{
"name": "stdout",
"text": "Grammar:\nBG ->\n VBG : 0.5\n KBBD : 0.5\nBBD ->\n VBBD : 0.5\n KBA : 0.5\nBA ->\n VBA : 0.5\n KAE : 0.25\n KBBD : 0.25\nAE ->\n VAE : 0.5\n KAA : 0.5\nAA ->\n VAA : 0.5\n KBBD : 0.25\n KAV : 0.25\nAV ->\n VAV : 1.0\n",
"output_type": "stream"
}
],
"id": "4f0db5a0-06b1-4041-b55a-60dbad21f0d0"
},
{
"cell_type": "markdown",
"source": "Hier ist ein Beispielprogramm in Python, das die gegebene probabilistische Grammatik nutzt, um das gegebene Korpus zu parsen:",
"metadata": [],
"id": "c5fff79b-99b4-4fe1-9a5a-a8706a41a362"
},
{
"cell_type": "code",
"source": "import random\n\n# Die gegebene probabilistische Grammatik\ngrammar = {\n 'BG': {'VBG': 0.5, 'KBBD': 0.5},\n 'BBD': {'VBBD': 0.5, 'KBA': 0.5},\n 'BA': {'VBA': 0.5, 'KAE': 0.25, 'KBBD': 0.25},\n 'AE': {'VAE': 0.5, 'KAA': 0.5},\n 'AA': {'VAA': 0.5, 'KAV': 0.25, 'KBBD': 0.25},\n 'AV': {'VAV': 1.0},\n}\n\n# Das zu parsende Korpus\ncorpus = ['KBG', 'VBG', 'KBBG', 'VBBD', 'KAE', 'VBA', 'KAE', 'VAA', 'KBBG', 'VBBD', 'KBA', 'VBA', 'KBBG', 'VBBD', 'KBA', 'VBA', 'KAE', 'VAE', 'KAA', 'VAA', 'KAV', 'VAV']\n\n# Initialisiere die Tabelle mit leeren Einträgen\nchart = [[{} for i in range(len(corpus) + 1)] for j in range(len(corpus) + 1)]\n\n# Fülle die Tabelle mit den Terminalsymbolen und den Wahrscheinlichkeiten\nfor i in range(len(corpus)):\n for lhs, rhs_probs in grammar.items():\n for rhs, prob in rhs_probs.items():\n if rhs == corpus[i]:\n chart[i][i+1][lhs] = {'prob': prob, 'prev': None}\n\n# Fülle die Tabelle mit den Nichtterminalsymbolen und den Wahrscheinlichkeiten\nfor span in range(2, len(corpus) + 1):\n for start in range(len(corpus) - span + 1):\n end = start + span\n for split in range(start + 1, end):\n for lhs, rhs_probs in grammar.items():\n for rhs, prob in rhs_probs.items():\n if len(rhs) == 2:\n left, right = rhs\n if left in chart[start][split] and right in chart[split][end]:\n prod_prob = prob * chart[start][split][left]['prob'] * chart[split][end][right]['prob']\n if lhs not in chart[start][end] or prod_prob > chart[start][end][lhs]['prob']:\n chart[start][end][lhs] = {'prob': prod_prob, 'prev': (split, left, right)}\n\n# Ausgabe des Parsing-Baums\ndef print_tree(start, end, symbol):\n if symbol in chart[start][end]:\n if chart[start][end][symbol]['prev'] is None:\n return [symbol]\n split, left, right = chart[start][end][symbol]['prev']\n return [symbol, print_tree(start, split, left), print_tree(split, end, right)]\n else:\n return []\n\n# Parse den Satz und gib den resultierenden Parse-Baum aus\nparse_tree = print_tree(0, len(corpus), 'BG')\nprint(parse_tree)\n",
"metadata": [],
"execution_count": null,
"outputs": [],
"id": "5fdfe647-666f-4657-b1d1-f1cc22ca3051"
},
{
"cell_type": "markdown",
"source": "Eine probabilistische Grammatik kann als Bayessches Netz interpretiert werden. In einem Bayesschen Netz werden die Abhängigkeiten zwischen den Variablen durch gerichtete Kanten modelliert, während die Wahrscheinlichkeiten der einzelnen Variablen und Kanten durch Wahrscheinlichkeitsverteilungen dargestellt werden.\n\nIn einer probabilistischen Grammatik werden die Produktionsregeln als Variablen und die Terme und Nichtterminale als Zustände modelliert. Jede Produktion hat eine bestimmte Wahrscheinlichkeit, die durch eine Wahrscheinlichkeitsverteilung dargestellt werden kann. Die Wahrscheinlichkeit, einen bestimmten Satz zu generieren, kann dann durch die Produktionsregeln und deren Wahrscheinlichkeiten berechnet werden.\n\nDie Zustände in der probabilistischen Grammatik können als Knoten im Bayesschen Netz interpretiert werden, während die Produktionsregeln als gerichtete Kanten dargestellt werden können. Die Wahrscheinlichkeiten der Produktionsregeln können dann als Kantenbedingungen modelliert werden. Durch die Berechnung der posterior Wahrscheinlichkeit kann dann eine probabilistische Vorhersage getroffen werden, welcher Satz am wahrscheinlichsten ist, gegeben die Beobachtungen.\n\n\n\n",
"metadata": [],
"id": "0b57b39d-0314-4a2a-9dd1-2db27e74406d"
},
{
"cell_type": "markdown",
"source": "Das Korpus kann als Protokoll der wechselseitigen Interaktion zweier Softwareagenten eines Multiagentensystems verstanden werden. Die Agenten dieses Multiagentensystems haben Zugriff auf das letzte generierte Terminalzeichen und die probabilistische Grammatik, die als Bayerisches Netz interpretiert werden kann. Dieses Wissen nutzen sie zur Generierung des nächsten Terminalzeichens. Ein Agent K generiert die Käufer-Terminalzeichen. Ein Agent V generiert die Verkäufer-Terminalzeichen.",
"metadata": [],
"id": "931a4b0f-f27d-4d1b-bc6f-bd575c9c7bf1"
},
{
"cell_type": "markdown",
"source": "Hier ist ein Beispielprogramm, das den Agenten K startet und das Terminalzeichen \"KBG\" setzt. Der Agent V generiert dann das nächste Terminalzeichen basierend auf der übergebenen Grammatik und dem letzten Terminalzeichen \"KBG\". Dies wird dann in einer Schleife fortgesetzt, bis eine maximale Anzahl von Terminalzeichen erreicht ist.",
"metadata": [],
"id": "b400dd09-7464-4b06-8d15-f958b21c4a4c"
},
{
"cell_type": "code",
"source": "import random\n\n# Grammatik als probabilistisches Bayessches Netz definieren\ngrammar = {\n \"BG\": {\"VBG\": 0.5, \"KBBD\": 0.5},\n \"BBD\": {\"VBBD\": 0.5, \"KBA\": 0.5},\n \"BA\": {\"VBA\": 0.5, \"KAE\": 0.25, \"KBBD\": 0.25},\n \"AE\": {\"VAE\": 0.5, \"KAA\": 0.5},\n \"AA\": {\"VAA\": 0.5, \"KBBD\": 0.25, \"KAV\": 0.25},\n \"AV\": {\"VAV\": 1.0}\n}\n\n# Funktion zur Generierung des nächsten Terminalzeichens\ndef generate_next_terminal(grammar, last_terminal):\n # Wähle die Produktion basierend auf dem letzten Terminalzeichen und der Grammatik aus\n productions = grammar[last_terminal]\n production = random.choices(list(productions.keys()), list(productions.values()))[0]\n return production\n\n# Maximale Anzahl von Terminalzeichen\nmax_length = 10\n\n# Startzeichen für Agent K\nlast_terminal = \"KBG\"\n\n# Schleife für Interaktion zwischen Agent K und Agent V\nfor i in range(max_length):\n # Agent K generiert das nächste Terminalzeichen basierend auf der Grammatik und dem letzten gesetzten Zeichen\n next_terminal = generate_next_terminal(grammar, last_terminal)\n print(\"Agent K: \", last_terminal)\n\n # Agent V generiert das nächste Terminalzeichen basierend auf der Grammatik und dem letzten gesetzten Zeichen\n last_terminal = generate_next_terminal(grammar, next_terminal)\n print(\"Agent V: \", next_terminal)\n\n# Letztes Terminalzeichen ausgeben, das von Agent K generiert wurde\nprint(\"Letztes Terminalzeichen: \", last_terminal)\n",
"metadata": [],
"execution_count": null,
"outputs": [],
"id": "507942c5-8a4b-4635-9f6d-cdefd69d15de"
},
{
"cell_type": "markdown",
"source": "Agent K: KBG\nAgent V: KBBD\nAgent K: KBBD\nAgent V: KAE\nAgent K: KAE\nAgent V: VAE\nAgent K: VAE\nAgent V: KAA\nAgent K: KAA\nAgent V: VAA\nAgent K: VAA\nLetztes Terminalzeichen: VAA\n",
"metadata": [],
"id": "df5f17d5-dbfb-4640-beec-132552d3524c"
}
]
}