[PYTHON] Utilisez le mot2vec appris de Sudachipy dans un environnement à faible mémoire

introduction

Si vous souhaitez utiliser le mot appris2vec lors du traitement de la langue japonaise Liste des vecteurs d'incorporation de mots prêts à l'emploi Il était facile d'obtenir les données formées et d'utiliser des gensim comme celui-ci. Cependant, beaucoup de choses sont apprises de wikipedia, etc., et le nombre de mots est d'environ 50 000, donc même si vous essayez de diviser et de vectoriser une phrase arbitraire, cela peut ne pas être utile car ce sont juste des mots inconnus.

Je pensais que l'analyse morphologique japonaise était mécab, mais récemment, il y a aussi Sudachi fourni par l'application Works. En outre, un modèle Word2Vec qui a été écrit et appris en Sudachi est également fourni, et il s'agit de données apprises avec 3,6 millions de mots du corpus Web japonais Kokugoken de 10 milliards de mots. Utilisez un modèle Word2Vec formé basé sur Sudachi Cela semble facile à utiliser car il y a pas mal de mots.

C'est juste un fichier txt avec des mots et des vecteurs correspondants, mais c'est une énorme donnée de 5 Go lorsqu'il est compressé et environ 12 Go après décompression. Il n'y a aucun problème si la machine a beaucoup de mémoire pour l'apprentissage, mais il peut être difficile d'étendre 12G à la mémoire dans un environnement à faible mémoire pour l'inférence.

Cependant, si vous souhaitez simplement vectoriser n'importe quel mot, vous pouvez l'appeler à chaque fois à partir du SSD (HDD) sans l'étendre à la mémoire.

Installation de suda chipy

https://github.com/WorksApplications/SudachiPy Vous pouvez l'installer exactement comme il est écrit sur github, Selon l'environnement, le terminal n'a pas reconnu la commande sudachipy. Pour définir sudachidict_full, exécutez set_default_dict_package dans config.py dans le répertoire sudachidict.

Accédez au répertoire sudapipy de destination de l'installation, ajoutez ce qui suit à la fin du fichier et exécutez-le dans le terminal.

config.py


#~~~~~~~~~~~
#~~~~~~~~~~~
import sys
output = sys.stdout
set_default_dict_package('sudachidict_full',output)

Utilisez des données entraînées sans passer en mémoire

Vous pouvez appeler n'importe quel vecteur de mot à grande vitesse en vous rappelant d'abord l'emplacement mémoire de chaque ligne en vous référant à cet article. [Python] Examen de la manière de lire efficacement une ligne spécifique en spécifiant un numéro de ligne à partir d'un fichier CSV avec un grand nombre de lignes et de colonnes

Obtenez les données apprises à partir de l'URL et placez-les où vous le souhaitez. Expression de mot japonais distribuée par corpus à grande échelle et division de granularité multiple

Les mots peuvent être convertis en vecteurs dans une classe, ou les phrases peuvent être divisées puis renvoyées sous forme de vecteurs.

sudachi_w2v.py


import numpy as np
import pickle
import re
import csv
import os
from sudachipy import tokenizer
from sudachipy import dictionary

class Sudachi_w2v:
    def __init__(self, path, sudachiDataPath="sudachiData.pickle"):
        f = open(path, 'r')
        self.file = f
        self.reader = csv.reader(f, delimiter=' ')
        #Créez d'abord une liste de mots contenus et une liste d'adresses mémoire (cela prend un temps considérable)
        #À partir de la deuxième fois, lisez la version pickle
        if os.path.exists(sudachiDataPath):
            with open(sudachiDataPath, 'rb') as f:
                dataset = pickle.load(f)
            self.offset_list = dataset["offset_list"]
            self.emb_size = dataset["emb_size"]
            self.word2index = dataset["word2index"]
            self.ave_vec = dataset["ave_vec"]
        else:
            txt = f.readline()
            #Nombre de dimensions de la représentation distribuée
            self.emb_size = int(txt.split()[1])
            #Renvoie le vecteur moyen lorsqu'un mot inconnu arrive
            self.ave_vec = np.zeros(self.emb_size, np.float)
            #Liste d'adresses mémoire
            self.offset_list = []
            word_list = []
            count = 0
            maxCount = int(txt.split()[0])
            while True:
                count+=1
                self.offset_list.append(f.tell())
                if count % 100000 == 0:print(count,"/",maxCount)
                line = f.readline()
                if line == '':break
                line_list = line.split()
                word_list.append(line_list[0])
                self.ave_vec += np.array(line_list[-300:]).astype(np.float)
            self.offset_list.pop()
            self.ave_vec = self.ave_vec/count
            self.word2index = {v:k for k,v in enumerate(word_list)}

            dataset = {}
            dataset["offset_list"] = self.offset_list
            dataset["emb_size"] = self.emb_size
            dataset["word2index"] = self.word2index
            dataset["ave_vec"] = self.ave_vec
            with open(sudachiDataPath, 'wb') as f:
                pickle.dump(dataset, f)

        self.num_rows = len(self.offset_list)
        #Préparation du sudachi
        self.tokenizer_obj = dictionary.Dictionary().create()
        self.mode = tokenizer.Tokenizer.SplitMode.C

    #Vectoriser les mots
    def word2vec(self, word):
        try:
            idx = self.word2index[word]
            result = self.read_row(idx)
            vec = np.array(result[-300:])
            return vec
        except:#Sinon dans la liste de mots
            print(word, ": out of wordlist")
    
    #Après avoir divisé la phrase, renvoyez chaque vecteur avec mat
    def sentence2mat(self, sentence):
        words = sentence.replace(" "," ").replace("\n"," ")
        words = re.sub(r"\s+", " ", words)
        input_seq = [m.surface().lower() for m in self.tokenizer_obj.tokenize(words, self.mode)]
        input_seq = [s for s in input_seq if s != ' ']

        mat = np.zeros((len(input_seq), self.emb_size))
        input_sentence = []
        for i, word in enumerate(input_seq):
            try:
                idx = self.word2index[word]
                result = self.read_row(idx)
                input_sentence.append(result[0])
                mat[i] = np.array(result[-300:])
            except:#Renvoie le vecteur moyen s'il ne figure pas dans la liste de mots
                input_sentence.append("<UNK>")
                mat[i] = self.ave_vec
        return input_sentence, mat

    def __del__(self):
        self.file.close()

    def read_row(self, idx):
        self.file.seek(self.offset_list[idx])
        return next(self.reader)

