[PYTHON] Obtenez une représentation distribuée des mots en Fast avec fastText sur Facebook

"France" - "Paris" + "Tokyo" = "Japon"

C'est Word2Vec annoncé par Google qu'il est devenu un sujet brûlant que de tels mots puissent être calculés. En termes simples, il s'agit d'une technologie qui exprime les mots numériquement, ce qui permet de mesurer la «proximité» des mots et d'effectuer les opérations ci-dessus. Cette expression numérique de mots est appelée une expression distribuée. Le fastText annoncé par Facebook introduit cette fois est une extension de ce Word2Vec, et vous pouvez apprendre des expressions plus précises à grande vitesse. Dans cet article, nous expliquerons le mécanisme et comment l'appliquer aux documents japonais.

Fonctionnement de FastText

Dans fastText, c'est un modèle qui peut résumer une «forme d'utilisation» qui n'était pas envisagée jusque-là dans Word2Vec et son modèle de type. Plus précisément, aller, aller et aller sont tous «aller», mais ils sont tous différents littéralement, ils sont donc traités comme des mots séparés dans les méthodes conventionnelles. Par conséquent, nous proposons une méthode pour rendre les mots proches les uns des autres plus cohérents dans leur sens en considérant les mots qui ont été décomposés en composantes (dans l'image, "go" et "es" pour go). Modèle de sous-mot).

image

Quant aux composants des mots, ceux de 3 caractères ou plus et de moins de 6 caractères sont utilisés dans l'article, et ceux de moins de 3 caractères sont traités comme préfixe / suffixe. Plus vous utilisez de composants de mots, plus vous pouvez faire de variations en combinaison, ce qui améliore votre expressivité, mais le calcul prendra plus de temps. C'est un compromis, mais je le limite à 2 millions dans mon article. Si vous souhaitez en savoir plus, veuillez consulter le document

