- Il existe deux méthodes de traitement du langage naturel.
- La méthode d'expression des mots à partir d'informations statistiques est appelée "** base de comptage ", et la méthode de réseau neuronal est appelée " base d'inférence **".
- En tant que méthode basée sur le décompte, considérons un programme qui génère des phrases basées sur la ** distribution de fréquence N-gramme ** de "séries" de lettres et de mots.
⑴ Lire des données textuelles
from google.colab import files
uploaded = files.upload()
- Sélectionnez un fichier texte localement et téléchargez-le sur Colaboratory.
- Ouvrez le fichier texte téléchargé et stockez-le dans une variable.
- Cette fois, j'utiliserai le texte intégral de "Je suis un chat" de Soseki Natsume comme corpus.
- https://github.com/yumi-ito/sample_data/blob/master/Neko.txt
with open('Neko.txt', mode='rt', encoding='utf-8') as f:
read_text = f.read()
nekotxt = read_text
print(nekotxt)
- Les arguments de ʻopen ()
sont
file namede gauche à droite,
mode = 'rt' est la spécification du mode texte et ʻencoding =' utf-8'
est le code du caractère. Si vous ajoutez with
à gauche, le fichier que vous avez ouvert sera fermé automatiquement après l'exécution du code dans le retrait.
⑵ Analyse morphologique par MeCab
- MeCab est un moteur d'analyse morphologique open source qui peut être utilisé de deux manières.
- La première consiste à utiliser ** pour créer une note distincte **, qui peut être traitée de la même manière que les phrases en anglais.
- L'autre est ** pour obtenir des informations telles que la lecture, la forme originale, une partie des mots pour chaque mot **, qui peuvent être utilisées pour extraire uniquement la nomenclature, par exemple.
!apt install aptitude
!aptitude install mecab libmecab-dev mecab-ipadic-utf8 git make curl xz-utils file -y
!pip install mecab-python3==0.7
- Ce qui précède est l'installation de MeCab. Ensuite, importez et convertissez le texte intégral en "écriture séparée".
- Vous pouvez obtenir le résultat sous forme de chaîne en créant une instance dans la classe
MeCab.Tagger ()
avec l'argument -Owakati
puis en appelant la méthode parse ()
.
import MeCab
tagger = MeCab.Tagger("-Owakati")
nekotxt = tagger.parse(nekotxt)
print(nekotxt)
- La chaîne de caractères est encore divisée, mais si l'argument est omis avec
split ()
, un espace sera le délimiteur.
nekotxt = nekotxt.split()
print(nekotxt)
⑶ Génération de dictionnaire N-gramme
from collections import Counter
import numpy as np
from numpy.random import *
- Maintenant, mettez la séquence de mots séparés
nekotxt
comme variable string
.
- Dans le cas de 2 mots, c'est-à-dire de 2 grammes, la liste du début à la fin de
string
et la liste du mot suivant à la fin de string
sont combinées en une seule aveczip ()
etdouble. Disons
.
- Pour 3 grammes, la liste du début à la fin de «string», la liste du mot suivant du début à celui qui précède la fin, et la liste du mot suivant du début à la fin. Combinez la liste en une seule, appelée «triple».
- À ce moment-là, utilisez la fonction
filter ()
pour supprimer tous les symboles de caractères définis dans la variable delimiiter
.
string = nekotxt
#Caractères à exclure
delimiter = ['「', '」', '…', ' ']
#Liste de 2 mots
double = list(zip(string[:-1], string[1:]))
double = filter((lambda x: not((x[0] in delimiter) or (x[1] in delimiter))), double)
#Liste de 3 mots
triple = list(zip(string[:-2], string[1:-1], string[2:]))
triple = filter((lambda x: not((x[0] in delimiter) or (x[1] in delimiter) or (x[2] in delimiter))), triple)
#Compter le nombre d'éléments et générer un dictionnaire
dic2 = Counter(double)
dic3 = Counter(triple)
double
est une liste avec deux mots consécutifs comme éléments, et triple
est une liste avec trois mots consécutifs comme éléments.
- Le résultat du comptage de la fréquence d'occurrence des éléments avec
Counter ()
est ** 2 grammes est dic2
, 3 grammes sont les données de fréquence dic3
**, c'est-à-dire ** dictionnaire N-grammes **. Je vais.
- Affiche le contenu du dictionnaire N-gramme.
for u,v in dic2.items():
print(u, v)
for u,v in dic3.items():
print(u, v)
⑷ Définition de la méthode de génération de phrases
- Définissez une méthode
nextword
** qui génère des phrases en générant les mots les uns après les autres à partir du dictionnaire N-gramme.
- En d'autres termes, ** la fréquence d'occurrence de chaque ensemble de mots consécutifs doit être lue comme la probabilité du "mot suivant" **.
- Donnez le premier mot, répétez la sélection du mot suivant, du mot suivant et des mots les plus fréquents, et arrêtez la génération lorsque vous atteignez la fin, comme ".".
def nextword(words, dic):
##➀ Obtenez le nombre d'éléments grammes des premiers mots
grams = len(words)
## ➁N-Extraire les éléments correspondants du dictionnaire gramme dic
#Pour 2 mots
if grams == 2:
matcheditems = np.array(list(filter(
(lambda x: x[0][0] == words[1]), #1ers matchs
dic.items())))
#Pour 3 mots
else:
matcheditems = np.array(list(filter(
(lambda x: x[0][0] == words[1]) and (lambda x: x[0][1] == words[2]), #1er et 2ème match
dic.items())))
##➂ Message d'erreur lorsqu'il n'y a pas de mot correspondant
if(len(matcheditems) == 0):
print("No matched generator for", words[1])
return ''
##➃ Liste de fréquence d'apparition pondérée
#Obtenir la fréquence d'occurrence des éléments correspondants
probs = [row[1] for row in matcheditems]
#Génère un nombre pseudo aléatoire de 0 à 1 et multiplie-le par la fréquence d'apparition
weightlist = rand(len(matcheditems)) * probs
##➄ Obtenez l'élément avec la fréquence d'apparition pondérée la plus élevée à partir des éléments correspondants
if grams == 2:
u = matcheditems[np.argmax(weightlist)][0][1]
else:
u = matcheditems[np.argmax(weightlist)][0][2]
return u
- ** ➀ ** Le premier argument,
words
, est ** un mot que vous pouvez saisir comme début **. Le deuxième argument «dic» (dic2 ou dic3) est sélectionné selon que le nombre d'éléments est de 2 ou 3 mots.
- ** ➁ ** Dans le cas de 2 mots, le premier mot correspond, et dans le cas de 3 mots, le premier et le mot suivant ** correspondent **, respectivement ** extraits du dictionnaire N-gramme ** Et stockez-le dans la variable
matcheditems
.
- ** ➂ ** Renvoie s'il n'y a pas de mot correspondant dans le message d'erreur.
- ** ➃ Génère une liste de «fréquence d'occurrence pondérée» ** en multipliant la fréquence d'occurrence par un nombre pseudo-aléatoire. Au fait, si vous prenez simplement l'élément avec la fréquence d'apparition la plus élevée, le résultat sera fixe et pas intéressant, vous pouvez donc le changer en donnant du bruit.
- ** ➄ ** Obtient et retourne l'élément ** avec la "fréquence d'apparition pondérée" la plus élevée de la liste des éléments correspondants "éléments correspondants".
⑸ Exécution du programme de génération de phrases
- Ici, 2 mots (2 grammes) sont adoptés, et le premier mot est entré comme "I".
- De plus, si vous utilisez l'argument optionnel «end =» «for» print () «dans la sortie documentée finale, les blancs (espaces demi-largeur) créés lors de la concaténation de chaînes de caractères seront éliminés.
#Entrez les premiers mots du mot
words = ['', 'je'] # 2-gram
#words = ['', 'je', 'Est'] # 3-gram
#Incorporer les mots au début de la sortie de sortie
output = words[1:]
#Obtenez "prochain mot"
for i in range(100):
#Pour 2 mots
if len(words) == 2:
newword = nextword(words, dic2)
#Pour 3 mots
else:
newword = nextword(words, dic3)
#Ajoutez les mots suivants à la sortie de sortie
output.append(newword)
#Fin si le caractère suivant est une fin
if newword in ['', '。', '?', '!']:
break
#Préparer le prochain mot
words = output[-len(words):]
print(words)
#Affichage de la sortie de sortie
for u in output:
print(u, end='')
- 2-Indique le processus d'extraction des éléments les uns après les autres du dictionnaire gramme.
- Ainsi, contrairement à la méthode basée sur l'inférence, N-gramme est très simple ...
- En tant qu'expérience personnelle, en 2008 (2008), je suis tombé sur un rapport de recherche très intéressant utilisant N-gram.
- En utilisant N-gram comme corpus de la collection de poèmes japonais du début de la période Heian, "Kokonwakashu", les expressions uniques des hommes et des femmes sont extraites, et sur cette base, les poèmes japonais écrits par les personnages de "Genji Monogatari" sont vérifiés. C'est une initiative.
- Il n'est pas rare que les femmes utilisent un langage masculin même dans les temps modernes, mais il s'est avéré qu'en réalité, les gens étaient habilement modelés en utilisant un langage masculin et féminin. Par exemple, un homme qui manque d'expressions propres aux hommes et qui n'est pas masculin, ou une femme qui va au-delà des normes sociales centrées sur les hommes, peut être considéré comme intéressant que seuls les lecteurs à cette époque peuvent comprendre.
- En bref, je pense que N-gram a encore beaucoup de potentiel, en fonction de l'idée de ce qu'il faut utiliser pour le corpus et de ce qu'il faut analyser avec.