[PYTHON] 100 Traitement du langage Knock Chapitre 4: Analyse morphologique

Chapitre 4: Analyse morphologique

Utilisez MeCab pour analyser morphologiquement le texte (neko.txt) du roman de Natsume Soseki "Je suis un chat" et enregistrez le résultat dans un fichier appelé neko.txt.mecab. Utilisez ce fichier pour implémenter un programme qui répond aux questions suivantes.

Pour les problèmes 37, 38, 39, utilisez matplotlib ou Gnuplot.

Description d'article

――Cet article est un article qui contient les résultats de la résolution de Language Processing 100 Knock 2020 par un étudiant amateur en traitement du langage et en python. .. Je suis très heureux de signaler toute erreur ou amélioration, alors merci. ―― ~~ Je suis l'inspection de pycharm pour étudier python, donc il peut y avoir beaucoup de code inutile. ~~

** Environnement ** --MacBook Pro (13 pouces, 2016, Thunderbolt 3 ports x 2)

Préparation préalable

Utilisez MeCab pour analyser morphologiquement le texte (neko.txt) du roman de Natsume Soseki "Je suis un chat" et enregistrez le résultat dans un fichier appelé neko.txt.mecab.

Alors, exécutez le programme suivant pour le créer.

** Programme créé (clic) **

pre_processing.py


# -*- coding: utf-8 -*-

import MeCab
from MeCab import Tagger

analyser: Tagger = MeCab.Tagger("-d /usr/local/lib/mecab/dic/mecab-ipadic-neologd")

with open('./neko.txt', "r") as infile:
    lines = infile.readlines()

with open('./neko.txt.mecab.txt', "w") as outfile:
    for line in lines:
        mors = analyser.parse(line)
        outfile.write(mors)

note

--Le format de sortie est (selon mecab) «Surface \ t Partie du mot, sous-classification d'une partie du mot 1, sous-classification d'une partie du mot 2, sous-classification d'une partie du mot 3, type d'utilisation, forme d'utilisation, prototype, lecture, prononciation» Il devrait y avoir 10 éléments, mais parfois il y avait une ligne avec 8 éléments comme indiqué ci-dessous. (Il n'y a pas 9 éléments) ['Muscle du cou', 'Nom', 'Général', '*', '*', '*', '*', '* \ n'] ['Girigo', 'Nomenclature', 'Général', '*', '*', '*', '*', '* \ n'] ['Mushi', 'Nomenclature', 'Général', '*', '*', '*', '*', '* \ n'] Je me demande s'il sera omis.

30. Lecture des résultats de l'analyse morphologique

Implémentez un programme qui lit les résultats de l'analyse morphologique (neko.txt.mecab). Cependant, chaque élément morphologique est stocké dans un type de mappage avec la clé de forme de surface (surface), de forme de base (base), une partie du mot (pos) et une partie du mot sous-classification 1 (pos1), et une phrase est exprimée sous la forme d'une liste d'éléments morphologiques (type de mappage). Faisons le. Pour le reste des problèmes du chapitre 4, utilisez le programme créé ici.

** Programme créé (clic) **

k30input.py


#! /usr/bin/env python3
# -*- coding: utf-8 -*-

import re
import sys

def input_macab(filename):
    with open(filename, "r") as infile:
        sentences = []
        sentence =[]
        for line in infile.readlines():
            #Paroles de couche de surface \ t part,Sous-classification des paroles des parties 1,Sous-classification des pièces détachées 2,Sous-classification des paroles des parties 3,Type d'utilisation,Type d'utilisation,Prototype,en train de lire,prononciation
            if line == 'EOS\n':
                if len(sentence) > 0:
                    sentences.append(sentence)
                    sentence =[]
                continue

            sline = re.split('[,\t]', line)

            if len(sline) < 8:
                print("###Erreur de lecture:\n", sline + "\n")
                sys.exit(1)

            sentence.append({'surface': sline[0], 'base': sline[7], 'pos': sline[1], 'pos1': sline[2] })

    print("**Chargement terminé**\n")
    return sentences

