[PYTHON] Traitement du langage 100 knocks-46: Extraction des informations de trame de cas de verbe

Traitement du langage 100 coups 2015 ["Chapitre 5: Analyse des dépendances"](http: //www.cl.ecei. Il s'agit de l'enregistrement de la 46e "Extraction des informations sur la casse des verbes" de tohoku.ac.jp/nlp100/#ch5). La dernière fois, seuls les mots auxiliaires étaient sortis comme cas, mais cette fois, les clauses (chaque trame) sont également sorties. Bien sûr, c'est encore plus gênant ...

Lien de référence

Lien Remarques
046.Extraction d'informations sur le cadre de la casse des verbes.ipynb Lien GitHub du programme de réponse
100 coups de traitement du langage amateur:46 Copiez et collez la source de nombreuses pièces source
Officiel de CaboCha Page CaboCha à regarder en premier

environnement

J'ai installé CRF ++ et CaboCha il y a trop longtemps et j'ai oublié comment les installer. Puisqu'il s'agit d'un package qui n'a pas du tout été mis à jour, nous n'avons pas reconstruit l'environnement. Je me souviens seulement d'avoir été frustré lorsque j'ai décidé d'utiliser CaboCha sous Windows. Je pense que je ne pourrais pas l'utiliser sur Windows 64 bits (j'ai une mémoire vague et peut-être qu'il y a un problème avec ma capacité technique).

type version Contenu
OS Ubuntu18.04.01 LTS Il fonctionne virtuellement
pyenv 1.2.16 J'utilise pyenv car j'utilise parfois plusieurs environnements Python
Python 3.8.1 python3 sur pyenv.8.J'utilise 1
Les packages sont gérés à l'aide de venv
Mecab 0.996-5 apt-Installer avec get
CRF++ 0.58 C'est trop vieux et j'ai oublié comment l'installer(Peut-êtremake install)
CaboCha 0.69 C'est trop vieux et j'ai oublié comment l'installer(Peut-êtremake install)

Chapitre 5: Analyse des dépendances

contenu de l'étude

Appliquer l'analyseur de dépendances CaboCha à "Je suis un chat" et expérimenter le fonctionnement de l'arbre de dépendances et l'analyse syntaxique.

Classe, Analyse des dépendances, CaboCha, Clause, Dépendance, Cas, Syntaxe des verbes fonctionnels, Chemin des dépendances, [Graphviz](http: / /www.graphviz.org/)

Contenu frappé

Utilisation de CaboCha pour le texte (neko.txt) du roman de Natsume Soseki "Je suis un chat" Analysez la dépendance et enregistrez le résultat dans un fichier appelé neko.txt.cabocha. Utilisez ce fichier pour implémenter un programme qui répond aux questions suivantes.

46. Extraction d'informations sur le cadre de la casse verbale

Modifiez le programme> 45 et affichez le terme (la clause elle-même liée au prédicat) au format délimité par des tabulations suivant le modèle de prédicat et de cas. En plus des 45 spécifications, répondez aux spécifications suivantes.

--Le terme doit être une chaîne de mots de la clause liée au prédicat (il n'est pas nécessaire de supprimer le verbe de fin) --S'il y a plusieurs clauses liées au prédicat, disposez-les dans le même standard et dans le même ordre que les mots auxiliaires, séparés par des espaces.

Prenons l'exemple de la phrase (8ème phrase de neko.txt.cabocha) que "j'ai vu un être humain pour la première fois ici". Cette phrase contient deux verbes, «commencer» et «voir», et la phrase liée à «commencer» est analysée comme «ici», et la phrase liée à «voir» est analysée comme «je suis» et «chose». Devrait produire la sortie suivante.

Commencez ici
Regarde ce que je vois

Supplément de tâche (à propos de "chaque cadre (grammaire des cas)")

Si vous êtes intéressé, veuillez consulter Wikipedia "Kakugaku". Vous pouvez le résoudre sans regarder. Je ne le comprends pas simplement en y jetant un œil.

Répondre

Programme de réponse [046. Extraction du cadre de la casse verbale information.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/05.%E4%BF%82%E3%82%8A%E5%8F % 97% E3% 81% 91% E8% A7% A3% E6% 9E% 90 / 046.% E5% 8B% 95% E8% A9% 9E% E3% 81% AE% E6% A0% BC% E3% 83% 95% E3% 83% AC% E3% 83% BC% E3% 83% A0% E6% 83% 85% E5% A0% B1% E3% 81% AE% E6% 8A% BD% E5% 87% BA.ipynb)

import re

#Délimiteur
separator = re.compile('\t|,')

#Dépendance
dependancy = re.compile(r'''(?:\*\s\d+\s) #Non soumis à la capture
                            (-?\d+)       #Nombres(Contact)
                          ''', re.VERBOSE)

class Morph:
    def __init__(self, line):
        
        #Diviser par tabulation et virgule
        cols = separator.split(line)
        
        self.surface = cols[0] #Type de surface(surface)
        self.base = cols[7]    #Forme basique(base)
        self.pos = cols[1]     #Partie(pos)
        self.pos1 = cols[2]    #Sous-classification des paroles des parties 1(pos1)

    def __init__(self, morphs, dst):
        self.morphs = morphs
        self.srcs = []   #Liste des numéros d'index des clauses d'origine
        self.dst  = dst  #Numéro d'index de la clause de contact
        
        self.phrase = ''
        self.verb = ''
        self.joshi = ''
        
        for morph in morphs:            
            if morph.pos != 'symbole':
                self.phrase += morph.surface #Pour les non-symboles
                self.joshi = ''  #Vide pour les non-symboles pour obtenir la dernière ligne de verbes à l'exclusion des symboles
            if morph.pos == 'verbe':
                self.verb = morph.base
            if morph.pos == 'Particule':
                self.joshi = morph.base

#Remplacez l'origine et ajoutez la liste Chunk à la liste d'instructions
def append_sentence(chunks, sentences):
    
    #Remplacer l'entrepreneur
    for i, chunk in enumerate(chunks):
        if chunk.dst != -1:
            chunks[chunk.dst].srcs.append(i)
    sentences.append(chunks)
    return sentences, []

morphs = []
chunks = []
sentences = []

with open('./neko.txt.cabocha') as f:
    
    for line in f:
        dependancies = dependancy.match(line)
        
        #S'il ne s'agit pas d'EOS ou du résultat de l'analyse des dépendances
        if not (line == 'EOS\n' or dependancies):
            morphs.append(Morph(line))
            
        #Lorsqu'il y a une analyse morphologique, le résultat de l'analyse EOS ou des dépendances
        elif len(morphs) > 0:
            chunks.append(Chunk(morphs, dst))
            morphs = []
       
        #En cas de dépendance résultat
        if dependancies:
            dst = int(dependancies.group(1))
        
        #Lorsqu'il y a un résultat de dépendance dans EOS
        if line == 'EOS\n' and len(chunks) > 0:
            sentences, chunks = append_sentence(chunks, sentences)

def output_file(out_file, sentence, chunk):
    #Créer une liste de commis
    sources = [[sentence[source].joshi, sentence[source].phrase] \
                for source in chunk.srcs if sentence[source].joshi != '']
            
    if len(sources) > 0:
        sources.sort()
        joshi = ' '.join([row[0] for row in sources])
        phrase = ' '.join([row[1] for row in sources])
        out_file.write(('{}\t{}\t{}\n'.format(chunk.verb, joshi, phrase)))

with open('./046.result_python.txt', 'w') as out_file:
    for sentence in sentences:
        for chunk in sentence:
            if chunk.verb != '' and len(chunk.srcs) > 0:
                output_file(out_file, sentence, chunk)

Répondre au commentaire

Classe de bloc

Après tout, la classe Chunk, qui est la bouée de sauvetage du chapitre 5, a été modifiée par rapport à la fois précédente. J'ai créé la variable d'instance «phrase» et mis le texte de la clause. Tout le reste est identique.

python


class Chunk:
    def __init__(self, morphs, dst):
        self.morphs = morphs
        self.srcs = []   #Liste des numéros d'index des clauses d'origine
        self.dst  = dst  #Numéro d'index de la clause de contact
        
        self.phrase = ''
        self.verb = ''
        self.joshi = ''
        
        for morph in morphs:
            if morph.pos != 'symbole':
                self.phrase += morph.surface #Pour les non-symboles
                self.joshi = ''  #Vide pour les non-symboles pour obtenir la dernière ligne de verbes à l'exclusion des symboles
            if morph.pos == 'verbe':
                self.verb = morph.base
            if morph.pos == 'Particule':
                self.joshi = morph.base

Fonction de sortie de fichier

Comme c'est devenu plutôt compliqué, j'ai découpé la partie sortie du fichier en tant que fonction. Une liste de mots et de clauses auxiliaires est créée avec la première notation d'inclusion de liste, et après le tri, elle est sortie avec la fonction join.

python


def output_file(out_file, sentence, chunk):
    #Créer une liste de commis
    sources = [[sentence[source].joshi, sentence[source].phrase] \
                for source in chunk.srcs if sentence[source].joshi != '']
            
    if len(sources) > 0:
        sources.sort()
        joshi = ' '.join([row[0] for row in sources])
        phrase = ' '.join([row[1] for row in sources])
        out_file.write(('{}\t{}\t{}\n'.format(chunk.verb, joshi, phrase)))

Résultat de sortie (résultat de l'exécution)

Lorsque le programme est exécuté, les résultats suivants sont affichés (uniquement les 10 premiers éléments).

bash:046.result_python.txt


Où naître
J'ai un indice
Où je pleurais
La seule chose que je pleurais
Commencez ici
Regarde ce que je vois
Écoutez plus tard
Attrapez-nous
Faire bouillir et attraper
Manger et bouillir

Recommended Posts

Traitement du langage 100 knocks-46: Extraction des informations de trame de cas de verbe
Traitement du langage 100 knocks-45: Extraction de modèles de cas verbaux
100 traitement de langue knock-22: Extraction du nom de la catégorie
Traitement du langage 100 knocks-48: Extraction du chemin du nez à la racine
100 traitements linguistiques frappent 03 ~ 05
100 coups de traitement linguistique (2020): 40
100 coups de traitement linguistique (2020): 32
100 coups de traitement linguistique (2020): 35
100 coups de traitement linguistique (2020): 47
100 coups de traitement linguistique (2020): 39
100 coups de traitement linguistique (2020): 26
100 coups de traitement linguistique (2020): 34
100 coups de traitement linguistique (2020): 42
100 coups de traitement linguistique (2020): 49
Le traitement de 100 langues frappe 06 ~ 09
100 coups de traitement linguistique (2020): 43
100 coups de traitement linguistique (2020): 24
100 coups de traitement linguistique (2020): 45
100 coups de traitement linguistique (2020): 10-19
100 coups de traitement linguistique (2020): 30
100 coups de traitement linguistique (2020): 00-09
100 coups de traitement linguistique (2020): 31
100 coups de traitement linguistique (2020): 48
100 coups de traitement linguistique (2020): 44
100 coups de traitement linguistique (2020): 41
100 coups de traitement linguistique (2020): 37
100 coups de traitement linguistique (2020): 25
100 coups de traitement linguistique (2020): 23
100 coups de traitement linguistique (2020): 33
100 coups de traitement linguistique (2020): 20
100 coups de traitement linguistique (2020): 27
100 coups de traitement linguistique (2020): 46
100 coups de traitement linguistique (2020): 21
100 coups de traitement linguistique (2020): 36
100 Language Processing Knock-32 (utilisant des pandas): Prototype de verbe
100 coups de traitement du langage amateur: 41
100 coups de traitement du langage amateur: 71
100 coups de traitement du langage amateur: 56
100 coups de traitement du langage amateur: 50
100 coups de traitement du langage amateur: 59
100 coups de traitement du langage amateur: 70
100 coups de traitement du langage amateur: 62
100 coups de traitement du langage amateur: 60
100 coups de langue amateur: 30
100 coups de langue amateur: 06
100 coups de traitement du langage amateur: 84
100 coups de traitement du langage amateur: 81
100 coups de langue amateur: 33
100 coups de traitement du langage amateur: 46
100 coups de traitement du langage amateur: 88
100 coups de traitement du langage amateur: 89
100 coups de traitement du langage amateur: 40
100 coups de traitement du langage amateur: 45
100 coups de traitement du langage amateur: 43
100 coups de traitement du langage amateur: 55
100 coups de traitement du langage amateur: 22
100 coups de traitement du langage amateur: 61
100 coups de traitement du langage amateur: 94
100 coups de traitement du langage amateur: 54
100 coups de langue amateur: 04
100 coups de traitement du langage amateur: 63