[PYTHON] Verwenden Sie Sudachipys gelerntes word2vec in einer Umgebung mit wenig Speicher

Einführung

Wenn Sie das gelernte Wort2vec bei der Verarbeitung der japanischen Sprache verwenden möchten Liste der gebrauchsfertigen Worteinbettungsvektoren Es war einfach, die trainierten Daten zu erhalten und Gensim wie dieses zu verwenden. Viele von ihnen werden jedoch aus Wikipedia usw. gelernt, und die Anzahl der Wörter beträgt ungefähr 50.000. Selbst wenn Sie versuchen, beliebige Sätze zu teilen und zu vektorisieren, sind sie nur unbekannte Wörter und nutzlos.

Ich dachte, dass die japanische morphologische Analyse Mecab ist, aber in letzter Zeit gibt es auch Sudachi, das von Works-Anwendung bereitgestellt wird. Darüber hinaus wird ein Word2Vec-Modell bereitgestellt, das in Sudachi geschrieben und gelernt wurde. Es enthält Daten mit 3,6 Millionen Wörtern aus dem Kokugoken Japanese Web Corpus mit einer Skala von 10 Milliarden Wörtern. Verwenden Sie ein geschultes Word2Vec-Modell basierend auf Sudachi Es scheint einfach zu bedienen zu sein, da es ziemlich viele Wörter gibt.

Es ist nur eine txt-Datei, in die Wörter und entsprechende Vektoren geschrieben werden, aber es sind riesige Daten, die beim Komprimieren 5 GB und nach der Dekomprimierung etwa 12 GB betragen. Es ist kein Problem, wenn die Maschine über viel Speicher zum Lernen verfügt, es kann jedoch schwierig sein, 12G in einer Umgebung mit wenig Speicher für Inferenz auf Speicher zu erweitern.

Wenn Sie jedoch nur ein Wort vektorisieren möchten, können Sie es jedes Mal von der SSD (HDD) aufrufen, ohne es in den Speicher zu erweitern.

Installation von Suda Chipy

https://github.com/WorksApplications/SudachiPy Sie können es genau so installieren, wie es auf github geschrieben ist. Abhängig von der Umgebung hat das Terminal den Befehl sudachipy nicht erkannt. Führen Sie zum Festlegen von sudachidict_full set_default_dict_package in config.py im Verzeichnis sudachidict aus.

Wechseln Sie in das sudapipy-Verzeichnis des Installationsziels, fügen Sie am Ende der Datei Folgendes hinzu und führen Sie es im Terminal aus.

config.py


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

Verwenden Sie trainierte Daten, ohne den Speicher zu erweitern

Sie können jeden Wortvektor mit hoher Geschwindigkeit aufrufen, indem Sie sich zuerst den Speicherort jeder Zeile merken, indem Sie auf diesen Artikel verweisen. [Python] Untersuchung zum effizienten Lesen einer bestimmten Zeile durch Angabe der Zeilennummer aus einer CSV-Datei mit einer großen Anzahl von Zeilen und Spalten

Beziehen Sie die gelernten Daten von der URL und platzieren Sie sie, wo immer Sie möchten. Verteilter japanischer Wortausdruck durch Korpus in großem Maßstab und multiple Granularitätsteilung

Es ist jetzt möglich, Wörter in einer Klasse zu einem Vektor zu gruppieren oder einen Satz zu teilen und dann jeweils eine vektorisierte Version zurückzugeben.

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=' ')
        #Erstellen Sie zunächst eine Liste der enthaltenen Wörter und eine Liste der Speicheradressen (dies dauert sehr lange).
        #Lesen Sie ab dem zweiten Mal die Pickle-Version
        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()
            #Anzahl der Dimensionen der verteilten Darstellung
            self.emb_size = int(txt.split()[1])
            #Gibt den durchschnittlichen Vektor zurück, wenn ein unbekanntes Wort kommt
            self.ave_vec = np.zeros(self.emb_size, np.float)
            #Speicheradressliste
            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)
        #Zubereitung von Sudachi
        self.tokenizer_obj = dictionary.Dictionary().create()
        self.mode = tokenizer.Tokenizer.SplitMode.C

    #Wörter vektorisieren
    def word2vec(self, word):
        try:
            idx = self.word2index[word]
            result = self.read_row(idx)
            vec = np.array(result[-300:])
            return vec
        except:#Wenn nicht in der Wortliste
            print(word, ": out of wordlist")
    
    #Geben Sie nach dem Teilen des Satzes jeden Vektor zusammen mit mat zurück
    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:#Gibt den durchschnittlichen Vektor zurück, wenn er nicht in der Wortliste enthalten ist
                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)