if __name__ == '__main__':
    filename = "neko.txt.mecab.txt"
    ss = input_macab(filename)
    print("")
    print("Il était géré comme principal.")

note

31. verbe

Extrayez toutes les formes de surface du verbe.

** Programme créé (clic) **

k31verb_surface.py


# -*- coding: utf-8 -*-
import k30input

sentences = k30input.input_macab("neko.txt.mecab.txt")

for sentence in sentences:
    for mor in sentence:
        if mor['pos']=="verbe":
            print(mor['surface'])

32. Prototype du verbe

Extrayez toutes les formes originales du verbe.

** Programme créé (clic) **

k32verb_base.py


# -*- coding: utf-8 -*-
import k30input

sentences = k30input.input_macab("neko.txt.mecab.txt")

for sentence in sentences:
    for mor in sentence:
        if mor['pos']=="verbe":
            print(mor['base'])

33. «B de A»

Extraire la nomenclature dans laquelle deux nomenclatures sont reliées par "non".

** Programme créé (clic) **

k33noun_no_noun.py


# -*- coding: utf-8 -*-
import k30input

sentences = k30input.input_macab("neko.txt.mecab.txt")

noun_flag = 0
no_flag = 0
noun1: str

for sentence in sentences:
    for mor in sentence:
        if noun_flag == 0 :
            if mor['pos']=="nom":
                noun_flag = 1
                noun1 = mor['surface']
        elif noun_flag == 1 and no_flag == 0:
            if mor['surface']=="de":
                no_flag = 1
            else:
                noun1 = ""
                noun_flag = no_flag = 0
        elif noun_flag == 1 and no_flag == 1:
            if mor['pos']=="nom":
                print(noun1+"de"+mor['surface'])
                noun_flag = no_flag = 0

34. Concaténation de nomenclature

Extrayez la concaténation de la nomenclature (noms qui apparaissent consécutivement) avec la correspondance la plus longue.

** Programme créé (clic) **

k34nounoun_longest.py


# -*- coding: utf-8 -*-
import k30input

sentences = k30input.input_macab("neko.txt.mecab.txt")

nouns = []

for sentence in sentences:
    for mor in sentence:
        if mor['pos']=="nom":
            nouns.append(mor['surface'])
        else:
            if len(nouns) > 1:
                for i in nouns:
                    print(i+" ", end="")
                print("")
            nouns = []

note

35. Fréquence d'occurrence des mots

Trouvez les mots qui apparaissent dans la phrase et leur fréquence d'apparition, et classez-les par ordre décroissant de fréquence d'apparition.

** Programme créé (clic) **

k35word_freq.py


# -*- coding: utf-8 -*-
import k30input

sentences = k30input.input_macab("neko.txt.mecab.txt")

nouns = []

mor_freq = dict()

for sentence in sentences:
    for mor in sentence:
        #La clé est(Système de surface,Partie)Taple,La valeur est le nombre d'occurrences.
        mor_freq.setdefault((mor['surface'], mor['pos']), 0)
        mor_freq[(mor['surface'], mor['pos'])] = mor_freq[(mor['surface'], mor['pos'])] + 1

ranking = sorted(mor_freq.items(), key=lambda i: i[1], reverse=True)

for i in ranking:
    print(i)

note

36. Top 10 des mots les plus fréquents

Affichez les 10 mots avec une fréquence d'apparition élevée et leur fréquence d'apparition dans un graphique (par exemple, un graphique à barres).

** Programme créé (clic) **

k36word10_graph.py


# -*- coding: utf-8 -*-
from matplotlib import pyplot
import k30input

sentences = k30input.input_macab("neko.txt.mecab.txt")

nouns = []

mor_freq = dict()

