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

introduction

Version 2020 de 100 coups de traitement du langage, qui est célèbre comme une collection de problèmes de traitement du langage naturel, a été publié. Cet article résume les résultats de la résolution du Chapitre 4: Analyse morphologique des chapitres 1 à 10 suivants. ..

Préparation préalable

Nous utilisons Google Colaboratory pour obtenir des réponses. Pour plus d'informations sur la configuration et l'utilisation de Google Colaboratory, consultez cet article. Le cahier contenant les résultats d'exécution des réponses suivantes est disponible sur github.

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.

Tout d'abord, téléchargez les données spécifiées. Si vous exécutez la commande suivante sur la cellule de Google Colaboratory, le fichier cible sera téléchargé dans le répertoire courant.

!wget https://nlp100.github.io/data/neko.txt

[Wget] commande-Télécharger le fichier en spécifiant l'URL

Ensuite, installez MeCab.

!apt install mecab libmecab-dev mecab-ipadic-utf8

Une fois l'installation terminée, une analyse morphologique sera effectuée immédiatement. En exécutant la commande suivante, le résultat de l'analyse morphologique de neko.txt sera affiché sous la forme `` `` neko.txt.mecab.

!mecab -o ./neko.txt.mecab ./neko.txt

Analyse morphologique (Wikipedia) Liste d'arguments de ligne de commande MeCab et son exemple d'exécution

Vérifiez le résultat de la sortie.

#Vérifiez le nombre de lignes
!wc -l ./neko.txt.mecab

production


216302 ./neko.txt.mecab
#Vérifiez les 10 premières lignes
!head -10 ./neko.txt.mecab

production


Un nom,nombre,*,*,*,*,un,Ichi,Ichi
EOS
EOS
symbole,Vide,*,*,*,*, , , 
Mon nom,Synonyme,Général,*,*,*,je,Wagahai,Wagahai
Est un assistant,Assistance,*,*,*,*,Est,C,sensationnel
Chat substantif,Général,*,*,*,*,Chat,chat,chat
Avec verbe auxiliaire,*,*,*,Spécial,Type continu,Est,De,De
Un verbe d'aide,*,*,*,Cinq étapes, La ligne Al,Forme basique,y a-t-il,Al,Al
.. symbole,Phrase,*,*,*,*,。,。,。

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.

filename = './neko.txt.mecab'

sentences = []
morphs = []
with open(filename, mode='r') as f:
  for line in f:  #Lire ligne par ligne
    if line != 'EOS\n':  #Autre que la fin de la phrase: stocke les informations d'analyse morphologique dans un type de dictionnaire et les ajoute à la liste morphologique
      surface, attr = line.split('\t')
      attr = attr.split(',')
      morph = {'surface': surface, 'base': attr[6], 'pos': attr[0], 'pos1': attr[1]}
      morphs.append(morph)
    else:  #Fin de phrase: Ajouter une liste d'éléments morphologiques à la liste de phrases
      sentences.append(morphs)
      morphs = []

#Vérification
for morph in sentences[2]:
  print(morph)

production


{'surface': '\u3000', 'base': '\u3000', 'pos': 'symbole', 'pos1': 'Vide'}
{'surface': 'je', 'base': 'je', 'pos': 'nom', 'pos1': '代nom'}
{'surface': 'Est', 'base': 'Est', 'pos': 'Particule', 'pos1': '係Particule'}
{'surface': 'Chat', 'base': 'Chat', 'pos': 'nom', 'pos1': 'Général'}
{'surface': 'alors', 'base': 'Est', 'pos': 'Verbe auxiliaire', 'pos1': '*'}
{'surface': 'y a-t-il', 'base': 'y a-t-il', 'pos': 'Verbe auxiliaire', 'pos1': '*'}
{'surface': '。', 'base': '。', 'pos': 'symbole', 'pos1': 'Phrase'}

Lecture et écriture de fichiers avec Python Split strings in Python Traitement en boucle par Python pour instruction Comment écrire une branche conditionnelle par instruction if en Python Dict () et wave brackets pour créer un dictionnaire en Python, notation d'inclusion de dictionnaire Ajout d'un élément à une liste (tableau) en Python

