[PYTHON] Essayez de visualiser vos tweets tout en comprenant BERT Hands-on

Cet article est l'article du 13ème jour du NTT Communications Advent Calendar 2019. Hier était l'article de @ nitky, Nous avons affaire à des renseignements sur les menaces dans une atmosphère.

introduction

Bonjour, c'est yuki uchida qui appartient à l'équipe NTT Communications SkyWay. Dans cet article, je vais essayer de visualiser mes tweets en utilisant le modèle de langage BERT utilisé pour le traitement du langage naturel, qui a été récemment appliqué à la recherche Google. Je vais l'écrire dans un format pratique afin que le plus de gens possible puissent l'essayer, donc si vous êtes intéressé, essayez-le.

Le moteur de recherche de Google "le plus grand bond en avant des 5 dernières années"

Qu'est-ce que BERT?

BERT est un modèle de langage naturel annoncé par Google en 2018, et a atteint une précision percutante dans de nombreuses tâches de langage naturel. Cette précision était étonnante et elle est devenue bien connue dans le domaine du traitement du langage naturel. (À propos, dans le domaine du traitement du langage naturel, un modèle de langage naturel appelé Word2Vec a été annoncé en 2014, et il y avait beaucoup de bruit, mais c'est aussi un article de Google.) Beaucoup de gens ont déjà expliqué les détails de ce BERT, je vais donc poster quelques liens.

Déplacer le modèle d'expression de langage à usage général BERT en japonais (PyTorch) Clarifions le fonctionnement interne du modèle d'expression de langage à usage général BERT

Que pouvez-vous faire avec ce BERT cette fois? Pour comprendre cela intuitivement, ouvrons le site suivant!

https://transformer.huggingface.co/

Ce site vous permet d'essayer une bibliothèque appelée transformers (anciennement pytorch-pretrained-bert) 'fournie par huggingfaceen ligne. Cette fois, sélectionnonsgpt`, qui est le même modèle de langage que BERT, et démontrons-le. Write_With_Transformer.png

Une fois sélectionné, l'écran passe à un écran de type Word dans lequel vous pouvez saisir du texte, comme illustré ci-dessous.

Dans cet état, entrez du texte, puis appuyez sur le bouton de tabulation. Ensuite, vous pouvez voir que les phrases sont affichées comme trois candidats. Si vous sélectionnez cette phrase, elle sera ajoutée à la phrase. 68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3132343631312f33346433643539312d323735372d323363312d613638612d6362303766333964303031372e706e67.png

Cette démo est un essai de ** génération de phrases **.

** La génération de phrases ** est une technologie étudiée depuis longtemps dans le domaine du traitement du langage naturel. En utilisant le ** modèle en langage naturel ** pour que l'ordinateur comprenne bien ** les informations textuelles **, il est devenu possible de générer des ** phrases ** naturellement de cette manière.

Si vous essayez de générer des phrases plusieurs fois telles quelles, vous obtiendrez des résultats assez intéressants. I have never met anyone who did not find it useful or useful for others . It was originally released as an open source project

Capture d'écran 2019-12-12 21.05.18.png

Cette fois, j'ai choisi le modèle appelé «GPT» sur ce site de démonstration, mais le modèle successeur appelé «GPT2» a été gardé privé pendant un certain temps parce que le promoteur d'OpenAI était préoccupé par son utilisation abusive. (Actuellement publié et peut être essayé sur le site de démonstration)

[Techcrunch: OpenAI a développé un très bon générateur de texte, mais je pense qu'il est trop dangereux de le publier tel quel](https://jp.techcrunch.com/2019/02/18/2019-02-17 -openai-générateur-de-texte-dangereux /)

Ainsi, ** un meilleur modèle de langage naturel améliore la précision de nombreuses tâches de traitement du langage naturel. ** **

Installation de transformateurs

Utilisez la bibliothèque huggingface, renommée de pytorch-pretrained-bert en transformers. Le site de démonstration que j'ai utilisé plus tôt sera la démo en ligne de ce transformers. En utilisant cette bibliothèque, vous pouvez facilement appeler BERT en combinaison avec pytorch (ou tensorflow).

https://github.com/huggingface/transformers

Pour cette pratique, nous appellerons BERT en utilisant pytorch au lieu de transformers. Si vous n'avez pas encore installé pytorch et transformers, installez-les avec la commande suivante.

pip install torch torchvision pip install transformers

Utilisez le modèle appris en anglais de BERT pour deviner les mots cachés

Cette fois, je vais tirer le modèle BERT qui prend en charge le japonais. Si vous pouvez utiliser l'anglais, vous n'avez rien à préparer et vous pouvez le lire avec le code suivant. model = BertForMasked.from_pretrained('bert-base-uncased')

** Cela prend un peu de temps pour utiliser le modèle formé japonais, donc avant d'utiliser le modèle formé japonais, utilisons le modèle formé anglais de BERT qui peut être facilement appelé. ** **

Tout d'abord, importez les bibliothèques requises. Créez test.py et écrivez comme suit.

import torch
from transformers import BertTokenizer, BertForMaskedLM
import numpy as np

Ensuite, définissons n'importe quelle phrase simple en anglais.


text = "How many lakes are there in Japan."

Maintenant, divisons les mots en utilisant l'outil d'écriture de division spécifique à BERT BertTokenizer. Collez le code ci-dessous. Le fractionnement mot par mot est ce que l'ordinateur doit faire pour déterminer où les coupures mot par mot sont effectuées. (En anglais, vous pouvez essentiellement diviser chaque mot simplement en le séparant par un espace.)

** (Remarque: entourez le début et la fin par [CLS] [SEP].) **

test.py


##Au stade de l'importation de la bibliothèque, BertTokenizer est également chargé
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
tokenized_text = tokenizer.tokenize(text)
tokenized_text.insert(0, "[CLS]")
tokenized_text.append("[SEP]")
# ['[CLS]', 'how', 'many', 'lakes', 'are', 'there', 'in', 'japan', '.', '[SEP]']

Cela nous a permis de diviser chaque mot.

** Ensuite, sélectionnez le mot que vous souhaitez masquer. BERT essaiera de deviner le mot. ** ** Cette fois, je voudrais cacher ** sont **. Décrivons le processus de remplacement de ce mot par «[MASQUE]».

test.py


masked_index = 4
tokenized_text[masked_index] = '[MASK]'
# ['[CLS]', 'how', 'many', 'lakes', '[MASK]', 'there', 'in', 'japan', '.', '[SEP]']

Cela a remplacé ** are ** par ** [MASK] **. Maintenant, je ne sais pas quel est le mot ici.

Donnez maintenant ce texte à BERT et demandez-leur de prédire le mot ** [MASQUE] **! !! !!

test.py


##Au lieu de le transmettre tel quel à BERT, convertissez-le avec un dictionnaire et faites-le id.
tokens = tokenizer.convert_tokens_to_ids(tokenized_text)
tokens_tensor = torch.tensor([tokens])
##Lisez BERT. Cela peut prendre un certain temps ici
model = BertForMaskedLM.from_pretrained('bert-base-uncased')
model.eval()

with torch.no_grad():
    outputs = model(tokens_tensor)
    predictions = outputs[0]
## masked_Retirez le résultat de la prédiction du mot dans la partie index et sortez le résultat de la prédiction top5
_, predict_indexes = torch.topk(predictions[0, masked_index], k=5)
predict_tokens = tokenizer.convert_ids_to_tokens(predict_indexes.tolist())
print(predict_tokens)
# ['are', 'were', 'lie', 'out', 'is']

En conséquence, suite à la prédiction des mots cachés, TOP5 est devenu «['are', 'were', 'lie', 'out', 'is']`. Comme vous pouvez le voir sur ce résultat, ** BERT a pu deviner les mots cachés. ** C'est étonnant!

Cette fois, j'ai utilisé ** BertForMaskedLM ** pour prédire les mots cachés. D'autres choses que vous pouvez facilement essayer sont les suivantes. Essayez-le.

  1. BertForNextSentencePrediction
  2. BertForSequenceClassification
  3. BertForTokenClassification
  4. BertForQuestionAnswering

Tirer le modèle appris japonais de BERT

Ensuite, à partir d'ici, c'est la production. ** Utilisez BERT pour visualiser le type de tweet que vous faites ** Tout d'abord, préparez BERT qui prend en charge le japonais. À l'origine, j'aimerais faire le pré-apprentissage de BERT par moi-même, mais BERT prend beaucoup de temps à apprendre. Par conséquent, Université de Kyoto Kurohashi / HP du laboratoire Kawahara distribue les modèles formés. Visitez% E6% 97% A5% E6% 9C% AC% E8% AA% 9EPretrained% E3% 83% A2% E3% 83% 87% E3% 83% AB) pour télécharger le modèle.

Il semble que cela prenne environ 30 jours pour apprendre BERT, donc je suis vraiment reconnaissant que vous puissiez vous sentir libre de l'essayer si vous le publiez comme ça ...

30 époques (1GPU (avec GeForce GTX 1080 Ti) prend environ 1 jour pour 1 époque, donc le pré-entraînement prend environ 30 jours)

Décompressez le fichier téléchargé et placez-le au même emplacement que le fichier python. (Créez un dossier bert comme indiqué ci-dessous et stockez-le là)

test.py


import torch
from transformers import BertTokenizer, BertModel, BertForMaskedLM
import numpy as np
model = BertModel.from_pretrained('bert/Japanese_L-12_H-768_A-12_E-30_BPE_transformers')
bert_tokenizer = BertTokenizer("bert/Japanese_L-12_H-768_A-12_E-30_BPE_transformers/vocab.txt",
                               do_lower_case=False, do_basic_tokenize=False)

Maintenant, essayons une fois de voir si le modèle BERT peut être utilisé.

Essayez de deviner les mots cachés dans BERT compatible japonais

J'aimerais utiliser le code que je viens de créer tel quel, mais cette fois, je parle de japonais au lieu d'anglais, donc je ne peux pas le séparer avec BertTokenizer. (Puisque la fonction de dictionnaire qui remplace les mots par id est utilisée, lisez-la comme ci-dessus) Cette fois, utilisons «Juman» pour diviser les mots et diviser les mots. Étant donné que l'installation de pip est requise pour gérer le juman, tapez la commande suivante pour l'installer. pip install pyknp

Maintenant que vous l'avez installé, utilisons ce Juman pour écrire un mot et séparer les mots. La phrase cible est «J'aime jouer au football avec mes amis», comme je l'ai fait en anglais.

test.py


from pyknp import Juman
jumanpp = Juman()
text = "J'aime jouer au foot avec mes amis"
result = jumanpp.analysis(text)
tokenized_text = [mrph.midasi for mrph in result.mrph_list()]
# ['je', 'Est', 'ami', 'Quand', 'Football', 'À', 'Faire', 'こQuand', 'Mais', 'J'aime']

A partir de là, la prédiction se fait de la même manière que la version anglaise.

test.py



tokenized_text.insert(0, '[CLS]')
tokenized_text.append('[SEP]')
masked_index = 5
tokenized_text[masked_index] = '[MASK]'
print(tokenized_text)
# ['[CLS]', 'je', 'Est', 'ami', 'Quand', '[MASK]', 'À', 'Faire', 'こQuand', 'Mais', 'J'aime', '[SEP]']
tokens = bert_tokenizer.convert_tokens_to_ids(tokenized_text)
tokens_tensor = torch.tensor([tokens])
model.eval()


with torch.no_grad():
    outputs = model(tokens_tensor)
    predictions = outputs[0]

_, predict_indexes = torch.topk(predictions[0, masked_index], k=5)
predict_tokens = bert_tokenizer.convert_ids_to_tokens(predict_indexes.tolist())
print(predict_tokens)
# ['Parler', 'travaux', 'baiser', 'Jeu', 'Football']

Dans la version japonaise de BERT, j'ai essayé de cacher et de prédire le «j'aime jouer au foot avec mes amis» ». C'est devenu «['histoire', 'travail', 'baiser', 'jeu', 'football']`. ** Le football n'était pas le numéro un, mais vous pouvez sentir que les autres réponses sont correctes. ** **

J'ai pu confirmer que la version japonaise de BERT fonctionne ici.

Préparer votre propre tweet

Maintenant, préparons un tweet pour la visualisation. Veuillez visiter la page suivante et cliquez sur «Données Twitter». https://twitter.com/settings/account

Lorsque l'écran ci-dessous apparaît, entrez le mot de passe, puis appuyez sur «Request Archive». Lorsque vous serez prêt et que vous recevrez un e-mail, celui-ci deviendra "Télécharger l'archive" et vous pourrez le télécharger. Twitterデータ___Twitter.png Twitterデータ___Twitter.png

Une fois le téléchargement terminé, décompressez-le et vérifiez le contenu. Comme ci-dessous. Ce n'est pas grave si vous avez beaucoup de fichiers Javascript et de tweet.js.

yuki-u_と_「BERTを理解しながら自分のツイートを可視化してみるハンズオン」を編集_-_Qiita.png

Convertissez vos tweets en csv

Tout l'historique actuel des tweets est stocké dans tweet.js et c'est un peu difficile à gérer, alors convertissons-le en csv. Vous pouvez convertir tweet.js en csv sur le site suivant.

** Cependant, comme décrit sur ce site, si vous êtes préoccupé par l'utilisation de cet outil, convertissez-le en csv d'une autre manière. ** ** J'ai créé un outil "tweet.js loader" qui lit tweet.js des données Twitter et affiche tout l'historique des tweets

tweet_js_loader_-_全ツイート履歴_表示er.png tweet_js_loader_-_全ツイート履歴_表示er.png

Cliquez sur le bouton CSV Output pour télécharger le CSV.

Une fois la conversion en csv terminée et que vous pouvez la télécharger, tout va bien. (Appelons-le tweets.csv)

Convertir les tweets en vecteurs de phrases

Maintenant, convertissons ce tweet tweet.csv en un vecteur de phrase avec BERT. ** Un vecteur de phrase est une version vectorisée de cette phrase **. Vérifions quel type de tweet est dit en versant le vecteur de phrase converti par BERT dans l'outil de visualisation.

test.py


import pandas as pd
import re
tweets_df = pd.read_csv("./tweets.csv")
tweets_df["text"] = tweets_df["text"].astype(str) #Faites-en une chaîne de caractères pour le moment
##Déclarez un tableau pour stocker le résultat après la conversion du vecteur de phrase et un tableau pour stocker le tweet d'origine
vectors = []
tweets = []
for tweet in tweets_df["text"]:
    tweet = re.sub('\n', " ", tweet)  #Supprimer les caractères de saut de ligne
    strip_tweet = re.sub(r'[︰-@]', "", tweet)  #Suppression des symboles pleine largeur
    try:
        if len(strip_tweet) > 3: #Parce que trop peu de mots peuvent ne pas vous donner le bon vecteur
            vector = compute_vector(
                strip_tweet, model, bert_tokenizer, juman_tokenizer)
            vectors.append(vector)
            tweets.append(tweet)
    except Exception as e:
        continue
##Placez le vecteur de texte converti dans tsv.(L'outil de visualisation nécessite tsv, alors faites-le tsv)
pd.DataFrame(tweets).to_csv('./tweets_text.tsv', index=False, header=None))
pd.DataFrame(vectors).to_csv('./tweets_vector.tsv', sep='\t', index=False, header=None))