for sentence in sentences:
    for mor in sentence:
        #La clé est(Système de surface,Partie)Taple,La valeur est le nombre d'occurrences.
        mor_freq.setdefault((mor['surface'], mor['pos']), 0)
        mor_freq[(mor['surface'], mor['pos'])] = mor_freq[(mor['surface'], mor['pos'])] + 1

ranking = sorted(mor_freq.items(), key=lambda i: i[1], reverse=True)

top10 = ranking[0:10]

x = []
y = []
for i in top10:
    x.append(i[0][0])
    y.append(i[1])

pyplot.bar(x, y)

#Titre du graphique
pyplot.title('Top 10 des mots les plus fréquents')

#Axe graphique
pyplot.xlabel('morphème')
pyplot.ylabel('la fréquence')

pyplot.show()

note

37. Top 10 des mots qui coïncident fréquemment avec "chat"

Affichez 10 mots qui coïncident souvent avec "chat" (fréquence élevée de cooccurrence) et leur fréquence d'apparition dans un graphique (par exemple, un graphique à barres).

** Programme créé (clic) **

k37co_cat.py


# -*- coding: utf-8 -*-
from matplotlib import pyplot
import k30input

sentences = k30input.input_macab("neko.txt.mecab.txt") # neko.txt.mecab.clean.txt

nouns = []

tmp_count = dict()
co_cat_count = dict()
cat_flag = 0

for sentence in sentences:
    for mor in sentence:
        #La clé est(Système de surface,Partie)Taple,La valeur est le nombre d'occurrences.
        tmp_count.setdefault((mor['surface'], mor['pos']), 0)
        tmp_count[(mor['surface'], mor['pos'])] = tmp_count[(mor['surface'], mor['pos'])] + 1
        if mor['surface'] == "Chat":
            cat_flag = 1

    if cat_flag == 1:
        for k, v in tmp_count.items():
            co_cat_count.setdefault(k, 0)
            co_cat_count[k] = co_cat_count[k] + v
        cat_flag = 0
    tmp_count = {}

ranking = sorted(co_cat_count.items(), key=lambda i: i[1], reverse=True)

top10 = ranking[0:10]

x = []
y = []
for i in top10:
    x.append(i[0][0])
    y.append(i[1])

pyplot.bar(x, y)

#Titre du graphique
pyplot.title('Top 10 des mots qui coïncident fréquemment avec "chat"')

#Axe graphique
pyplot.xlabel('morphème')
pyplot.ylabel('la fréquence')

pyplot.show()

note

La cooccurrence signifie que lorsqu'un mot apparaît dans une phrase (ou phrase), un autre mot limité apparaît fréquemment dans la phrase (phrase). ^ 1

――Cette fois, ce sont les 10 premiers mots (morphologie) qui apparaissent souvent dans les phrases qui incluent "chat". ―― "Chat" lui-même devrait être exclu, mais je l'ai laissé car il est intéressant comme l'un des critères et il peut être facilement effacé si vous voulez l'effacer.

résultat

1 2 3 4 5 6 7 8 9 10
de Est Chat À À main Quand Mais

Les points de phrase, les mots auxiliaires et les verbes auxiliaires sont également comptés comme des mots, donc ce n'est pas intéressant car le résultat ne ressemble pas à un résultat car c'est un "chat". En d'autres termes, ce n'est pas intéressant car n'importe quel mot coexistera avec ces mots.

Résultat 2

Donc, le résultat de la préparation d'un fichier neko.txt.mecab.clean.txt qui exclut les informations morphologiques des signes de ponctuation, des mots auxiliaires et des verbes auxiliaires de neko.txt.mecab

1 2 3 4 5 6 7 8 9 10
Chat Shi Chose je de Est y a-t-il Faire Humain こde

ThoughBien que ce soit un peu mieux, je ne pense pas que les caractéristiques des «chats» aient encore été capturées. «Je me demande si une phrase dit" oui, il y a, fais ".

