[PYTHON] Traitement du langage 100 knocks-47: Exploration de la syntaxe des verbes fonctionnels

Traitement du langage 100 coups 2015 ["Chapitre 5: Analyse des dépendances"](http: //www.cl.ecei. Il s'agit d'un enregistrement du 47e "Minning of Functional verb syntax" de tohoku.ac.jp/nlp100/#ch5). En plus du coup précédent, la cible d'extraction devient des conditions plus compliquées. Il faut un peu de temps pour comprendre l'énoncé du problème, et bien sûr, il faut du temps pour le résoudre.

Lien de référence

Lien Remarques
047.Exploration de la syntaxe des verbes fonctionnels.ipynb Lien GitHub du programme de réponse
100 coups de traitement du langage amateur:47 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.

47. Exploration de la syntaxe des verbes fonctionnels

Je voudrais prêter attention uniquement au cas où le verbe wo case contient un nom de connexion sa-variant. Modifiez 46 programmes pour répondre aux spécifications suivantes.

--Uniquement lorsque la phrase consistant en "nom de connexion sahen + (verbe auxiliaire)" est liée au verbe --Le prédicat est "nom de connexion sahen + est la forme de base de + verbe", et lorsqu'il y a plusieurs verbes dans une phrase, le verbe le plus à gauche est utilisé. --S'il existe plusieurs mots auxiliaires (phrases) liés au prédicat, arrangez tous les mots auxiliaires dans l'ordre du dictionnaire, séparés par des espaces. --S'il y a plusieurs clauses liées au prédicat, arrangez tous les termes séparés par des espaces (alignez-vous sur l'ordre des mots auxiliaires).

Par exemple, la sortie suivante doit être obtenue à partir de la phrase «Le maître répondra à la lettre, même si elle vient à un autre endroit».

Quand je réponds à la lettre, mon mari

Enregistrez la sortie de ce programme dans un fichier et vérifiez les éléments suivants à l'aide des commandes UNIX.

--Prédicats qui apparaissent fréquemment dans le corpus (nomenclature de connexion sahénienne + + verbe) --Prédicats et modèles de verbes qui apparaissent fréquemment dans le corpus

Supplément de tâche (à propos du "verbe fonctionnel")

Selon "Verbe fonctionnel / verbe composé", les verbes fonctionnels sont les suivants. En d'autres termes, il n'a de sens que s'il est attaché à une nomenclature comme «faire» et «manger».

Les verbes fonctionnels sont des verbes qui perdent leur sens originel et sont associés à la nomenclature des actions pour représenter le sens du verbe.

Répondre

Answer Program [047. Functional verb syntax mining.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 / 047.% E6% A9% 9F% E8% 83% BD% E5% 8B% 95% E8% A9% 9E% E6% A7% 8B% E6% 96% 87% E3% 81% AE% E3% 83% 9E% E3% 82% A4% E3% 83% 8B% E3% 83% B3% E3% 82% B0.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)

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 = ''
        self.sahen = '' #Sa étrange+À+Que ce soit ou non une cible de modèle de verbe
        
        for i, morph in enumerate(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' and self.verb == '':
                self.verb = morph.base
            
            if morphs[-1].pos == 'Particule':
                self.joshi = morphs[-1].base
                
            try:
                if morph.pos1 == 'Changer de connexion' and \
                   morphs[i+1].surface == 'À':
                    self.sahen = morph.surface + morphs[i+1].surface
            except IndexError:
                pass

#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, sahen, 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(sahen, joshi, phrase)))

with open('./047.result_python.txt', 'w') as out_file:
    for sentence in sentences:
        for chunk in sentence:
            
            if chunk.sahen != '' and \
               chunk.dst != -1 and \
               sentence[chunk.dst].verb != '':
                output_file(out_file, chunk.sahen+sentence[chunk.dst].verb, 
                            sentence, sentence[chunk.dst])
#Trier par prédicat, déduplication et trier par numéro
cut --fields=1 047.result_python.txt | sort | uniq --count \
| sort --numeric-sort --reverse > 047.result_unix1.txt

#Trier par prédicats et mots auxiliaires, supprimer les doublons et trier par nombre d'observations
cut --fields=1,2 047.result_python.txt | sort | uniq --count \
| sort --numeric-sort --reverse > 047.result_unix2.txt

Répondre au commentaire

Classe de morceaux

Comme d'habitude, modifiez la classe Chunk de la ligne de vie. Si la valeur de la sous-classification du mot partiel «pos1» est «connexion sahen» et que l'entrée suivante est «o», alors la variable d'instance «sahen» est saisie avec une chaîne de caractères concaténée (exemple: réponse +).

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 = ''
        self.sahen = '' #Sa étrange+À+Que ce soit ou non une cible de modèle de verbe
        
        for i, morph in enumerate(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' and self.verb == '':
                self.verb = morph.base
            
            if morphs[-1].pos == 'Particule':
                self.joshi = morphs[-1].base
                
            try:
                if morph.pos1 == 'Changer de connexion' and \
                   morphs[i+1].surface == 'À':
                    self.sahen = morph.surface + morphs[i+1].surface
            except IndexError:
                pass

Section de sortie

La branche conditionnelle de la section de sortie est modifiée.

python


with open('./047.result_python.txt', 'w') as out_file:
    for sentence in sentences:
        for chunk in sentence:
            
            if chunk.sahen != '' and \
               chunk.dst != -1 and \
               sentence[chunk.dst].verb != '':
                output_file(out_file, chunk.sahen+sentence[chunk.dst].verb, 
                            sentence, sentence[chunk.dst])

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

Résultat d'exécution Python

Lorsque vous exécutez le script Python, le résultat suivant est généré.

text:047.result_python.txt(Seulement les 10 premiers)


Décidez de prendre une décision
Donner une réponse, donner une réponse
Fais une sieste Fais une sieste
Il fait une sieste
Poursuivre et chasser la persécution
Vivre une vie de famille
Parler parler parler
Pour écrire une lettre à Totogisu
Parfois parler pour parler
Faire un croquis

Résultat de l'exécution de la commande UNIX

Exécutez une commande UNIX et affichez "Prédicats qui apparaissent fréquemment dans le corpus (nom de connexion Sahen + + verbe)"

text:047.result_unix1.txt(Seulement les 10 premiers)


29 réponse
21 Dites bonjour
16 parler
15 imiter
13 querelle
9 Exercice
9 Poser une question
6 Soyez prudent
6 Faites une sieste
6 Poser des questions

Exécuter des commandes UNIX et générer des "prédicats et modèles complémentaires qui apparaissent fréquemment dans le corpus"

text:047.result_unix2.txt(Seulement les 10 premiers)


14 Lorsque vous répondez
9 Exercice
9 Faites l'imitation
8 Qu'est-ce qu'une réponse?
7 Se battre
6 Pour parler
6 Quand tu dis bonjour
5 pour parler
5 Pour dire bonjour
4 Poser une question

Recommended Posts

Traitement du langage 100 knocks-47: Exploration de la syntaxe des verbes fonctionnels
100 traitement du langage knock-31 (en utilisant des pandas): verbe
100 coups de traitement linguistique (2020): 28
100 coups de traitement linguistique (2020): 38
100 traitement de la langue frapper 00 ~ 02
100 traitements linguistiques Knock 2020 [00 ~ 39 réponse]
100 langues de traitement knock 2020 [00-79 réponse]
100 traitements linguistiques Knock 2020 [00 ~ 69 réponse]
100 Language Processing Knock 2020 Chapitre 1
100 coups de traitement du langage amateur: 17
100 traitements linguistiques Knock 2020 [00 ~ 49 réponse]
100 Traitement du langage Knock-52: Stemming
100 Traitement du langage Knock Chapitre 1
100 coups de langue amateur: 07
100 Language Processing Knock 2020 Chapitre 3
100 Language Processing Knock 2020 Chapitre 2
100 coups de traitement du langage amateur: 09
100 coups en traitement du langage amateur: 47
Traitement 100 langues knock-53: Tokenisation
100 coups de traitement du langage amateur: 97
100 traitements linguistiques Knock 2020 [00 ~ 59 réponse]
100 coups de traitement du langage amateur: 67
100 Language Processing Knock-32 (utilisant des pandas): Prototype de verbe
Traitement du langage 100 knocks-45: Extraction de modèles de cas verbaux
100 coups de traitement du langage avec Python 2015
100 traitement du langage Knock-51: découpage de mots
100 Language Processing Knock-58: Extraction de Taple
100 Language Processing Knock-57: Analyse des dépendances
100 traitement linguistique knock-50: coupure de phrase
100 Language Processing Knock Chapitre 1 (Python)
100 Language Processing Knock Chapitre 2 (Python)
100 Language Processing Knock-25: Extraction de modèles
Traitement du langage 100 Knock-87: similitude des mots
J'ai essayé 100 traitements linguistiques Knock 2020
100 Language Processing Knock-56: analyse de co-référence
Résolution de 100 traitements linguistiques Knock 2020 (01. "Patatokukashi")
100 coups de traitement du langage amateur: Résumé
100 Language Processing Knock 2020 Chapitre 2: Commandes UNIX
100 Language Processing Knock 2015 Chapitre 5 Analyse des dépendances (40-49)
100 traitements de langage avec Python
100 Language Processing Knock Chapitre 1 en Python
100 Language Processing Knock 2020 Chapitre 4: Analyse morphologique
100 Language Processing Knock 2020 Chapitre 9: RNN, CNN
100 traitement du langage knock-76 (en utilisant scicit-learn): étiquetage
100 Language Processing Knock-55: extraction d'expressions uniques
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 3
100 Language Processing Knock-82 (mot de contexte): Extraction de contexte
100 traitements de langage avec Python (chapitre 3)
100 Language Processing Knock: Chapitre 1 Mouvement préparatoire
100 Language Processing Knock 2020 Chapitre 6: Apprentissage automatique
100 Traitement du langage Knock Chapitre 4: Analyse morphologique
Traitement du langage 100 knock-86: affichage vectoriel Word
100 Language Processing Knock 2020 Chapitre 10: Traduction automatique (90-98)
100 Language Processing Knock 2020 Chapitre 5: Analyse des dépendances
100 Language Processing Knock-28: Suppression du balisage MediaWiki
100 Traitement du langage Knock 2020 Chapitre 7: Vecteur de mots
100 Language Processing Knock 2020 Chapitre 8: Neural Net
100 traitement du langage knock-59: analyse de la formule S
Le débutant en Python a essayé 100 traitements de langage Knock 2015 (05 ~ 09)
100 langues de traitement frappent 2020 "pour Google Colaboratory"
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 1