31. verbe

Extraire toutes les formes de surface du verbe.

Après cela, nous traiterons les phrases '' créées en 30. Le type set '' qui stocke le résultat ici est un type de données qui représente un ensemble et n'autorise pas la duplication. Par conséquent, même si vous ajoutez un élément sans y penser, vous pouvez obtenir un résultat qui ne se chevauche pas naturellement, ce qui est pratique dans un cas comme celui-ci.

ans = set()
for sentence in sentences:
  for morph in sentence:
    if morph['pos'] == 'verbe':
      ans.add(morph['surface'])  #Puisqu'il s'agit d'un type d'ensemble, seuls les éléments uniques sont conservés.

#Vérification
print(f'Types de formes de surface des verbes: {len(ans)}\n')
print('---échantillon---')
for i in range(10):
  print(list(ans)[i])

production


Types de formes de surface des verbes: 3893

---échantillon---
Profit
Shinobi
S'aligner
Remarquer
Spectacle
Vite
Séparé
Garder
Matsuwa
De

Python, opération de définition avec le type de jeu

32. Prototype du verbe

Extraire toutes les formes originales du verbe.

ans = set()
for sentence in sentences:
  for morph in sentence:
    if morph['pos'] == 'verbe':
      ans.add(morph['base'])

#Vérification
print(f'Types de prototypes de verbes: {len(ans)}\n')
print('---échantillon---')
for i in range(10):
  print(list(ans)[i])

production


Types de prototypes de verbes: 2300

---échantillon---
S'aligner
Attendre
Implacable
Peut frapper
Répondre
entreprendre
Plier
transpercer
Grandir
dire

33. «B de A»

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

ans = set()
for sentence in sentences:
  for i in range(1, len(sentence) - 1):
    if sentence[i - 1]['pos'] == 'nom' and sentence[i]['surface'] == 'de' and sentence[i + 1]['pos'] == 'nom':
      ans.add(sentence[i - 1]['surface'] + sentence[i]['surface'] + sentence[i + 1]['surface'])

#Vérification
print(f'"nom+de+名詞」de種類: {len(ans)}\n')
print('---échantillon---')
for i in range(10):
  print(list(ans)[i])

production


"nom+de+名詞」de種類: 4924

---échantillon---
Le corps de la maladie
Un côté de la
Je me hais
Problème de police
De la loi
Convient aux choses
Détective du monde
Peur de la protection
Deux éléments
Troupeau debout

Obtenez la taille des objets de différents types avec la fonction len de Python Concaténer et combiner des chaînes avec Python

34. Concaténation de nomenclature

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

Pour chaque phrase, les règles suivantes sont appliquées dans l'ordre à partir du premier élément de formulaire, et la concaténation de nomenclature est extraite avec la correspondance la plus longue.

  1. S'il s'agit d'un nom, concaténez-le en noms '' et comptez le nombre de concaténations ( `num '')
  2. Pour la non-nomenclature, afficher si le nombre de concaténations jusqu'à présent est de 2 ou plus, et initialiser `nouns``` et` num```
  3. Sinon, initialisez les noms '' et num ''
ans = set()
for sentence in sentences:
  nouns = ''
  num = 0
  for i in range(len(sentence)):
    if sentence[i]['pos'] == 'nom':  # 最初の形態素から順に、nomであればnounsに連結し、連結数(num)Compter
      nouns = ''.join([nouns, sentence[i]['surface']])
      num += 1
    elif num >= 2:  #Sorties autres que la nomenclature et si le nombre de concaténations jusqu'à ce point est de 2 ou plus, et initialise les noms et num.
      ans.add(nouns)
      nouns = ''
      num = 0
    else:  #Sinon, initialisez les noms et num
      nouns = ''
      num = 0

#Vérification
print(f'Types de nomenclature concaténée: {len(ans)}\n')
print('---échantillon---')
for i in range(10):
  print(list(ans)[i])

production


Types de nomenclature concaténée: 4454