Le compute_vector qui apparaît ici est le processus de conversion en un vecteur de phrase en utilisant le modèle BERT.

test.py


def compute_vector(text, model, bert_tokenizer, juman_tokenizer):
    use_model = model
    tokens = juman_tokenizer.tokenize(text)
    bert_tokens = bert_tokenizer.tokenize(" ".join(tokens))
    ids = bert_tokenizer.convert_tokens_to_ids(
        ["[CLS]"] + bert_tokens[:126] + ["[SEP]"])
    tokens_tensor = torch.tensor(ids).reshape(1, -1)
    use_model.eval()
    with torch.no_grad():
        all_encoder_layers, _ = use_model(tokens_tensor)
    pooling_layer = -2
    embedding = all_encoder_layers[0][pooling_layer].numpy()
    # embedding = all_encoder_layers[0].numpy()
    # return np.mean(embedding, axis=0)
    return embedding

Si vous vérifiez le fichier enregistré par ce processus, il devrait y avoir tweets_vector.tsv où le vecteur de phrase est enregistré dans les délimiteurs d'onglets et tweets_text.tsv où le tweet d'origine est enregistré. est.

tweets_vector_tsv_—_AIResearch.png tweets_text_tsv_—_AIResearch.png

Essayez de visualiser

Vous êtes maintenant prêt pour la visualisation. Visualisons ces vecteurs de phrases en utilisant EmbeddingProjector! !! !! !! !!