38. histogramme

Dessinez un histogramme de la fréquence d'apparition des mots. Cependant, l'axe horizontal représente la fréquence d'occurrence, et est une échelle linéaire de 1 à la valeur maximale de la fréquence d'occurrence des mots. L'axe vertical est le nombre de mots différents (nombre de types) qui sont devenus la fréquence d'occurrence indiquée par l'axe des x.

** Programme créé (clic) **

k38histogram.py


# -*- coding: utf-8 -*-
from matplotlib import pyplot
import k30input

sentences = k30input.input_macab("neko.txt.mecab.txt") # neko.txt.mecab.clean.txt

nouns = []

tmp_count = dict()
co_cat_count = dict()
cat_flag = 0

for sentence in sentences:
    for mor in sentence:
        #La clé est(Système de surface,Partie)Taple,La valeur est le nombre d'occurrences.
        tmp_count.setdefault((mor['surface'], mor['pos']), 0)
        tmp_count[(mor['surface'], mor['pos'])] = tmp_count[(mor['surface'], mor['pos'])] + 1
        if mor['surface'] == "Chat":
            cat_flag = 1

    if cat_flag == 1:
        for k, v in tmp_count.items():
            co_cat_count.setdefault(k, 0)
            co_cat_count[k] = co_cat_count[k] + v
        cat_flag = 0
    tmp_count = {}

ranking = sorted(co_cat_count.items(), key=lambda i: i[1], reverse=True)

x = []
for i in ranking:
    x.append(i[1])

pyplot.hist(x, range=(0,ranking[0][1]))