---échantillon---
Kan Inoguchi
Rue aujourd'hui
Monde incontournable
Deux feuilles
Vous champagne
Approchant
Idiot
Kitsukigaki
10 ans maintenant
Autre que la stimulation

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.

from collections import defaultdict 

ans = defaultdict(int)
for sentence in sentences:
  for i in range(len(sentence)):
    if sentence[i]['pos'] != 'symbole':
      ans[sentence[i]['base']] += 1  #Mettre à jour le nombre de mots(Définir 1 s'il s'agit du premier mot)
ans = sorted(ans.items(), key=lambda x: x[1], reverse=True)

#Vérification
for i in range(5):
  print(ans[i])

production


('de', 9194)
('main', 6848)
('Est', 6420)
('À', 6243)
('À', 6071)

Comment utiliser Python defaultdict Trier la liste des dictionnaires en Python en fonction de la valeur de clé spécifique

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 histogramme).

Installez `` japanize_matplotlib '' pour afficher le japonais avec matplotlib.

!pip install japanize_matplotlib

[Super facile] Comment faire correspondre la notation japonaise matplotlib en seulement 2 étapes

Puis, comme pour 35, agrégez la fréquence d'occurrence et visualisez-la avec un graphique à barres.

import matplotlib.pyplot as plt
import japanize_matplotlib

ans = defaultdict(int)
for sentence in sentences:
  for i in range(len(sentence)):
    if sentence[i]['pos'] != 'symbole':
      ans[sentence[i]['base']] += 1  #Mettre à jour le nombre de mots(Définir 1 s'il s'agit du premier mot)
ans = sorted(ans.items(), key=lambda x: x[1], reverse=True)

keys = [a[0] for a in ans[0:10]]
values = [a[1] for a in ans[0:10]]
plt.figure(figsize=(8, 4))
plt.bar(keys, values)
plt.show()

36.png

Bases de la bibliothèque de dessins de graphes Python Matplotlib

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

Afficher 10 mots qui co-apparaissent souvent avec "chat" (haute fréquence de cooccurrence) et leur fréquence d'apparition dans un graphique (par exemple, un graphique à barres).

Je n'ai pas sélectionné la partie du mot ici car il n'y a pas d'instruction particulière, mais selon le but, je pense que la suppression des mots auxiliaires donnera un résultat plus significatif.

ans = defaultdict(int)
for sentence in sentences:
  if 'Chat' in [morph['surface'] for morph in sentence]:  # 文の形態素に「Chat」が含まれる場合のみ辞書に追加
    for i in range(len(sentence)):
      if sentence[i]['pos'] != 'symbole':
        ans[sentence[i]['base']] += 1  #Mettre à jour le nombre de mots(Définir 1 s'il s'agit du premier mot)
del ans['Chat']
ans = sorted(ans.items(), key=lambda x: x[1], reverse=True)

keys = [a[0] for a in ans[0:10]]
values = [a[1] for a in ans[0:10]]
plt.figure(figsize=(8, 4))
plt.bar(keys, values)
plt.show()

37.png

Supprimer les éléments du dictionnaire en Python

38. histogramme

Tracez un histogramme de la fréquence d'occurrence des mots (l'axe horizontal représente la fréquence d'occurrence et l'axe vertical représente le nombre de types de mots qui prennent la fréquence d'occurrence sous forme de graphique à barres).

ans = defaultdict(int)
for sentence in sentences:
  for i in range(len(sentence)):
    if sentence[i]['pos'] != 'symbole':
      ans[sentence[i]['base']] += 1  #Mettre à jour le nombre de mots(Définir 1 s'il s'agit du premier mot)
ans = ans.values()

plt.figure(figsize=(8, 4))
plt.hist(ans, bins=100)
plt.show()

38.png

Obtenir uniquement les clés et les valeurs du dictionnaire sous forme de liste en Python

39. Loi de Zipf

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

import math

ans = defaultdict(int)
for sentence in sentences:
  for i in range(len(sentence)):
    if sentence[i]['pos'] != 'symbole':
      ans[sentence[i]['base']] += 1  #Mettre à jour le nombre de mots(Définir 1 s'il s'agit du premier mot)
