Post-scriptum 2017/4/13: J'ai reçu des conseils de M. taku910 lui-même. Voir la section des commentaires pour plus de détails. Cet article sera révisé ultérieurement. PostScript 2017/4/18: L'API publique a été modifiée. Unigram est toujours en train de construire un modèle (cela ne se termine pas même après 5 jours). 2017/4/26 postscript: Unigram a également été fait (il était finalement terminé après avoir tourné pendant 12 jours). Des détails à ce sujet ont été publiés dans Un autre article.
API
Pour expliquer brièvement
Laissez-moi vous expliquer un peu plus en détail.
Les données de Wikipedia japonais que j'avais étaient un peu anciennes avec le vidage de 20160915, mais je les ai utilisées comme données d'origine. Je le façonne avec quelques modifications. Si vous listez ce que vous avez fait
La raison pour laquelle je fais cela est que SentencePiece semble nécessiter beaucoup de mémoire et que je ne pouvais pas entrer le texte intégral (environ 2 Go) sur mon PC (16 Go de mémoire). Après de nombreux essais et erreurs, il semble qu'environ 600 Mo soit la limite pour un PC de 16 Go. Au lieu de cela, le processus est rapide tant que les données sont en mémoire.
PhrasePiece s'exécute avec la commande suivante. En ce qui concerne l'environnement d'exécution, j'ai mis Cygwin dans Windows 10 et l'ai exécuté. La bibliothèque nécessaire qui était dans le README original était Cygwin et j'ai mis quelque chose comme ça (certaines versions ne correspondent pas, mais cela a fonctionné).
$ ./spm_train --input=input.txt --model_prefix=output --vocab_size=8000 --model_type=bpe
La sortie est un fichier vocal et un fichier modèle. Le fichier de vocabulaire est un fragment de mot de 8000 lignes.
Maintenant, préparez-vous à publier avec l'API Web. La réponse de l'API Web renverra un ensemble de "fragment de mot" et "ID de fragment de mot" sous forme de tableau. Utilisez "Word Fragment ID", par exemple, lors de la création d'un vecteur One-Hot dans l'apprentissage automatique. Bien sûr, vous n'êtes pas obligé de l'utiliser.
Maintenant, considérons l'implémentation. Le marché de l'API Web Apitore que j'exécute est entièrement implémenté en Java, mais Sentence Piece est écrit en C ++. "C'est un problème d'écrire un wrapper, et je ne comprends pas vraiment WebAPI en C ++ ... donc je dois le réaliser de force! SentencePiece est comme une analyse morphologique, n'est-ce pas?" J'ai décidé d'utiliser l'analyseur morphologique Java kuromoji. kuromoji est la version Java du célèbre mecab. Et mecab est la technologie de recherche de M. Kudo qui a créé Sentence Piece. Vous êtes connecté!
Donc, cette fois, j'ai pris la forme d'ajouter la sortie de Sentence Piece en tant que nouveau dictionnaire au kuromoji existant. Au lieu de cela, voici quelques astuces. Le format du dictionnaire ressemble à ceci.
#Type de surface,ID de contexte gauche,ID de contexte correct,Coût,Partie,Partie細分類1,Partie細分類2,Partie細分類3,Type d'utilisation,Type d'utilisation,Prototype,en train de lire,prononciation
Être terminé,1,1,1,SPWORD,1,*,*,*,*,*,*,*
La «forme de surface» est le «fragment de mot» qui est la sortie de la phrase Piece. Le but est de régler le «coût» sur «1». Si "Coût" est réglé sur "1", le fragment de mot du fragment de phrase sera presque certainement sélectionné lors de l'analyse morphologique. Pour être sûr, modifiez le coût de connexion de toutes les pièces à 1 dans `` matrice.def '', qui définit le coût de connexion du contexte. En faisant cela, vous pouvez "relier les fragments de mots de la phrase Piece sans tenir compte du contexte". Vous n'avez pas à vous soucier du contexte, donc l '"ID de contexte" peut être n'importe quoi. Cette fois, l '"ID de contexte" est défini sur "1".
«ID de fragment de mot» a été attribué à «Partie de la sous-catégorie de mots 1». "Word Fragment ID" est un identifiant unique que j'ai donné à la sortie 8000 mots de la phrase Piece (c'est-à-dire 8000 identifiants au total, les numéros 1 à 8000 sont utilisés). La «partie du mot» de la phrase est «SPWORD». Cette partie du mot est utilisée pour rechercher des mots qui ne sont pas couverts par le fragment de phrase. Pour expliquer un peu, les fragments de mot de Sentence Piece sont basés sur des données d'entraînement. Bien sûr, il n'existe aucun moyen de gérer des caractères qui ne sont jamais apparus dans les données d'entraînement. J'ai décidé de détecter le caractère inconnu avec le kuromoji conventionnel. (Je pense que les caractères inconnus sont presque certainement classés comme "mots inconnus") Lorsque les paroles de la partie ne sont pas "SPWORD", l'ID de fragment de mot est mis à "0". Cela peut gérer des caractères inconnus.
Tout ce que vous avez à faire est de compiler. Compilez kuromoji comme d'habitude. Le code de test inclus dans kuromoji ne passera jamais, supprimez donc le test.
L'API est disponible sur ici. Veuillez consulter ici pour les préparatifs des appels d'API (enregistrement d'API, émission de jetons d'accès, exemple d'exécution).
Les spécifications telles que les entrées / sorties API sont publiées sur ici. Si vous l'écrivez également ici, les spécifications de réponse de l'API sont comme ça. L'entrée est du texte.
{
"endTime": "string",
"log": "string",
"processTime": "string",
"startTime": "string",
"tokens": [
{
"token": "string",
"wid": 0
}
]
}
Voyons un exemple d'utilisation réel. J'ai entré "Je suis un chat. Je n'ai pas encore de nom". Certes, c'est un peu différent de l'analyse morphologique normale.
"tokens": [
{
"wid": 5578,
"token": "je"
},
{
"wid": 5386,
"token": "Employé"
},
{
"wid": 472,
"token": "Est"
},
{
"wid": 5643,
"token": "Chat"
},
{
"wid": 11,
"token": "Est"
},
{
"wid": 3796,
"token": "。"
},
{
"wid": 2002,
"token": "Nom"
},
{
"wid": 472,
"token": "Est"
},
{
"wid": 1914,
"token": "encore"
},
{
"wid": 26,
"token": "Absent"
},
{
"wid": 3796,
"token": "。"
}
]
Puis, "WRYYYYYYYYYY! Le plus élevé est Aaaa". Il a été démonté en morceaux.
"tokens": [
{
"wid": 829,
"token": "W"
},
{
"wid": 589,
"token": "R"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 3032,
"token": "Y"
},
{
"wid": 0,
"token": "!"
},
{
"wid": 799,
"token": "Meilleur"
},
{
"wid": 2689,
"token": "À"
},
{
"wid": 646,
"token": "Oui"
},
{
"wid": 9,
"token": "Quoi"
},
{
"wid": 3880,
"token": "Ou"
},
{
"wid": 3888,
"token": "Un"
},
{
"wid": 3914,
"token": "Est"
},
{
"wid": 1726,
"token": "UNE"
},
{
"wid": 1726,
"token": "UNE"
},
{
"wid": 1726,
"token": "UNE"
}
]
Enfin, entrez "Vaincre la" peur ", c'est" vivre "". C'est un segment très caractéristique.
"tokens": [
{
"wid": 648,
"token": "「"
},
{
"wid": 5092,
"token": "Effrayant"
},
{
"wid": 5725,
"token": "Effrayant"
},
{
"wid": 3846,
"token": "」"
},
{
"wid": 2163,
"token": "À"
},
{
"wid": 5711,
"token": "Katsu"
},
{
"wid": 4840,
"token": "vêtements"
},
{
"wid": 543,
"token": "Faire"
},
{
"wid": 648,
"token": "「"
},
{
"wid": 2859,
"token": "Vivre"
},
{
"wid": 3798,
"token": "Ru"
},
{
"wid": 3846,
"token": "」"
},
{
"wid": 12,
"token": "chose"
}
]
J'ai défini la phrase Piece sur Web API. Cela semble être Mochiron à utiliser dans la traduction, et comme il peut être utilisé pour sec2sec, il semble que la conversion standard langue-dictionnaire puisse également être effectuée. Je pense l'utiliser pour le jugement de polarité. En ce moment, je fais RNN + LSTM pour les résultats Word2Vec, mais RNN + LSTM n'est-il pas quelque chose de bon pour créer un vecteur unique avec les fragments de mots de Sentence Piece?
Recommended Posts