En outre, fastText implémente également une fonction de classification de document qui utilise une représentation distribuée basée sur cette méthode (l'article est ci-dessous).

Ce qui précède est le mécanisme de fastText. À partir de là, je vais vous présenter la procédure pour utiliser réellement fastText.

Comment utiliser fastText

L'utilisation de fastText lui-même est très simple.

./fasttext skipgram -input data.txt -output model

Comme vous pouvez le voir sur la page officielle, il est aussi simple que possible de créer un modèle en passant les données du document data.txt. Cependant, contrairement à l'anglais, les mots ne sont pas séparés par des espaces en japonais, il est donc nécessaire de supprimer le mot «écriture séparée». La procédure pour cela est expliquée ci-dessous.

Le référentiel suivant est préparé pour ce travail. Si vous le clonez et procédez selon la procédure, ce sera OK, donc j'espère que vous en ferez usage.

icoxfog417/fastTextJapaneseTutorial

(Ce sera encourageant de recevoir Star m (_ _) m)

Préparation préalable

Cette fois, nous utiliserons Python pour le traitement, nous avons donc besoin d'un environnement Python. De plus, comme MeCab est utilisé pour écrire le japonais séparément, MeCab doit être installé. Sous Windows, il existe de nombreuses difficultés autour de MeCab, donc dans le cas de Windows 10, il est plus facile de travailler dans l'environnement Ubuntu en utilisant bash sous Windows.

1. Préparez un document à utiliser pour l'apprentissage

Tout d'abord, préparez un document à utiliser pour l'apprentissage (dans la communauté du langage naturel, cela s'appelle un corpus). Le plus connu est Wikipedia. Cette fois, j'ai utilisé les données de vidage de Wikipedia japonais.

[Wikipédia: Téléchargement de la base de données](https://ja.wikipedia.org/wiki/Wikipedia:%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83% BC% E3% 82% B9% E3% 83% 80% E3% 82% A6% E3% 83% B3% E3% 83% AD% E3% 83% BC% E3% 83% 89)

Accédez à l'emplacement de stockage de vidage à partir de "Wikipédia version japonaise de vidage" sur la page ci-dessus et obtenez les dernières données de date. Il existe de nombreux types, mais seuls l'aperçu (jawiki-xxxxxxxx-abstract.xml) et l'article complet (jawiki-xxxxxxxx-pages-articles.xml.bz2) sont utiles.

Bien entendu, d'autres documents tels que des articles de journaux et des articles de blog sont également acceptés. Il est préférable de préparer un corpus adapté aux fins de l'expression distribuée. Comme Wikipedia n'est qu'un dictionnaire, par exemple, même si vous regardez l'élément "Disneyland", son histoire, etc. est écrite en détail et les mots-clés tels que "fun" et les noms des attractions n'apparaissent jamais. Étant donné que la nature des expressions distribuées est déterminée par les mots qui apparaissent autour d'elles, vaut-il mieux inclure des éléments tels que amusants et célèbres en disant «Disneyland», ou vaut-il mieux inclure des éléments tels que Los Angeles et les années 1950? Le corpus à utiliser pour l'apprentissage dépend du type.

2. Extraire le texte

Lorsque vous utilisez Wikipédia, les données de vidage sont du XML, il est donc nécessaire d'en extraire des données textuelles pures. Il existe divers outils qui peuvent le faire, mais cette fois, j'ai utilisé Wikipedia Extractor fabriqué par Python.

Wikipedia Extractor

Il peut être exécuté comme suit. L'option -b sépare les fichiers tous les 500M.

python wikiextractor/WikiExtractor.py -b 500M -o (Dossier de sortie) jawiki-xxxxxxxx-pages-articles-multistream.xml.bz2

De plus, Wikipedia Extractor suppose un fichier dont le format de fichier est «bz2» et ne prend pas en charge les fichiers abstraits. Si vous voulez l'essayer avec un fichier abstrait, veuillez utiliser parser.py dans le référentiel car il peut être traité.

Enfin, les données texte extraites sont combinées dans un seul fichier texte. Ceci termine l'extraction de texte.

3. Divisez le texte en mots (séparés)

Eh bien, le sujet principal est d'ici. Contrairement à l'anglais, les mots ne sont pas séparés par des espaces en japonais, il est donc nécessaire de découper chaque mot en le traitant comme une division. MeCab est utilisé pour ce travail. Cette fois, nous n'avons pas besoin des informations morphologiques car nous les écrivons simplement séparément, nous allons donc les traiter avec la commande suivante.

mecab (Fichier texte cible) -O wakati -o (Fichier de destination de sortie)

Vous avez maintenant un fichier avec des mots séparés par des espaces.

De plus, MeCab dispose d'un dictionnaire de mots à partager. Plus vous aurez de vocabulaire dans ce dictionnaire, plus vos divisions seront précises et vous pourrez utiliser mecab-neologd pour reconnaître des mots plus modernes. Vous pouvez l'écrire séparément, veuillez donc l'utiliser au besoin.

4. Apprenez avec fastText

Maintenant que vous avez un fichier séparé par mot, tout comme en anglais, il ne vous reste plus qu'à exécuter fastText. Clonez le référentiel fastText et compilez-le avec make comme décrit dans la documentation.

Il existe différents paramètres de réglage, mais en se référant au papier, la taille de l'expression numérique (dimension vectorielle) du mot est la suivante en fonction de l'ensemble de données à traiter (* Il n'y avait aucune mention de ce qu'est le jeton d'unité. Mais c'est probablement un nombre de mots).

Le fait est qu'un petit jeu de données a une petite dimension. Dans le cas de tous les cas de Wikipédia, cela correspond à 300 dimensions complètes, alors procédez comme suit.

./fasttext skipgram -input (Fichiers séparés) -output model -dim 300

Si vous souhaitez utiliser les mêmes paramètres que l'apprentissage de Word2Vec, ce sera comme suit (pour le paramétrage, etc., voir ici. ).

./fasttext skipgram -input (Fichiers séparés) -output model -dim 200 -neg 25 -ws 8

(Bien qu'il soit également publié sur la question, il semble que cela change considérablement en fonction du paramètre](https://github.com/facebookresearch/fastText/issues/5). Epoch, mincount, etc.)

Lorsque la formation est terminée, deux types de fichiers, .bin et .vec, seront créés pour le nom de fichier spécifié par -output. Ce seront les fichiers qui contiennent les représentations distribuées apprises. En particulier, .vec est un simple fichier texte dans lequel les mots et les expressions distribuées sont appariés, donc je pense qu'il peut être lu et utilisé dans des langues autres que Python.

Cependant, dans le cas de tous les cas Wikipeida, la taille des données est trop grande et lorsque vous essayez de lire le fichier model, il saute parfois avec une erreur de mémoire, et il y a des cas où des problèmes d'encodage se produisent (ou plutôt, cela s'est produit). Mais). Dans ce cas, créez un dictionnaire de mots une seule fois (créez un dictionnaire qui convertit les mots en identifiants tels que "matin" -> 11) et convertissez le fichier texte en une colonne d'identifiants de mots.

5. Utilisez fastText

Maintenant, utilisons en fait fastText. Il existe une interface Python, mais comme mentionné ci-dessus, la structure du fichier est simple, il n'est donc pas nécessaire de l'utiliser. Nous avons eval.py dans le référentiel, vous pouvez donc l'utiliser pour rechercher des mots similaires.

python eval.py EXILE

Le résultat est ···

EXILE, 0.9999999999999999
Exilé, 0.8503456049215405
ATSUSHI, 0.8344220054003253

Eh bien, les similitudes sont nettes (les nombres indiquent la similitude cosinus; plus il est proche de 1, plus il est similaire, et plus il est proche de 0, moins il est similaire). À l'inverse, regardons des mots qui ne sont pas similaires.

python eval.py EXILE --negative

Le résultat est ····

la souveraineté, 0.011989817895453175
Génial, 0.03867233333573319
Hospital, 0.10808885165592982
Pression, 0.11396957694584102
Tableau d'affichage électronique, 0.12102514551120924
Faction chiite, 0.13388425615685776
Philippin, 0.134102069272474
Relier, 0.13871080016061785
Cannes, 0.1560228702600865
Iseki, 0.16740051927385632
SaaS, 0.1938341440200136
Kaisei Junior et Senior High School, 0.19798593808666984
Peinture de musée, 0.23079469060502433
papillon, 0.23615273153248512
P5, 0.2795962625371914
AH, 0.2919494095090802

EXILE et Shia ne sont pas tout à fait similaires. Il est très raisonnable de le penser de cette façon (???).

Avec ce genre de sensation, vous pouvez facilement l'utiliser. Veuillez essayer.

Recommended Posts

Obtenez une représentation distribuée des mots en Fast avec fastText sur Facebook
Utilisons rapidement l'expression distribuée des mots avec fastText!
Obtenez une liste de fichiers dans un dossier avec python sans chemin
Obtenez le nombre de lecteurs d'articles sur Mendeley en Python
Obtenez une liste des packages installés dans l'environnement actuel avec python
Récupérer l'appelant d'une fonction en Python
Obtenir une liste d'utilisateurs IAM avec Boto3
Touchons une partie de l'apprentissage automatique avec Python
Comment obtenir une liste de fichiers dans le même répertoire avec python
Remarque sur le comportement par défaut de collate_fn dans PyTorch
Obtenez l'identifiant d'un GPU avec une faible utilisation de la mémoire
Obtenez UNIXTIME au début d'aujourd'hui avec une commande
Obtenez le nombre d'éléments spécifiques dans la liste python
Obtenez une liste des livres électroniques DMM achetés avec Python + Selenium
Comment obtenir une liste d'exceptions intégrées pour python
Obtenez le nom d'hôte du PC hôte avec Docker sous Linux
Rendement dans la classe qui a hérité de l'unittest.TestCase ne fonctionnait pas avec le nez (selon la version du nez?)
Comment est le progrès? Continuons le boom ?? en Python
Traitez le contenu du fichier dans l'ordre avec un script shell
Essayez d'obtenir la liste des fils du bulletin d'information (je n'aime pas) avec Python.
J'ai écrit un script pour vous aider à démarrer avec AtCoder à grande vitesse!
Quand j'obtiens une erreur avec Pylint sur Windows Atom
Créez un nuage de mots avec uniquement des mots positifs / négatifs sur Twitter
Obtenez des données de VPS MySQL avec Python 3 et SQL Alchemy
J'ai essayé de résumer brièvement la procédure de démarrage du développement de Django
Obtenir l'URL du ticket JIRA créé par la bibliothèque jira-python
Comment obtenir les coordonnées de sommet d'une entité dans ArcPy
Trouvez le rang de la matrice dans le monde XOR (rang de la matrice sur F2)
Pourquoi l'expression distribuée des mots est-elle importante pour le traitement du langage naturel?
Créez une fonction pour obtenir le contenu de la base de données dans Go