ans = sorted(ans.items(), key=lambda x: x[1], reverse=True)

ranks = [math.log(r + 1) for r in range(len(ans))]
values = [math.log(a[1]) for a in ans]
plt.figure(figsize=(8, 4))
plt.scatter(ranks, values)
plt.show()

39.png

[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) Calculer des fonctions exponentielles / logarithmiques avec Python

en conclusion

Traitement du langage 100 coups sont conçus pour que vous puissiez apprendre non seulement le traitement du langage naturel lui-même, mais également le traitement des données de base et l'apprentissage automatique général. Même ceux qui étudient l'apprentissage automatique dans des cours en ligne pourront pratiquer de très bons résultats, alors essayez-le.

Recommended Posts

100 coups de traitement du langage 2020: Chapitre 4 (analyse morphologique)
[Traitement du langage 100 coups 2020] Chapitre 4: Analyse morphologique
Traitement du langage 100 coups Chapitre 4: Analyse morphologique 31. Verbes
100 traitements du langage frappent l'analyse morphologique apprise au chapitre 4
100 Language Processing Knock 2020 Chapitre 4: Analyse morphologique
[Traitement du langage 100 coups 2020] Chapitre 5: Analyse des dépendances
100 Language Processing Knock 2015 Chapitre 4 Analyse morphologique (30-39)
100 traitements du langage naturel frappent Chapitre 4 Analyse morphologique (première moitié)
100 traitements du langage naturel frappent Chapitre 4 Analyse morphologique (seconde moitié)
100 coups de traitement du langage ~ Chapitre 1
Le traitement de 100 langues frappe le chapitre 2 (10 ~ 19)
Traitement du langage naturel 1 Analyse morphologique
100 traitements linguistiques frappent 03 ~ 05
100 coups de traitement linguistique (2020): 40
100 coups de traitement linguistique (2020): 32
100 Language Processing Knock 2015 Chapitre 5 Analyse des dépendances (40-49)
100 coups de traitement linguistique (2020): 35
[Traitement du langage 100 coups 2020] Chapitre 3: Expressions régulières
100 coups de traitement linguistique (2020): 47
100 coups de traitement linguistique (2020): 39
100 traitements du langage naturel frappent le chapitre 4 Commentaire
[Traitement du langage 100 coups 2020] Chapitre 6: Machine learning
100 coups de traitement linguistique (2020): 22
100 coups de traitement linguistique (2020): 26
100 coups de traitement linguistique (2020): 34
100 coups de traitement linguistique (2020): 29
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
[Traitement du langage 100 coups 2020] Chapitre 1: Mouvement préparatoire
100 coups de traitement linguistique (2020): 45
100 coups de traitement linguistique (2020): 10-19
[Traitement du langage 100 coups 2020] Chapitre 7: Vecteur Word
100 coups de traitement linguistique (2020): 30
100 Language Processing Knock 2020 Chapitre 5: Analyse des dépendances
100 coups de traitement linguistique (2020): 00-09
100 Language Processing Knock 2020: Chapitre 3 (expression régulière)
100 coups de traitement linguistique (2020): 31
[Traitement du langage 100 coups 2020] Chapitre 8: Réseau neuronal
100 coups de traitement linguistique (2020): 48
[Traitement du langage 100 coups 2020] Chapitre 2: Commandes UNIX
100 coups de traitement linguistique (2020): 41
100 coups de traitement linguistique (2020): 37
[Traitement du langage 100 coups 2020] Chapitre 9: RNN, CNN
100 coups de traitement linguistique (2020): 25
100 coups de traitement linguistique (2020): 33
100 coups de traitement linguistique (2020): 27
Le traitement du langage naturel à 100 coups
100 coups de traitement linguistique (2020): 46
100 coups de traitement linguistique (2020): 21
100 points de traitement du langage naturel Chapitre 5 Analyse des dépendances (premier semestre)
100 coups de traitement linguistique (2020): 36
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: 24
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