L'utilisation est la suivante. Tout d'abord, créez une liste de mots contenus et une liste d'adresses de mémoire. Cela prend un certain temps. (Plusieurs dizaines de minutes) Après avoir créé une fois, le résultat de la création est transformé en pickle, donc à partir de la deuxième fois, vous pouvez créer une instance en quelques secondes en lisant pickle.

python


path = '~Emplacement de stockage des données d'entraînement~/nwjc_sudachi_full_abc_w2v/nwjc.sudachi_full_abc_w2v.txt'
sudachi = Sudachi_w2v(path)

vec = sudachi.word2vec("Sudachi")
print(vec)
#['0.07975651' '0.08931299' '-0.06070593' '0.46959993' '0.19651023' ~

input_sentence, mat = sudachi.sentence2mat("Si tu abandonnes, le match s'arrêtera là")
print(input_sentence, mat)
#(['abandonner', 'Tara', 'Là', 'alors', 'Jeu terminé', 'Est', 'Yo'], array([[ 1.9788130e-02,  1.1190426e-01, -1.6153505e-01, ...,

Étant donné que les données entraînées de sudachi ont un grand nombre de mots, la plupart des mots peuvent être convertis et cela semble facile à utiliser.

Recommended Posts

Utilisez le mot2vec appris de Sudachipy dans un environnement à faible mémoire
Utiliser WebDAV dans un environnement Docker portable
Utilisez le dernier pip dans un environnement virtualenv
Utilisez un GPU gratuit dans votre environnement préféré
Utiliser Anaconda dans un environnement pyenv
Utilisez le vecteur appris par word2vec dans la couche Embedding de LSTM
Utilisez django-debug-toolbar dans l'environnement VirtualBox / Vagrant
Utiliser l'impression dans l'expression lambda Python2
Utilisez tensorflow dans un environnement sans racine
Utiliser un modèle scikit-learn formé à PySpark
Utilisez Python 3 Subprocess.run () dans le script CGI
Créer un environnement virtuel dans un environnement Anaconda
Installer CaboCha dans un environnement non-Anaconda (Win)
Démarrage de Node.js dans un environnement virtuel
Flutter dans Docker - Comment créer et utiliser un environnement de développement Flutter dans un conteneur Docker
Créez un environnement LAMP en très peu de temps
Le basculement du système se produit dans l'environnement de cluster CentOS 7
Démarrez Django dans un environnement virtuel à l'aide de Pipenv
Pensez à créer un environnement Python 3 dans un environnement Mac
Travaillez dans un environnement virtuel avec Python virtualenv.
Utiliser jupyter-lab installé dans l'environnement virtuel python (venv)
Utiliser Python dans un environnement Anaconda avec VS Code
Utilisez une page d'erreur personnalisée avec python / tornado
Utiliser Python et word2vec (appris) avec Azure Databricks
Créez un environnement de développement de plugins Minecraft avec Eclipse
[Docker] Créez un environnement jupyterLab (python) en 3 minutes!
Utilisez pydantic lors de la lecture des variables d'environnement en Python
Utilisez os.getenv pour obtenir des variables d'environnement en Python
Comment utiliser Docker pour conteneuriser votre application et comment utiliser Docker Compose pour exécuter votre application dans un environnement de développement