#Titre du graphique
pyplot.title('Fréquence d'occurrence des mots')

#Axe graphique
pyplot.xlabel('Fréquence d'apparition')
pyplot.ylabel('Nombre de types')

pyplot.show()

note

résultat

Figure_1.png

Un histogramme logarithmique ressemble à ceci

Figure_1.png

39. Loi de Zipf

Tracez les deux graphiques logarithmiques avec la fréquence d'occurrence des mots sur l'axe horizontal et la fréquence d'occurrence sur l'axe vertical.

** Programme créé (clic) **

k39loglog_graph.py


# -*- coding: utf-8 -*-
from matplotlib import pyplot
import k30input
import numpy as np

sentences = k30input.input_macab("neko.txt.mecab.txt") # neko.txt.mecab.clean.txt

nouns = []

tmp_count = dict()
co_cat_count = dict()
cat_flag = 0

for sentence in sentences:
    for mor in sentence:
        #La clé est(Système de surface,Partie)Taple,La valeur est le nombre d'occurrences.
        tmp_count.setdefault((mor['surface'], mor['pos']), 0)
        tmp_count[(mor['surface'], mor['pos'])] = tmp_count[(mor['surface'], mor['pos'])] + 1
        if mor['surface'] == "Chat":
            cat_flag = 1

    if cat_flag == 1:
        for k, v in tmp_count.items():
            co_cat_count.setdefault(k, 0)
            co_cat_count[k] = co_cat_count[k] + v
        cat_flag = 0
    tmp_count = {}

ranking = sorted(co_cat_count.items(), key=lambda i: i[1], reverse=True)

y = []
for i in ranking:
    y.append(i[1])
x = range(len(ranking))

print("size", len(ranking))

pyplot.title('Fréquence d'occurrence des mots')
pyplot.xlabel('Journal de classement de fréquence d'occurrence(y)')
pyplot.ylabel('Journal du nombre de types(x)')

# scatter(Nuage de points)Je ne savais pas comment en faire une mémoire logarithmique, alors j'ai juste kanned ici. C'est pourquoi j'utilise numpy.
pyplot.scatter(np.log(x),np.log(y))
pyplot.show()

résultat

Figure_1.png

note

C'est une règle empirique que le rapport de l'élément avec la kème fréquence d'apparition la plus élevée à l'ensemble est proportionnel à 1 / k. [^ 3]

«Il semble que cette loi ne soit pas seulement une règle empirique du langage naturel, mais qu'elle s'applique à divers phénomènes.

ウィキペディア(30ヶ国語版)における単語の出現頻度

Impressions

Il est toujours dans la catégorie de l'étude de python. Cependant, étudier les modules numpy, pandas et collections était un problème et je n'avais pas à les utiliser. Mais n'est-il pas plus difficile de ne pas l'utiliser? De plus, je voulais rendre le même processus fonctionnel et cool. Continuez à la prochaine fois. (Je vais certainement le faire)

[^ 2]: --Wixtionary version japonaise [^ 3]: [La loi de Zip-Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%83%E3%83%97%E3%81%AE% E6% B3% 95% E5% 89% 87)

Recommended Posts

100 Language Processing Knock 2020 Chapitre 4: Analyse morphologique
100 Traitement du langage Knock Chapitre 4: Analyse morphologique
100 Language Processing Knock 2015 Chapitre 4 Analyse morphologique (30-39)
100 Language Processing Knock 2015 Chapitre 5 Analyse des dépendances (40-49)
100 coups de traitement du langage 2020: Chapitre 4 (analyse morphologique)
100 Language Processing Knock 2020 Chapitre 5: Analyse des dépendances
[Traitement du langage 100 coups 2020] Chapitre 4: Analyse morphologique
100 Language Processing Knock 2020 Chapitre 1
100 Traitement du langage Knock Chapitre 1
100 Language Processing Knock 2020 Chapitre 3
100 Language Processing Knock 2020 Chapitre 2
Traitement du langage 100 coups Chapitre 4: Analyse morphologique 31. Verbes
100 Language Processing Knock-57: Analyse des dépendances
100 Language Processing Knock Chapitre 1 (Python)
100 Language Processing Knock Chapitre 2 (Python)
Traitement du langage naturel 1 Analyse morphologique
100 Language Processing Knock-56: analyse de co-référence
100 traitements du langage frappent l'analyse morphologique apprise au chapitre 4
100 traitements du langage naturel frappent Chapitre 4 Analyse morphologique (première moitié)
100 Language Processing Knock 2020 Chapitre 2: Commandes UNIX
100 traitements de langage avec Python
100 traitements du langage naturel frappent Chapitre 4 Analyse morphologique (seconde moitié)
100 Language Processing Knock Chapitre 1 en Python
100 Language Processing Knock 2020 Chapitre 9: RNN, CNN
[Traitement du langage 100 coups 2020] Chapitre 5: Analyse des dépendances
100 coups de traitement linguistique (2020): 28
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 3
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 Language Processing Knock 2020 Chapitre 10: Traduction automatique (90-98)
100 Language Processing Knock-30 (en utilisant des pandas): lecture des résultats de l'analyse morphologique
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
100 coups de traitement linguistique (2020): 38
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 1
100 traitement de la langue frapper 00 ~ 02
100 Language Processing Knock 2020 Chapitre 1: Mouvement préparatoire
100 Language Processing Knock Chapitre 1 par Python
100 Language Processing Knock 2020 Chapitre 3: Expressions régulières
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 2
J'ai essayé 100 traitements linguistiques Knock 2020: Chapitre 4
J'ai fait 100 traitements linguistiques Knock 2020 avec GiNZA v3.1 Chapitre 4
100 traitements de langage avec Python (chapitre 2, partie 2)
100 traitements de langage avec Python (chapitre 2, partie 1)
[Programmeur nouveau venu "100 language processing knock 2020"] Résoudre le chapitre 1
100 traitements linguistiques Knock 2020 [00 ~ 39 réponse]
100 langues de traitement knock 2020 [00-79 réponse]
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 coups de traitement du langage ~ Chapitre 1
100 coups de langue amateur: 07
Le traitement de 100 langues frappe le chapitre 2 (10 ~ 19)
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