Cette référence expérimentale compare différentes façons de représenter les mots dans une tâche simplifiée de construire le modèle de langue So called.
Le modèle de langue est un moyen de calculer la probabilité d'un fragment donné du texte (chaîne de mots). La PNL a auparavant largement utilisé diverses options de construction de LM en fonction du comptage des n-grammes et du lissage (lissage) afin de compenser la décharge des n-grammes de grandes arches. Par exemple, NLTK a la mise en œuvre de la méthode Kneser-nney. Il existe également un grand nombre d'implémentations différentes qui diffèrent dans les détails techniques concernant le stockage de grands volumes d'informations N-gramères et la vitesse du traitement du texte, par exemple https://github.com/kpu/kenlm.
Au cours des deux dernières années, différentes options pour les modèles de langage neuronal (NLMS) ont été largement utilisées, qui utilisent diverses architectures neurosotéales, notamment récurrentes et scintillants. Le NLM peut être divisé en deux groupes: travailler au niveau des mots (NLM Aware Word) et au niveau des caractères (NLM Aware-Aware). La deuxième option est particulièrement intéressante en ce qu'elle permet au modèle de travailler avec des morphèmes . Ceci est extrêmement significatif pour les langues avec une morphologie riche. Pour certains mots, des centaines de formes grammaticales peuvent potentiellement exister, comme dans le cas des adjectifs dans la langue russe. Même un très grand cas de texte ne garantit pas que toutes les variantes des formulaires de mots seront incluses dans le vocabulaire pour le NLM consacré aux mots. D'un autre côté, les structures morphémiques obéissent presque toujours aux règles régulières, de sorte que la connaissance de la base ou de la forme de base du mot vous permet de générer ses options grammaticales et sémantiques: audacieuse, audacieuse, morsure, audacieuse, etc., ainsi que de déterminer la connexion sémantique entre les mêmes mots racinés, même si les mots correspondants ne sont pas connus pour la première fois et les statistiques de leur contexte de leur utilisation ne sont pas connus. La dernière remarque devient très importante pour les champs de la PNL avec une formation de mots dynamique, tout d'abord, ce sont toutes sortes de médias sociaux.
Dans le cadre de la référence, tout le code nécessaire a été préparé pour étudier et comparer les deux options NLM, ainsi que d'autres méthodes de construction de LM-Characte-Aware et Word-Aware.
Nous allons simplifier un peu notre modèle Langage, en définissant la tâche sous cette forme. Il y a un n-gram de longueur présélectionnée (voir la constante NGRAM_ORDER dans le module DataSetVectrisers). S'il est obtenu à partir du boîtier de texte (le chemin d'accès au fichier UTF-8 collé est cousu dans la classe de classe _GET_CORPUS_PATH), alors nous pensons qu'il s'agit d'une combinaison valide de mots et de la valeur cible y = 1. Si le n-gram est obtenu par un remplacement aléatoire de l'un des mots et une telle chaîne ne se trouve pas dans le cas, alors la valeur cible est y = 0.
Les n-grammes inacceptables sont générés lors de l'analyse du cas au même montant que valide. Il s'avère un ensemble de données équilibré, qui facilite la tâche. Et le manque de besoin de marquages manuels vous permet de "jouer" facilement avec un paramètre tel que le nombre d'enregistrements dans l'ensemble de données de formation.
Ainsi, le problème de classification binaire est résolu. Le classificateur sera la mise en œuvre de l'amélioration du gradient XGBOost et du réseau neuronal, implémenté sur des keras, ainsi que de plusieurs autres options sur différents langages de programmation et des cadres DL.
L'objet de l'étude est l'influence de la méthode de représentation des mots dans la matrice d'entrée X sur la précision de la classification.
Une analyse détaillée de diverses approches de la PNL, y compris pour des tâches similaires, peut être trouvée dans l'article: une amorce sur les modèles de réseau neuronal pour le traitement du langage naturel.
Les options suivantes sont vérifiées pour xgboost:
W2V - Nous utilisons le Core Word2Vec formé, collant des mots de mots dans un long vecteur
W2V_TAGS - L'expansion de la représentation W2V, des catégories supplémentaires du vecteur final sont obtenues à partir d'étiquettes morphologiques de mots. Il s'avère que quelque chose comme un modèle de langue factorisé
SDR - Crateaux distribués de représentations Mots obtenus par la factorisation du modèle Word2vector
Random_Bitvector - Chaque mot est attribué à un vecteur binaire aléatoire fixe avec une proportion donnée de 0/1
BC - Les vecteurs créés à la suite du travail du clustering brun (voir description https://en.wikipedia.org/wiki/Bron_clusterring et l'implémentation https://github.com/percyliang/brunki) sont utilisés en conséquence
Chars - Chaque mot est codé comme une chaîne de représentation de symboles 1-hot
HASHING_TRICK - Utilisé un astuce de hachage pour encoder des mots avec un nombre limité de bits d'index (voir Description https://en.wikipedia.org/wiki/Featuture_Hashing and Implementation https://radimrek.com/gensim/corporca/hashdictionary.html)
AE - Des mots de mots sont obtenus sous forme d'activation sur la couche intérieure de l'autoencodeur. La formation dans l'autoencoder et l'obtention de mots vecteurs sont effectuées par le script word_autoencoder3.py dans le dossier pymodels / wordAutoencoders.
Deux méthodes de présentation supplémentaires sont disponibles pour les réseaux de neurones, qui sont convertis en une certaine représentation vectorielle en utilisant la couche d'incorporation (ou similaire à la bibliothèque utilisée utilisée.
Word_inces - Un vocabulaire est compilé, chaque mot se voit attribuer un index entier unique. Ainsi, le grade à 3 semble être un triple entiers.
CHAR_INDECES - Un alphabet est compilé, chaque symbole se voit attribuer un index entier unique. De plus, les chaînes des index de symboles sont complétées par un indice d'échantillon à la même longueur (la longueur maximale du mot), et la chaîne résultante des indices de symbole est renvoyée comme présentation du n-gram. En utilisant une couche d'incorporation (intégration dans des keras ou similaires), les symboles sont convertis en une forme vectorielle dense avec laquelle fonctionne le reste du réseau neuronal. Il s'avère que la version du modèle de langue neuronale consciente des personnages.
Pour résoudre le problème, diverses bibliothèques d'apprentissage automatique, de réseaux de neurones et de bibliothèques pour l'informatique matricielle ont été utilisés, notamment:
Keras (avec backend Theano)
Lasagnes (Theano)
Nolearn (Theano)
Tensorflow
Solutions Python:
Pymodels / wr_xgboost.py - Resolver sur la base de xgboost
Pymodels / wr_catboost.py - Résolver CatBoost sur les index de mots en utilisant la possibilité d'indiquer des index des fonctionnalités catégorielles dans l'ensemble de données afin que le booster les apprenne indépendamment pendant la formation
Pymodels / wr_keras.py - un résolveur basé sur des neurosettes en avant de flux implémentées sur des keras
Pymodels / wr_keras_sdr2.py - Une solution distincte pour vérifier la représentation distribuée clairsemée d'une grande dimension (à partir de 1024) avec une génération de matrices en portion pour l'apprentissage et la validation, sur Keras. Pymodels / wr_lasagne.py - un résolveur basé sur des neurosettes en avant de nourriture implémentées sur les lasagnes (Theano)
Pymodels / wr_nolearn.py - Un résolveur basé sur les neurosettes en avant de nourriture implémentées sur Nolearn + Lasagne (Theano)
Pymodels / wr_tensorflow.py - un solveur basé sur des neurosettes en avant nourries implémentées sur Tensorflow
Solutions sur C #:
CSharpModels / WithaccordNet / Program.cs - Un résolveur basé sur les réseaux Feed Forward Accord.net (C #, Project for vs 2015)
CSharpModels / MyBaseline / Program.cs - Solution basée sur ma mise en œuvre Vanilla MLP (C #, Project for vs 2015)
Solutions sur C ++:
CXXMODELS / TINYDNN_MODEL / TINYDN_MODEL.CPP - Résolution MLP, implémentée par la bibliothèque Tiny -DNN (C ++, Projet pour VS 2015)
CXXMODELS / SINGA_MODEL / ALEXNET.CC - Un résolveur sur la base d'un réseau de neurones implémenté par Apache.Singa (C ++, projet pour vs 2015)
CXXMODELS / OpenNN_MODEL / MAIN.CPP - Un résolveur basé sur un neuro-émetteur, mis en œuvre par OpenNN (C ++, Project for vs 2015)
Solutions sur java javamodels / with4j / src / main / java / wordRepresentationStest.java - MLP Resolver, implémenté par DeepLearning4J Library
Cours et outils internes:
Pymodels / CorpusReaders.py - Classes pour la lecture des lignes à partir de bâtiments de texte de différents formats (zippé | Plain TXT) Pymodels / DataSetVectorzers.py - Vectoriseurs de données et usine pour un choix pratique
Pymodels / store_dataset_file.py - génération de l'ensemble de données et sa conservation pour les modèles C # et C ++
Pour des réseaux de neurones, 2 architectes ont été mis en œuvre sur la base de Keras. Le MLP est un simple NEFETE en avant avec des couches complètes. ConvNet est un maillage qui utilise des couches de bundle.
Les architectures de commutation sont effectuées par net_arch dans le paramètre net_arch dans le fichier wr_keras.py.
On peut noter que l'option Bristly donne souvent une solution plus précise, mais les modèles correspondants ont une variante plus grande, simplement en place - la précision finale saute considérablement pour plusieurs modèles avec les mêmes paramètres.
Une description détaillée de l'architecture et des résultats numériques des expériences se trouvent ici: https://kelijah.livejournal.com/224925.html.
Toutes les options de référence utilisent un fichier texte dans le codage UTF-8 pour recevoir des listes N-gram. Il est supposé que la division du texte en mots et la diffusion du registre inférieur sont faites à l'avance par un code de troisième partie. Par conséquent, les scripts lisent les lignes de ce fichier, les divisent en mots par des espaces.
Pour la commodité de jouer des expériences, j'ai placé une exposition compressée d'un grand boîtier avec une taille de 100 mille lignes dans le dossier de données. Cela suffit pour répéter toutes les mesures. Afin de ne pas surcharger le référentiel avec un grand fichier, il est haché. La méthode Basevectrizer._Load_Ngrams a elle-même déballé son contenu à la volée, vous n'avez donc pas besoin de faire des manipulations manuelles.
Dans la variante de la vectorisation de W2V_TAGS, des caractéristiques morphologiques sont ajoutées aux veines W2V. Ces signes pour chaque mot sont tirés du fichier word2tags_bin.zip dans le sous-calcaire de données, qui est obtenu par la conversion de mon dictionnaire grammatical (http://solarix.ru/sql-dictionary-sdk.shtml). Le résultat de la conversion est tiré à 165 Mo, ce qui est un peu trop pour le référentiel GIT. Par conséquent, j'ai crié le fichier résultant du dictionnaire grammatical, et la classe de vectorisation correspondante de l'ensemble de données lui-même l'a déballé à la volée pendant le fonctionnement.
Veuillez noter qu'en raison de l'homonymie des formes grammaticales, de nombreux mots ont plus d'un ensemble de balises. Par exemple, le mot «ours» peut être une forme d'un seul ou du pluriel, respectivement, dans un cas génitif ou nominatif. Lors de la formation de balises pour les mots, je combine des balises homonymes.
Un processus à deux stages est utilisé. Nous obtenons d'abord des vecteurs W2V de mots. Un petit script sur le Python décharge les vecteurs dans un fichier texte au format CSV.
Ensuite, en utilisant l'utilitaire https://github.com/mfaruqui/sparsecoding, une commande est effectuée:
./nonneg.o input_vectors.txt 16 0,2 1e-5 4 out_vecs.txt
Le fichier OUT_VECS.TXT contenant des mots SDR avec les paramètres indiqués est généré: size = 16 * vector w2v, remplissage = 0,2 Ce fichier est chargé avec la classe SDR_Vectizer.
https://habrahabr.ru/post/335838/
http://kelijah.livejournal.com/217608.html
En tant que chèque, nous utilisons la mémorisation des n-grammes de l'ensemble de formation et la recherche parmi les n-grammes rappelés pour l'ensemble de tests. La petite taille de l'ensemble d'entraînement conduit au fait que sur l'ensemble de tests, le modèle se comporte simplement comme une supposition aléatoire, donnant une précision de 0,50.
Le tableau principal des résultats est disponible sur le lien. Les autres résultats suivants ont été obtenus pour un ensemble de 1 000 000 3 grammes.
Pour un résolveur sur la base de xgboost (wr_xgboost.py), les résultats suivants ont été obtenus.
Pour un ensemble de données contenant 1 000 000 trigrammes: W2V_TAGS (Word2Vector + Morph Tags) ==> 0,81
W2v (word2vector dim = 32) ==> 0,80
Sdr (clairsemé distribué représente, longueur 512, 20% unités) ==> 0,78 avant JC (clustering brun) ==> 0,70
Chars (charbon un codage-hot) ==> 0,71
Random_Bitvector (vecteurs de bits aléatoires, part des unités 16%) ==> 0,696
Hash_trick (astuce de hachage avec 32 000 emplacements) ==> 0,64
Pour un solveur basé sur les lasagnes MLP:
Précision = 0,71
Pour un solveur basé sur Nolearn + Lasagne MLP:
Précision = 0,64
Pour un résolveur basé sur un MLP Tiny-DNN:
Précision = 0,58
Pour un solveur basé sur Accord.net Feed Feed Forwing Neural Net:
Word2vector ==> 0,68
Pour une résolution Catboost sur les caractéristiques catégorielles de "l'indice des mots":
Précision = 0,50
Pour un solveur basé sur Apache.Singa MLP:
Précision = 0,74
Solution de base - Mémoir les n-grammes de l'ensemble de données de formation
Précision = 0,50