Die Verwendung ist wie folgt. Erstellen Sie zunächst eine Liste der enthaltenen Wörter und eine Liste der Speicheradressen. Dies dauert einige Zeit. (Mehrere zehn Minuten) Nach dem einmaligen Erstellen wird das Erstellungsergebnis in pickle umgewandelt. Ab dem zweiten Mal können Sie eine Instanz in wenigen Sekunden erstellen, indem Sie pickle lesen.

python


path = '~Speicherort der Trainingsdaten~/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("Wenn Sie aufgeben, endet das Spiel dort")
print(input_sentence, mat)
#(['Gib auf', 'Tara', 'Dort', 'damit', 'Spiel ist aus', 'Ist', 'Yo'], array([[ 1.9788130e-02,  1.1190426e-01, -1.6153505e-01, ...,

Da die trainierten Daten von Sudachi eine große Anzahl von Wörtern enthalten, können die meisten Wörter konvertiert werden und scheinen einfach zu verwenden zu sein.

Recommended Posts

Verwenden Sie Sudachipys gelerntes word2vec in einer Umgebung mit wenig Speicher
Verwenden Sie WebDAV in einer Portable Docker-Umgebung
Verwenden Sie den neuesten Pip in einer virtuellen Umgebung
Verwenden Sie eine kostenlose GPU in Ihrer Lieblingsumgebung
Verwenden Sie Anaconda in einer Pyenv-Umgebung
Verwenden Sie den von word2vec gelernten Vektor in der Einbettungsebene von LSTM
Verwenden Sie die django-debug-Symbolleiste in der VirtualBox / Vagrant-Umgebung
Verwenden Sie print in Python2 lambda expression
Verwenden Sie Tensorflow in einer wurzellosen Umgebung
Verwenden Sie ein in PySpark geschultes Scikit-Lernmodell
Verwenden Sie Python 3 Subprocess.run () im CGI-Skript
Erstellen einer virtuellen Umgebung in einer Anaconda-Umgebung
Installieren Sie CaboCha in einer Umgebung, die nicht von Anaconda stammt (Win).
Startete Node.js in einer virtuellen Umgebung
Flutter in Docker - Erstellen und Verwenden einer Flutter-Entwicklungsumgebung in einem Docker-Container
Erstellen Sie in kürzester Zeit eine LAMP-Umgebung
Die Systemumschaltung erfolgt in der CentOS 7-Clusterumgebung
Starten Sie Django in einer virtuellen Umgebung mit Pipenv
Denken Sie daran, eine Python 3-Umgebung in einer Mac-Umgebung zu erstellen
Arbeiten Sie in einer virtuellen Umgebung mit Python virtualenv.
Verwenden Sie jupyter-lab, das in einer virtuellen Python-Umgebung (venv) installiert ist.
Verwenden Sie Python in einer Anaconda-Umgebung mit VS-Code
Verwenden Sie eine benutzerdefinierte Fehlerseite mit Python / Tornado
Verwenden Sie Python und word2vec (gelernt) mit Azure Databricks
Erstellen Sie mit Eclipse eine Minecraft-Plug-Entwicklungsumgebung
[Docker] Erstellen Sie in 3 Minuten eine jupyterLab (Python) -Umgebung!
Verwenden Sie pydantic beim Lesen von Umgebungsvariablen in Python
Verwenden Sie os.getenv, um Umgebungsvariablen in Python abzurufen
Verwendung von Docker zum Containerisieren Ihrer Anwendung und Verwenden von Docker Compose zum Ausführen Ihrer Anwendung in einer Entwicklungsumgebung