[PYTHON] 100 Language Processing Knock-30 (en utilisant des pandas): lecture des résultats de l'analyse morphologique

Traitement du langage 100 coups 2015 ["Chapitre 4: Analyse morphologique"](http: //www.cl.ecei.tohoku) Il s'agit d'un enregistrement de 30e "Lecture du résultat de l'analyse morphologique" de .ac.jp / nlp100 / # ch4). "Analyse morphologique" En entrant dans le chapitre, il est devenu plus comme un traitement linguistique à grande échelle. L'analyse morphologique est une méthode qui divise une phrase telle que «attente» en «attente», «shi», «te», «ori» et «masu», et ajoute des informations telles que des paroles de partie à chacune. Pour plus d'informations "Wikipedia" Etc.

Lien de référence

Lien Remarques
030.Lecture des résultats de l'analyse morphologique.ipynb Lien GitHub du programme de réponse
100 coups de traitement du langage amateur:30 Copiez et collez la source de nombreuses pièces source
Officiel MeCab Page MeCab à regarder en premier

environnement

J'utilise Python 3.8.1 à partir de ce moment (3.6.9 jusqu'à la dernière fois). Dans le chapitre 3, "Expressions régulières", collections.OrderdDict était utilisé pour prendre en charge les types de dictionnaire ordonnés, mais [depuis Python 3.7.1, même les types de dictionnaire standard sont garantis d'être ordonnés](https: //docs.python .org / ja / 3 / whatsnew / 3.7.html). Il n'y avait aucune raison particulière de s'en tenir à la version 3.6.9, j'ai donc renouvelé l'environnement. J'ai oublié comment installer MeCab. Je l'ai installé il y a un an, mais je ne me souviens pas avoir trébuché.

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

Dans l'environnement ci-dessus, j'utilise les packages Python supplémentaires suivants. Installez simplement avec pip ordinaire.

type version
pandas 1.0.1

Chapitre 4: Analyse morphologique

contenu de l'étude

Appliquer l'analyseur morphologique MeCab au roman «Je suis un chat» de Natsume Soseki et obtenir les statistiques des mots du roman.

Analyse morphologique, MeCab, paroles de partie, fréquence d'occurrence, loi de Zipf, matplotlib, Gnuplot

Contenu frappé

Utilisation de MeCab pour le texte (neko.txt) du roman de Natsume Soseki "Je suis un chat" Effectuez une analyse morphologique 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 et 39, utilisez matplotlib ou Gnuplot.

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 la forme de surface (surface), de la forme de base (base), d'une partie du mot (pos) et d'une partie du mot sous-classification 1 (pos1), et une phrase est exprimée sous 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.

Supplément de problème (à propos de "MeCab")

C'est "MeCab" qui est un standard d'analyse morphologique. Pour comparaison avec d'autres analyseurs morphologiques, je me suis référé à l'article "Comparaison des analyseurs morphologiques fin 2019" (résultat de la comparaison "MeCab" Je pensais que je le ferais). Si vous utilisez MeCab, les informations seront jugées dans le format suivant pour les mots divisés. Notez que le délimiteur est une tabulation (\ t) et une virgule (pourquoi?).

Forme de surface \ t Paroles de partie, Sous-classification partielle 1, Sous-classification partielle 2, Sous-classification partielle 3, Type d'utilisation, Forme d'utilisation, Forme originale, Lecture, Prononciation

Par exemple, dans le cas de "dans la cuisse cuisse", le résultat de sortie est le suivant.

No Type de surface Partie Partie細分類1 Partie細分類2 Partie細分類3 Type d'utilisation Type d'utilisation Prototype en train de lire prononciation
1 Sumomo nom Général * * * * Sumomo Sumomo Sumomo
2 Aussi Particule 係Particule * * * * Aussi Mo Mo
3 Les pêches nom Général * * * * Les pêches pêche pêche
4 Aussi Particule 係Particule * * * * Aussi Mo Mo
5 Les pêches nom Général * * * * Les pêches pêche pêche
6 de Particule syndicat * * * * de Non Non
7 domicile nom Non indépendant Avocat possible * * * domicile Uchi Uchi
8 EOS

Répondre

Programme de réponse (exécution MeCab) [Chapter 4_ Morphological analysis.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/04.%E5%BD%A2%E6%85%8B%E7% B4% A0% E8% A7% A3% E6% 9E% 90 /% E7% AC% AC4% E7% AB% A0_% 20% E5% BD% A2% E6% 85% 8B% E7% B4% A0% E8 % A7% A3% E6% 9E% 90.ipynb)

La partie d'exécution MeCab suivante est la condition préalable au chapitre 4.

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

C'est un processus simple qui se termine par une seule commande.

mecab neko.txt -o neko.txt.mecab

Pour le moment, j'ai créé un programme en utilisant mecab-python3 (ver0.996.3) en Python comme indiqué ci-dessous, mais le résultat est légèrement différent de celui de l'exécution de la commande. ** La phrase n'a pas été séparée par EOS (End Of Statement) ** a été fatale au coup qui a suivi. La méthode de spécification des options peut être mauvaise, mais je ne veux pas trop creuser dedans, donc je n'ai pas utilisé les résultats d'exécution du programme Python plus tard.

import MeCab
mecab = MeCab.Tagger()

with open('./neko.txt') as in_file, \
    open('./neko.txt.mecab', mode='w') as out_file:   
    out_file.write(mecab.parse(in_file.read()))

Programme de réponse (création de liste) [030. Reading morphological analysis results.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/04.%E5%BD%A2%E6%85%8B%E7 % B4% A0% E8% A7% A3% E6% 9E% 90 / 030.% E5% BD% A2% E6% 85% 8B% E7% B4% A0% E8% A7% A3% E6% 9E% 90% E7% B5% 90% E6% 9E% 9C% E3% 81% AE% E8% AA% AD% E3% 81% BF% E8% BE% BC% E3% 81% BF.ipynb)

from pprint import pprint

import pandas as pd

def read_text():
    # 0:Type de surface(surface)
    # 1:Partie(pos)
    # 2:Sous-classification des paroles des parties 1(pos1)
    # 7:Forme basique(base)
    df = pd.read_table('./neko.txt.mecab', sep='\t|,', header=None, 
                       usecols=[0, 1, 2, 7], names=['surface', 'pos', 'pos1', 'base'], 
                       skiprows=4, skipfooter=1 ,engine='python')
    #Le blanc est en fait pos1, mais il a changé.
    return df[df['pos'] != 'Vide']

df = read_text()
print(df.info())

target = []
morphemes = []

for i, row in df.iterrows():
    if row['surface'] == 'EOS' \
     and len(target) != 0:
        morphemes.append(df.loc[target].to_dict(orient='records'))
        target = []
    else:
        target.append(i)

print(len(morphemes))
pprint(morphemes[:5])

Répondre au commentaire

Lecteur de fichiers

Le fichier créé par MeCab est lu par read_table. C'est un peu ennuyeux que les délimiteurs soient tabulation (\ t) et virgule (, ). Ceci est réalisé en utilisant une expression régulière (OU avec «|») avec le paramètre «sep» et en changeant «moteur» en «python». J'ai mis skiprows et skipfooter parce qu'ils étaient ennuyeux de voir le contenu du fichier.

python


def read_text():
    # 0:Type de surface(surface)
    # 1:Partie(pos)
    # 2:Sous-classification des paroles des parties 1(pos1)
    # 7:Forme basique(base)
    df = pd.read_table('./neko.txt.mecab', sep='\t|,', header=None, 
                       usecols=[0, 1, 2, 7], names=['surface', 'pos', 'pos1', 'base'], 
                       skiprows=4, skipfooter=1 ,engine='python')    
    return df

La trame de données est l'information suivante. image.png

Problème de Read_table avec les blancs

C'est difficile à comprendre, mais si le suivant `` (espace demi-largeur) arrive au début de la ligne, la colonne se déplacera lors de la lecture avec la fonction read_table. En ignorant «» et «\ t» (tabulation), la première colonne est reconnue comme un «symbole». J'ai fait quelques essais et erreurs, tels que la définition du paramètre «skipinitialspace», mais je n'ai pas pu le résoudre. Je pense que c'est probablement un bug chez les pandas. Cette fois, je n'avais pas besoin d'être particulier à ce sujet, donc j'exclus les lignes «vides».

symbole,Vide,*,*,*,*, , , 

Informations DataFrame

Les données du fichier lu en tant que DataFrame sont sorties comme suit avec df.info ().

<class 'pandas.core.frame.DataFrame'>
Int64Index: 212143 entries, 0 to 212552
Data columns (total 4 columns):
 #   Column   Non-Null Count   Dtype 
---  ------   --------------   ----- 
 0   surface  212143 non-null  object
 1   pos      202182 non-null  object
 2   pos1     202182 non-null  object
 3   base     202182 non-null  object
dtypes: object(4)
memory usage: 8.1+ MB
None

Sortie de liste de types de dictionnaire

Stockez chaque élément morphologique dans un type de mappage avec la clé de la forme de surface (surface), de la forme de base (base), d'une partie du mot (pos) et d'une partie du mot sous-classification 1 (pos1), et exprimez une phrase sous forme de liste d'éléments morphologiques (type de mappage).

Faites une liste des types de mappage (type dictionnaire). Cependant, je ne l'ai pas utilisé dans les coups suivants ** et c'est entièrement pour la pratique de Python (dans les coups ultérieurs, l'utilisation de pandas ne nécessite pas un processus aussi fastidieux). Quand EOS (End Of Statement) est émis, c'est la fin d'une phrase, donc les éléments morphologiques jusqu'à ce point sont générés par la fonction to_dict.

python


target = []
morphemes = []

for i, row in df.iterrows():
    if row['surface'] == 'EOS' \
     and len(target) != 0:
        morphemes.append(df.loc[target].to_dict(orient='records'))
        target = []
    else:
        target.append(i)

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

Lorsque le programme est exécuté, le résultat suivant est sorti (seulement les 5 premières phrases). À propos, la raison pour laquelle «je suis un chat» sur la première ligne est une nomenclature, c'est parce que c'est une nomenclature appropriée du titre du livre. Il est vrai que la phrase du livre est décomposée, mais ce n'est pas encore fait.

Résultat de sortie


[[{'base': 'je suis un chat', 'pos': 'nom', 'pos1': '固有nom', 'surface': 'je suis un chat'},
  {'base': '。', 'pos': 'symbole', 'pos1': 'Phrase', 'surface': '。'}],
 [{'base': 'Nom', 'pos': 'nom', 'pos1': 'Général', 'surface': 'Nom'},
  {'base': 'Est', 'pos': 'Particule', 'pos1': '係Particule', 'surface': 'Est'},
  {'base': 'encore', 'pos': 'adverbe', 'pos1': 'Connexion auxiliaire', 'surface': 'encore'},
  {'base': 'Non', 'pos': 'adjectif', 'pos1': 'Indépendance', 'surface': 'Non'},
  {'base': '。', 'pos': 'symbole', 'pos1': 'Phrase', 'surface': '。'}],
 [{'base': None, 'pos': None, 'pos1': None, 'surface': 'EOS'},
  {'base': 'Où', 'pos': 'nom', 'pos1': '代nom', 'surface': 'Où'},
  {'base': 'alors', 'pos': 'Particule', 'pos1': '格Particule', 'surface': 'alors'},
  {'base': 'Née', 'pos': 'verbe', 'pos1': 'Indépendance', 'surface': 'Née'},
  {'base': 'Ta', 'pos': 'Verbe auxiliaire', 'pos1': '*', 'surface': 'Ta'},
  {'base': 'Feu', 'pos': 'nom', 'pos1': 'Général', 'surface': 'Katon'},
  {'base': 'Quand', 'pos': 'Particule', 'pos1': '格Particule', 'surface': 'Quand'},
  {'base': 'S'inscrire', 'pos': 'nom', 'pos1': 'Changer de connexion', 'surface': 'S'inscrire'},
  {'base': 'Mais', 'pos': 'Particule', 'pos1': '格Particule', 'surface': 'Mais'},
  {'base': 'Tsukuri', 'pos': 'verbe', 'pos1': 'Indépendance', 'surface': 'Tsuka'},
  {'base': 'Nu', 'pos': 'Verbe auxiliaire', 'pos1': '*', 'surface': 'Nu'},
  {'base': '。', 'pos': 'symbole', 'pos1': 'Phrase', 'surface': '。'}],
 [{'base': 'quoi', 'pos': 'nom', 'pos1': '代nom', 'surface': 'quoi'},
  {'base': 'Mais', 'pos': 'Particule', 'pos1': '副Particule', 'surface': 'Mais'},
  {'base': 'faible', 'pos': 'adjectif', 'pos1': 'Indépendance', 'surface': 'faible'},
  {'base': 'Humide', 'pos': 'adverbe', 'pos1': 'Général', 'surface': 'Humide'},
  {'base': 'fait', 'pos': 'nom', 'pos1': 'Général', 'surface': 'fait'},
  {'base': 'Endroit', 'pos': 'nom', 'pos1': 'suffixe', 'surface': 'Endroit'},
  {'base': 'alors', 'pos': 'Particule', 'pos1': '格Particule', 'surface': 'alors'},
  {'base': 'Miaou miaou', 'pos': 'adverbe', 'pos1': 'Général', 'surface': 'Miaou miaou'},
  {'base': 'cri', 'pos': 'verbe', 'pos1': 'Indépendance', 'surface': 'Pleurs'},
  {'base': 'main', 'pos': 'Particule', 'pos1': '接続Particule', 'surface': 'main'},
  {'base': 'Qu'y avait-il', 'pos': 'nom', 'pos1': 'Général', 'surface': 'Qu'y avait-il'},
  {'base': 'Seulement', 'pos': 'Particule', 'pos1': '副Particule', 'surface': 'Seulement'},
  {'base': 'Est', 'pos': 'Particule', 'pos1': '係Particule', 'surface': 'Est'},
  {'base': 'Mémoire', 'pos': 'nom', 'pos1': 'Changer de connexion', 'surface': 'Mémoire'},
  {'base': 'Faire', 'pos': 'verbe', 'pos1': 'Indépendance', 'surface': 'Shi'},
  {'base': 'main', 'pos': 'Particule', 'pos1': '接続Particule', 'surface': 'main'},
  {'base': 'Est', 'pos': 'verbe', 'pos1': 'Non indépendant', 'surface': 'Est'},
  {'base': '。', 'pos': 'symbole', 'pos1': 'Phrase', 'surface': '。'}],
 [{'base': 'je', 'pos': 'nom', 'pos1': '代nom', 'surface': 'je'},
  {'base': 'Est', 'pos': 'Particule', 'pos1': '係Particule', 'surface': 'Est'},
  {'base': 'ici', 'pos': 'nom', 'pos1': '代nom', 'surface': 'ici'},
  {'base': 'alors', 'pos': 'Particule', 'pos1': '格Particule', 'surface': 'alors'},
  {'base': 'début', 'pos': 'verbe', 'pos1': 'Indépendance', 'surface': 'début'},
  {'base': 'main', 'pos': 'Particule', 'pos1': '接続Particule', 'surface': 'main'},
  {'base': 'Humain', 'pos': 'nom', 'pos1': 'Général', 'surface': 'Humain'},
  {'base': 'Cette', 'pos': 'Particule', 'pos1': '格Particule', 'surface': 'Cette'},
  {'base': 'chose', 'pos': 'nom', 'pos1': 'Non indépendant', 'surface': 'chose'},
  {'base': 'À', 'pos': 'Particule', 'pos1': '格Particule', 'surface': 'À'},
  {'base': 'à voir', 'pos': 'verbe', 'pos1': 'Indépendance', 'surface': 'Vous voyez'},
  {'base': 'Ta', 'pos': 'Verbe auxiliaire', 'pos1': '*', 'surface': 'Ta'},
  {'base': '。', 'pos': 'symbole', 'pos1': 'Phrase', 'surface': '。'}]]

Recommended Posts

100 Language Processing Knock-30 (en utilisant des pandas): lecture des résultats de l'analyse morphologique
100 langage de traitement knock-20 (à l'aide de pandas): lecture de données JSON
100 Language Processing Knock 2020 Chapitre 4: Analyse morphologique
100 Traitement du langage Knock Chapitre 4: Analyse morphologique
100 traitement du langage knock-31 (en utilisant des pandas): verbe
100 Language Processing Knock 2015 Chapitre 4 Analyse morphologique (30-39)
100 traitement du langage knock-38 (en utilisant des pandas): histogramme
100 Language Processing Knock-33 (en utilisant des pandas): nom sahen
100 traitement du langage knock-35 (utilisant des pandas): concaténation de nomenclature
100 Language Processing Knock-39 (en utilisant des pandas): la loi de Zipf
100 traitement de langage knock-34 (utilisant des pandas): "B of A"
Traitement du langage 100 knocks-40: lecture des résultats de l'analyse des dépendances (morphologie)
100 traitement du langage knock-41: lecture du résultat de l'analyse des dépendances (phrase / dépendance)
100 Language Processing Knock-32 (utilisant des pandas): Prototype de verbe
100 traitement du langage knock-99 (à l'aide de pandas): visualisation par t-SNE
100 traitement du langage knock-95 (en utilisant des pandas): Note avec WordSimilarity-353
100 Language Processing Knock-57: Analyse des dépendances
Traitement du langage naturel 1 Analyse morphologique
100 Language Processing Knock-56: analyse de co-référence
100 traitement du langage knock-36 (en utilisant des pandas): fréquence d'occurrence des mots
100 Language Processing Knock: Chapitre 2 Principes de base des commandes UNIX (à l'aide de pandas)
100 Language Processing Knock-83 (en utilisant des pandas): Mesure de la fréquence des mots / contextes
100 Language Processing Knock 2015 Chapitre 5 Analyse des dépendances (40-49)
100 traitement du langage knock-76 (en utilisant scicit-learn): étiquetage
100 Language Processing Knock 2020 Chapitre 5: Analyse des dépendances
100 traitement du langage knock-59: analyse de la formule S
100 traitement du langage knock-73 (en utilisant scikit-learn): apprentissage
[Traitement du langage 100 coups 2020] Chapitre 4: Analyse morphologique
100 traitement du langage knock-74 (en utilisant scicit-learn): prédiction
100 Language Processing Knock-84 (en utilisant des pandas): Création d'une matrice de contexte de mots
100 traitement du langage knock-97 (en utilisant scicit-learn): clustering k-means
100 coups de traitement linguistique (2020): 28
100 Language Processing Knock-71 (en utilisant Stanford NLP): Stopword
100 coups de traitement linguistique (2020): 38
100 traitement de la langue frapper 00 ~ 02
100 traitement du langage knock-93 (en utilisant des pandas): calcul du taux de précision de la tâche d'analogie
100 traitement du langage knock-75 (en utilisant scicit-learn): poids de l'identité
100 traitements du langage frappent l'analyse morphologique apprise au chapitre 4
100 traitement du langage knock-72 (en utilisant Stanford NLP): Extraction d'identité
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 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 langage traitement knock-92 (utilisant Gensim): application aux données d'analogie
100 traitements du langage naturel frappent Chapitre 4 Analyse morphologique (seconde moitié)
100 traitement de langage knock-94 (en utilisant Gensim): calcul de similarité avec WordSimilarity-353
100 traitements linguistiques knock-37 (utilisant des pandas): Top 10 des mots les plus fréquents
[Pour les débutants] Analyse du langage à l'aide de l'outil de traitement du langage naturel "GiNZA" (de l'analyse morphologique à la vectorisation)
100 coups de traitement du langage avec Python 2015