http://projector.tensorflow.org/

Lorsque vous y accédez, vous devriez voir la distribution de mots Word2Vec comme indiqué ci-dessous. Embedding_projector_-_visualization_of_high-dimensional_data.png

Cette fois, je veux voir la distribution de mes tweets, alors utilisons les tweets_vector.tsv et tweets_text.tsv générés plus tôt comme sources de données. Appuyez sur le bouton Charger et sélectionnez tweets_vector.tsv pour le premier et tweets_text.tsv pour le second. Embedding_projector_-_visualization_of_high-dimensional_data.png

Embedding_projector_-_visualization_of_high-dimensional_data.png

** Vous devriez maintenant pouvoir visualiser vos tweets. ** **

Étant donné que le vecteur de phrase converti par BERT est à l'origine de 768 dimensions, il ne peut pas être affiché en 3 dimensions comme celle-ci, mais comme l'ACP (l'une des méthodes de compression de dimension) est effectuée automatiquement, ce qui suit Est affiché. Pour la compression dimensionnelle, non seulement PCA mais aussi T-SNE et UMAP peuvent être sélectionnés.

Embedding_projector_-_visualization_of_high-dimensional_data.png

Si vous sélectionnez un point quelconque, une phrase similaire à cette phrase sera affichée. Cette fois, les 10 principales similitudes sont affichées.

スクリーンショット 2019-12-12 1.19.36.png

** Les phrases liées à l'étude et à la thèse ont été sélectionnées comme des phrases similaires! !! Il semble que la similitude des phrases puisse être raisonnablement bien calculée. ** **

Il s'agit de la distribution lorsqu'elle est divisée en deux dimensions. Embedding_projector_-_visualization_of_high-dimensional_data.png

** À l'origine, les objets de 768 dimensions sont déposés de force dans quelques dimensions, de sorte que la distribution n'est pas clairement séparée. ** ** ** Grâce à l'ACP, le taux d'explication était de 25% à la 2e place supérieure, 30% à la 3e place et 50% à la 10e place, donc c'était également un résultat convaincant. ** **

Résumé

Cette fois, c'est une pratique ** que j'ai essayé de visualiser mes tweets tout en comprenant BERT. En visualisant la distribution de vos propres tweets, vous serez en mesure de comprendre dans une certaine mesure quel type de tweets vous tweetez. Dans mon exemple, j'étais plutôt biaisé vers la programmation et les tweets négatifs, et j'ai découvert que "je suis une telle personne d'un point de vue objectif ...". Je regrette de ne pas avoir eu le temps d'utiliser le morceau de phrase, donc je vais vous donner un autre article en utilisant le morceau de phrase.

Le traitement du langage naturel ne produit souvent pas de résultats faciles à comprendre, mais la visualisation donne de nouvelles découvertes. Si vous trouvez cet article intéressant, ** essayez-le avec vos propres tweets **.

De plus, si vous suivez twitter, vous murmurerez sur le traitement du langage naturel et les systèmes de recommandation, et rédigerez des articles.

Eh bien, c'est la fin de mon article. Tomorrow est un article de @Mahito. impatient de!

Recommended Posts

Essayez de visualiser vos tweets tout en comprenant BERT Hands-on
[Introduction à TensorBoard] Visualisez le traitement TensorFlow pour approfondir la compréhension
[Introduction à TensorBoard: image] TensorFlow Visualisez le traitement d'image pour approfondir la compréhension