Dans cet article, nous verrons comment utiliser fastText pour obtenir une représentation distribuée de mots ** nets **. Je l'ai écrit avec l'espoir qu'il puisse être lié à l'article de la veille.
fastText est une méthode pour acquérir la représentation distribuée de mots (mots exprimés numériquement) annoncée par Facebook. La base est le Word2Vec familier (CBOW / skip-gram). Word2Vec est encore nouveau, donc aucune explication n'est nécessaire.
Article: Enrichir les vecteurs de mots avec des informations de sous-mots
La différence entre Word2Vec et fastText est de savoir comment prendre un vecteur. En incorporant un mécanisme appelé sous-mots, des mots proches les uns des autres, comme sous forme d'utilisation, sont captés.
Dans Word2Vec, aller et venir étaient des mots complètement différents. Mais fastText prend cela en compte et fait aller et venir significatif comme le même composant. Bien sûr, vous serez fort contre les mots inconnus!
Pour plus de détails, nous vous recommandons le papier et les matériaux suivants.
Le but de ce temps est de "jouer avec des expressions distribuées de mots rapidement en utilisant Python et FastText".
e? Ne pouvez-vous même pas introduire Python rapidement? Utilisons Google Colaboratory. (Ci-après colab)
colab est l'environnement gratuit le plus puissant où toute personne disposant d'un compte Google peut facilement utiliser Python et GPU.
Un modèle d'apprentissage est nécessaire pour utiliser fastText. Vous pouvez collecter les données vous-même et les former, mais ici nous utiliserons le modèle formé.
Modèle formé: Le modèle entraîné de fastText a été publié --Qiita
Jetez simplement le modèle dans Google Drive. Comme c'est un gros problème, décompressons-le du lecteur, y compris les instructions sur la façon d'utiliser colab!
Un support est nécessaire pour toucher l'intérieur du lecteur avec colab. Vous pouvez le faire en exécutant le code ci-dessous, mais si vous appuyez sur le bouton «Mount Drive», vous devriez obtenir le même code, alors exécutez-le.
from google.colab import drive
drive.mount('/content/drive')
Après cela, accédez à l'URL, connectez-vous au compte et vous verrez le code d'autorisation, alors copiez-le et collez-le avec colab. Facile.
Tout ce que vous avez à faire est de décompresser le modèle!
%cd /content/drive/My Drive/data
!unzip vector_neologd.zip
Pour le chemin, spécifiez l'emplacement du modèle entraîné que vous avez téléchargé sur le lecteur.
Cherchons des mots similaires.
import gensim
model = gensim.models.KeyedVectors.load_word2vec_format('model.vec', binary=False)
model.most_similar(positive=['Traitement du langage naturel'])
résultat.
[('Comprendre le langage naturel', 0.7600098848342896),
('Langage naturel', 0.7503659725189209),
('Linguistique computationnelle', 0.7258570194244385),
('Programmation automatique', 0.6848069429397583),
('Exploration de texte', 0.6811494827270508),
('Langage informatique', 0.6618390083312988),
('Métaprogrammation', 0.658093273639679),
('programmation web', 0.6488876342773438),
('Analyse morphologique', 0.6479052901268005),
('Linguistique du corpus', 0.6465639472007751)]
C'est étonnamment amusant de jouer.
model.most_similar(positive=['ami'], negative=['relation amicale'])
[('connaissance', 0.4586910605430603),
('domicile', 0.35488438606262207),
('connaissance', 0.329221248626709),
('fréquentation', 0.3212822675704956),
('Les proches', 0.31865695118904114),
('Connaissance', 0.3158203959465027),
('domicile', 0.31503963470458984),
('Invitation', 0.302945077419281),
('Fréquemment', 0.30250048637390137),
('Collègue', 0.29792869091033936)]
C'était si net que je continuerais à limiter mon vocabulaire et à faire de même. C'est une option qu'il existe également une telle méthode.
Cette fois, nous traiterons du texte japonais, mais contrairement à l'anglais, chaque mot n'est pas divisé par des espaces, donc le prétraitement doit être effectué en premier (écriture séparée).
L'implémentation est basée sur Apprendre tout en faisant! Deep learning by PyTorch.
Ici, nous utilisons janome.
!pip install janome
Écrivons-le.
from janome.tokenizer import Tokenizer
j_t = Tokenizer()
def tokenizer_janome(text):
return [tok for tok in j_t.tokenize(text, wakati=True)]
Vous pouvez écrire rapidement avec seulement janome, mais faisons un simple prétraitement.
import re
import unicodedata
import string
def format_text(text):
text = unicodedata.normalize("NFKC", text)
table = str.maketrans("", "", string.punctuation + """,. ・")
text = text.translate(table)
return text
def preprocessing(text):
"""
Fonction à prétraiter
"""
text.translate(str.maketrans({chr(0xFF01 + i): chr(0x21 + i) for i in range(94)})) #Angle complet → demi-angle
text = text.lower() #Majuscules → minuscules
text = re.sub('\r', '', text)
text = re.sub('\n', '', text)
text = re.sub(' ', '', text)
text = re.sub(' ', '', text)
text = re.sub(r'[0-9 0-9]', '', text) #Suppression de numéros
text = re.sub(r'[!-/:-@[-`{-~]', '', text) #Suppression des symboles demi-largeur
text = re.sub(r'/[!-/:-@[-`{-~、-~ "" ・]', '', text) #Suppression des symboles pleine largeur
text = format_text(text) #Suppression des symboles pleine largeur
return text
def tokenizer_with_preprocessing(text):
text = preprocessing(text)
text = tokenizer_janome(text)
return text
Comme je l'ai écrit dans le commentaire, j'ai effectué un pré-traitement. Bien sûr, ce que vous devez faire lors du prétraitement changera en fonction de la tâche et du but.
Essayons de mettre une phrase appropriée.
text = 'Cette fois, je veux obtenir une expression distribuée en utilisant fastText! !! !!?'
print(tokenizer_with_preprocessing(text))
résultat.
['cette fois', 'Est', 'fasttext', 'À', 'Utilisation', 'main', 'Distribué', 'Expression', 'À', 'Acquis', 'Shi', 'Vouloir']
On dirait que ça marche.
Ensuite, utilisez torchtext pour faciliter les choses. Pour plus d'informations sur torchtext, voir Traitement du langage naturel facile et profond avec torchtext-Qiita.
import torchtext
max_length = 25
TEXT = torchtext.data.Field(sequential=True, tokenize=tokenizer_with_preprocessing,
use_vocab=True, lower=True, include_lengths=True,
batch_first=True, fix_length=max_length)
LABEL = torchtext.data.Field(sequential=False, use_vocab=False)
train_ds, val_ds, test_ds = torchtext.data.TabularDataset.splits(
path='./tsv/', train='train.tsv',
validation='val.tsv', test='test.tsv', format='tsv',
fields=[('Text', TEXT), ('Label', LABEL)])
Nous avons préparé train.tsv / test.tsv / val.tsv. Il s'agit d'un fichier tsv en divisant le texte de «Qu'est-ce que fastText» dans cet article en trois parties. Ceci est également un lien détaillé ci-dessus, donc je le recommande.
from torchtext.vocab import Vectors
vectors = Vectors(name='model.vec')
#Créer une version vectorisée du vocabulaire
TEXT.build_vocab(train_ds, vectors=vectors, min_freq=1)
#Vérifiez le vecteur de vocabulaire
print(TEXT.vocab.vectors.shape) #52 mots sont représentés par un vecteur de 300 dimensions
TEXT.vocab.vectors
#Vérifiez l'ordre des mots dans le vocabulaire
TEXT.vocab.stoi
Maintenant que nous sommes prêts, calculons la similitude de chaque mot du vocabulaire. Voyons si trois mots sont similaires à "mot".
import torch.nn.functional as F
tensor_calc = TEXT.vocab.vectors[TEXT.vocab.stoi['mot']]
#Similitude cosinus
print("papier", F.cosine_similarity(tensor_calc, TEXT.vocab.vectors[TEXT.vocab.stoi['papier']], dim=0))
print("mot", F.cosine_similarity(tensor_calc, TEXT.vocab.vectors[TEXT.vocab.stoi['mot']], dim=0))
print("vecteur", F.cosine_similarity(tensor_calc, TEXT.vocab.vectors[TEXT.vocab.stoi['vecteur']], dim=0))
résultat.
Tenseur de papier(0.3089)
Tenseur de mots(0.3704)
Tenseur de vecteur(0.3265)
Il existe différents articles sur fastText, mais pas autant que Word2Vec, je vais donc présenter ceux que je recommande particulièrement (références) et conclure.
Emplacement Postscript. J'ai déjà présenté divers articles, mais les articles suivants publiés récemment sont les plus recommandés. Il y a une comparaison avec Watson dans le titre, mais il y a un code fastText qui fonctionne avec Google colab, alors cliquez simplement. L'explication du format des données d'entraînement est également polie, et je pense que c'est une bonne idée de jeter un coup d'œil à l'article et au code.
Si vous voulez en savoir plus sur l'intégration de mots plus récents, je pense que beaucoup sortiront si vous recherchez sur Google avec ELMo ou BERT. Bien sûr, plus les modèles sont récents, plus cela devient difficile.
@ takashi1029!
Recommended Posts