[PYTHON] 100 natürliche Sprachverarbeitung klopft Kapitel 5 Abhängigkeitsanalyse (erste Hälfte)

Eine Aufzeichnung zur Lösung der Probleme in der ersten Hälfte von Kapitel 5. Die Zieldatei ist neko.txt, wie auf der Webseite gezeigt.

Verwenden Sie CaboCha, um den Text (neko.txt) von Natsume Sosekis Roman "Ich bin eine Katze" abhängig zu machen und zu analysieren, und speichern Sie das Ergebnis in einer Datei namens neko.txt.cabocha. Verwenden Sie diese Datei, um ein Programm zu implementieren, das die folgenden Fragen beantwortet.

</ i> 40. Lesen des Ergebnisses der Abhängigkeitsanalyse (Morphologie)

Implementieren Sie die Klasse Morph, die die Morphologie darstellt. Diese Klasse hat eine Oberflächenform (Oberfläche), eine Basisform (Basis), ein Teilwort (pos) und eine Teilwortunterklassifikation 1 (pos1) als Elementvariablen. Lesen Sie außerdem das Analyseergebnis von CaboCha (neko.txt.cabocha), drücken Sie jeden Satz als Liste von Morph-Objekten aus und zeigen Sie die morphologische Elementzeichenfolge des dritten Satzes an.

# -*- coding: utf-8 -*-
__author__ = 'todoroki'

class Morph():
    def __init__(self, surface, base, pos, pos1):
        self.surface = surface
        self.base = base
        self.pos = pos
        self.pos1 = pos1

    def print_all(self):
        return self.surface + "\t" + self.base + ", " + self.pos + ", " + self.pos1

def read_morpheme(cabochafile):
    sentences = []
    sentence = []
    for line in cabochafile:
        if line == "EOS\n":
            # if len(sentence) > 0:
            #     sentences.append(sentence)
            sentences.append(sentence)
            sentence = []
        elif line[0] == "*":
            continue
        else:
            surface, other = line.split()
            others = other.split(",")
            base, pos, pos1 = others[6], others[0], others[1]
            morph = Morph(surface, base, pos, pos1)
            sentence.append(morph)
    return sentences

if __name__ == "__main__":
    f = open("neko.txt.cabocha", "r")
    sentences = read_morpheme(f)
    for morph in sentences[2]:
        print morph.print_all()
    f.close()

</ i> 41. Lesen des Abhängigkeitsanalyseergebnisses (Phrase / Abhängigkeit)

Implementieren Sie zusätzlich zu> 40 die Klauselklasse Chunk. Diese Klasse verfügt über eine Liste von Morph-Elementen (Morph-Objekten) (Morphs), eine Liste verwandter Klauselindexnummern (dst) und eine Liste verwandter ursprünglicher Klauselindexnummern (srcs) als Mitgliedsvariablen. Lesen Sie außerdem das Analyseergebnis von CaboCha des Eingabetextes, drücken Sie einen Satz als Liste von Chunk-Objekten aus und zeigen Sie die Zeichenfolge und den Kontakt der Phrase des achten Satzes an. Verwenden Sie für die restlichen Probleme in Kapitel 5 das hier erstellte Programm.

# -*- coding: utf-8 -*-
__author__ = 'todoroki'

import problem40


class Chunk():
    def __init__(self):
        self.morphs = []
        self.dst = -1
        self.srcs = []

    def __repr__(self):
        if self.morphs:
            surfs = [morph.surface for morph in self.morphs if morph.pos != 'Symbol']
            return "".join(surfs)

    def include_pos(self, pos):
        return pos in [morph.pos for morph in self.morphs]

    def morphs_of_pos(self, pos):
        return [morph for morph in self.morphs if morph.pos == pos]

    def morphs_of_pos1(self, pos1):
        return [morph for morph in self.morphs if morph.pos1 == pos1]


def read_chunk(cabochafile):
    sentences = []
    sentence = []
    for line in cabochafile:
        if line == "EOS\n":
            for idx, c in enumerate(sentence[:-1]):
                if c.dst != -1:
                    sentence[c.dst].srcs.append(idx)
            # if len(sentence) > 1:
                # sentences.append(sentence)
            sentences.append(sentence)
            sentence = []
        elif line[0] == "*":
            chunk = Chunk()
            chunk.dst = int(line.split()[2].strip("D"))
            sentence.append(chunk)
        else:
            surface, other = line.split()
            others = other.split(",")
            base, pos, pos1 = others[6], others[0], others[1]
            morph = problem40.Morph(surface, base, pos, pos1)
            sentence[-1].morphs.append(morph)
    return sentences


