Language processing 100 knock 2020 a été publié, je vais donc l'essayer immédiatement.
Dans le chapitre 4, nous analyserons la morphologie avec MeCab. Cependant, comme c'est un gros problème, je le ferai avec GiNZA (même si je ne l'ai utilisé qu'au début).
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.
code
import spacy
import pandas as pd
import pprint
from functools import reduce
import collections
import matplotlib.pyplot as plt
import seaborn as sns
with open('neko.txt') as f:
raw_text = f.read()
#Supprimez les caractères supplémentaires au début
raw_text = raw_text.replace('un\n\n ', '')
nlp = spacy.load('ja_ginza')
doc = nlp(raw_text)
with open('neko.txt.ginza', 'a') as f2:
for sent in doc.sents:
for token in sent:
#Numéro de sortie, système de surface, forme de base, paroles de partie
f2.write(','.join([str(token.i), token.orth_, token.lemma_, token.tag_]) + '\n')
GiNZA semble être capable de produire la même sortie que MeCab sur la ligne de commande, mais comme je n'ai pas pu trouver l'API de Python, je la sortie telle quelle.
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.
code
neko_df = pd.read_csv('neko.txt.ginza', header=None)
docs = []
sentence = []
for row in neko_df.itertuples():
pos, *pos1 = row[4].split('-')
neko_dict = {
'surface': row[2],
'base': row[3],
'pos': pos,
'pos1': pos1
}
sentence.append(neko_dict)
#.. Séparé par
if row[2] == '。':
docs.append(sentence)
sentence = []
pprint.pprint(docs[0])
Résultat de sortie
[{'base': 'Mon compagnon', 'pos': 'Synonyme', 'pos1': [], 'surface': 'je'},
{'base': 'Est', 'pos': 'Particule', 'pos1': ['係Particule'], 'surface': 'Est'},
{'base': 'Chat', 'pos': 'nom', 'pos1': ['普通nom', 'Général'], 'surface': 'Chat'},
{'base': 'Est', 'pos': 'Verbe auxiliaire', 'pos1': [], 'surface': 'alors'},
{'base': 'Oui', 'pos': 'verbe', 'pos1': ['Non indépendant'], 'surface': 'y a-t-il'},
{'base': '。', 'pos': 'Symbole auxiliaire', 'pos1': ['Phrase'], 'surface': '。'}]
Extrayez toutes les formes de surface du verbe.
code
surfaces = []
for sentence in docs:
for morpheme in sentence:
surfaces.append(morpheme['surface'])
print(surfaces[:30])
Résultat de sortie
['je', 'Est', 'Chat', 'alors', 'y a-t-il', '。', 'Nom', 'Est', 'encore', 'Non', '。', 'Où', 'alors', 'Née', 'Ta', 'Ou', 'Quand', 'んQuand', 'S'inscrire', 'Mais', 'つOu', 'Nu', '。', 'quoi', 'alors', 'Aussi', 'faible', 'Humide', 'Shi', 'Ta']
Extrayez toutes les formes originales du verbe.
code
bases = []
for sentence in docs:
for morpheme in sentence:
bases.append(morpheme['base'])
print(bases[:30])
Résultat de sortie
['Mon compagnon', 'Est', 'Chat', 'Est', 'Oui', '。', 'Nom', 'Est', '未Est', 'Non', '。', 'Où', 'alors', 'naître', 'Ta', 'Ou', 'Quand', 'うんQuand', 'S'inscrire', 'Mais', 'Attacher', 'Zu', '。', 'quoi', 'alors', 'Aussi', 'faible', 'Humide', 'Faire', 'Ta']
Extraire la nomenclature dans laquelle deux nomenclatures sont reliées par "non".
code
nouns = []
for sentence in docs:
for i in range(len(sentence) - 2):
if sentence[i]['pos'] == 'nom' and sentence[i + 1]['surface'] == 'de' and sentence[i + 2]['pos'] == 'nom':
nouns.append(sentence[i]['surface'] + sentence[i + 1]['surface'] + sentence[i + 2]['surface'])
print(nouns[:30])
Résultat de sortie
['Sur la paume', 'Visage de l'élève', 'Voir des choses', 'Devrait faire face', 'Au milieu du visage', 'Dans le trou', 'Palmier de calligraphie', 'L'arrière de la paume', 'Jusque là', 'Sur la paille', 'À Sasahara', 'Devant l'étang', 'Sur l'étang', 'Merci à Kazuki', 'Trou dans la clôture', 'Les trois cheveux d'à côté', 'Passage du temps', 'Grâce momentanée', 'À l'intérieur de la maison', 'Humains autres que', 'Étudiant précédent', 'Ta chance', 'Trois d'entre vous', 'Démangeaisons thoraciques', 'Gouvernante', 'Maître', 'Petit chat sans', 'Sous le nez', 'Ma maison', 'Trucs pour la maison']
Extrayez la concaténation de la nomenclature (noms qui apparaissent consécutivement) avec la correspondance la plus longue.
code
nouns2 = []
for sentence in docs:
word = ''
count = 0
for morpheme in sentence:
if morpheme['pos'] == 'nom':
word += morpheme['surface']
count += 1
else:
if count >= 2:
nouns2.append(word)
word = ''
count = 0
print(nouns2[:30])
Résultat de sortie
['Début', 'Opportun', 'Un cheveu', 'Chat arrière', 'Jusqu'à maintenant', 'Uchiike', 'Autre que étudiant', 'Mao', 'Pas d'auberge', 'Maman de retour', 'Étude d'une journée', 'Presque', 'Parfois furtif', 'Quelques pages', 'Autre que mon mari', 'Maître du matin', 'Côté Sou', 'Une pièce', 'Estomac nerveux faible', 'Parfois pareil', 'Pause linguistique', 'Ma femme', 'Le bal de l'autre jour', 'Toute l'histoire', 'Combien d'humain', 'M.', 'Sora Munemori', 'janvier', 'Date du salaire mensuel', 'Peinture aquarelle']
code
#Aplatir une liste à deux dimensions
words = reduce(list.__add__, docs)
#Extraire uniquement les mots
words = collections.Counter(map(lambda e: e['surface'], words))
#Calculez la fréquence d'apparition
words = words.most_common()
#Trier par fréquence d'apparition
words = sorted(words, key=lambda e: e[1], reverse=True)
print(words[:30])
Résultat de sortie
[('de', 9546), ('。', 7486), ('main', 7401), ('À', 7047), ('、', 6772), ('Est', 6485), ('Quand', 6150), ('À', 6118), ('Mais', 5395), ('alors', 4542), ('Ta', 3975), ('「', 3238), ('」', 3238), ('Aussi', 3229), ('Est', 2705), ('Shi', 2530), ('Absent', 2423), ('De', 2213), ('Ou', 2041), ('y a-t-il', 1729), ('Hmm', 1625), ('Nana', 1600), ('Est', 1255), ('Chose', 1214), ('Faire', 1056), ('Ausside', 1005), ('Quoi', 998), ('alorsす', 978), ('Tu', 967), ('dire', 937)]
code
words_df = pd.DataFrame(words[:10], columns=['word', 'count'])
sns.set(font='AppleMyungjo')
fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(words_df['word'], words_df['count'])
plt.show()
Résultat de sortie
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).
code
cats = []
for sentence in docs:
cat_list = list(filter(lambda e: e['surface'] == 'Chat', sentence))
if len(cat_list) > 0:
for morpheme in sentence:
if morpheme['surface'] != 'Chat':
cats.append(morpheme['surface'])
cats = collections.Counter(cats)
#Calculez la fréquence d'apparition
cats = cats.most_common()
#Trier par fréquence d'apparition
cats = sorted(cats, key=lambda e: e[1], reverse=True)
cats_df = pd.DataFrame(cats[:10], columns=['word', 'count'])
sns.set(font='AppleMyungjo')
fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(cats_df['word'], cats_df['count'])
# plt.show()
plt.savefig('37.png')
Résultat de sortie
Dessinez 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).
code
hist_df = pd.DataFrame(words, columns=['word', 'count'])
sns.set(font='AppleMyungjo')
fig = plt.figure()
ax = fig.add_subplot(111)
ax.hist(hist_df['count'], range=(1, 100))
# plt.show()
plt.savefig('38.png')
Résultat de sortie
L'axe horizontal est limité à 100. Étant donné que le nombre d'apparitions autour de 1 est extrêmement important, si vous l'affichez sans restrictions, ce sera comme suit et vous ne pourrez pas le visualiser correctement.
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.
code
zipf_df = pd.DataFrame(words, columns=['word', 'count'])
sns.set(font='AppleMyungjo')
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_yscale('log')
ax.set_xscale('log')
ax.plot(zipf_df['count'])
# plt.show()
plt.savefig('39.png')
Résultat de sortie
Vous pouvez le voir en en faisant un graphe logarithmique.
Ce que vous pouvez apprendre au chapitre 4
Recommended Posts