if __name__ == "__main__":
    f = open("neko.txt.cabocha", "r")
    sentences = read_chunk(f)
    for idx, chnk in enumerate(sentences[7]):
        surfaces = ""
        for mrph in chnk.morphs:
            surfaces += mrph.surface
        print "%d" % idx, surfaces, "=>", chnk.dst
    f.close()

</ i> 42. Anzeige der Klauseln der betroffenen Person und der betroffenen Person

Extrahieren Sie den gesamten Text der ursprünglichen Klausel und der zugehörigen Klausel in tabulatorgetrenntem Format. Geben Sie jedoch keine Symbole wie Satzzeichen aus.

# -*- coding: utf-8 -*-
__author__ = 'todoroki'

import problem41

def make_chunk_pair(sentence):
    pairs = []
    for chunk in sentence:
        if chunk.dst != -1:
            pairs.append((chunk, sentence[chunk.dst]))
    return pairs

if __name__ == "__main__":
    f = open("neko.txt.cabocha")
    sentences = problem41.read_chunk(f)
    pair_sentences = []
    for sentence in sentences:
        pair = make_chunk_pair(sentence)
        pair_sentences.append(pair)
    for sentence in pair_sentences:
        for pair in sentence:
            print "\t".join([str(chunk) for chunk in pair])
    f.close()

</ i> 43. Extrahieren Sie Klauseln mit Nomenklatur in Bezug auf Klauseln mit Verben

Wenn sich Klauseln mit Nomenklatur auf Klauseln mit Verben beziehen, extrahieren Sie sie in tabulatorgetrennten Formaten. Geben Sie jedoch keine Symbole wie Satzzeichen aus.

# -*- coding: utf-8 -*-
__author__ = 'todoroki'

import problem41
import problem42

def findNtoV(chunk_pair):
    flagN = False
    flagV = False
    if "Substantiv" in [morph.pos for morph in chunk_pair[0].morphs]:
        flagN = True
    if "Verb" in [morph.pos for morph in chunk_pair[1].morphs]:
        flagV = True
    return flagN and flagV

if __name__ == "__main__":
    f = open("neko.txt.cabocha", "r")
    sentences = problem41.read_chunk(f)
    pair_sentences = []
    for sentence in sentences:
        pair = problem42.make_chunk_pair(sentence)
        pair_sentences.append(pair)
    pairs_NtoV = []
    for pair_sentence in pair_sentences:
        for chunk_pair in pair_sentence:
            if findNtoV(chunk_pair):
                pairs_NtoV.append(chunk_pair)
    for pair_NtoV in pairs_NtoV:
        noun, verb = pair_NtoV
        print "%s\t%s" % (noun, verb)
    f.close()

</ i> 44. Visualisierung abhängiger Bäume

Visualisieren Sie den Abhängigkeitsbaum eines bestimmten Satzes als gerichteten Graphen. Zur Visualisierung ist es ratsam, den Abhängigkeitsbaum in die DOT-Sprache zu konvertieren und Graphviz zu verwenden. Verwenden Sie pydot, um gerichtete Diagramme direkt aus Python zu visualisieren.

# -*- coding: utf-8 -*-
__author__ = 'todoroki'

import problem41
import problem42


def sentenceToDot(idx, sentence):
    head = "digraph sentence{0} ".format(idx)
    body_head = "{ graph [rankdir = LR]; "
    body = ""
    for chunk_pair in sentence:
        former, latter = chunk_pair
        body += ('"'+str(former)+'"->"'+str(latter)+'"; ')
    dotString = head + body_head + body + '}'
    return dotString


if __name__ == "__main__":
    f = open("neko.txt.cabocha", "r")
    sentences = problem41.read_chunk(f)
    pair_sentences = []
    for sentence in sentences:
        pair = problem42.make_chunk_pair(sentence)
        pair_sentences.append(pair)
    # dotStrings = []
    for idx, sentence in enumerate(pair_sentences):
        dotString = sentenceToDot(idx, sentence)
        print dotString
        # dotStrings.append(dotString)
    f.close()

Recommended Posts