Ein Hinweis, über den ich in Kapitel 2 von ["Deep Learning von Grund auf neu - Verarbeitung natürlicher Sprache"] gestolpert bin (https://www.oreilly.co.jp/books/9784873118369/) ist.
Die Ausführungsumgebung ist macOS Catalina + Anaconda 2019.10 und die Python-Version ist 3.7.4. Weitere Informationen finden Sie in Kapitel 1 dieses Memos.
Dieses Kapitel beginnt die Geschichte der Verarbeitung natürlicher Sprache.
Die Verarbeitung natürlicher Sprache soll "eine Technologie (ein Feld) sein, mit der ein Computer unsere Worte verstehen kann", aber wenn ich "einen Computer verständlich machen" höre, erweitert sich das Bild und ich stelle mir so etwas wie Doraemon vor. Daher denke ich, dass der Ausdruck "es von einem Computer verarbeitbar machen" gut ist.
Numerische Daten können einfach verarbeitet werden, indem summiert, gemittelt und verglichen, mit Diagrammen visualisiert, mit Zeitreihendaten die Zukunft vorhergesagt usw. werden. Sie können auch das im vorherigen Band erlernte Deep Learning verwenden. Dies ist jedoch bei Daten in natürlicher Sprache nicht der Fall. Es ist eine Technologie, die es möglich macht.
Außerdem ist die Abkürzung NLP dieselbe wie die neurolinguistische Programmierung, und wenn Sie mit "NLP" googeln, kommt die Geschichte der neuronalen Sprachprogrammierung zuerst heraus. Ich denke, es mag verwirrend sein, weil die Felder unterschiedlich sind, aber es kann für einen Moment zusammenhängen, wenn es während des Studiums des tiefen Lernens herauskommt. Bitte beachten Sie, dass Sie das vielleicht denken.
Ich werde in dem Buch nur Englisch sprechen, also werde ich das japanische System notieren.
--WordNet hat eine japanische Version von Japanese WordNet. Es ist jedoch nicht bestätigt, ob es mit NLTK wie in "Anhang B Ausführen von WordNet" im Buch verwendet werden kann. ――Die aus dem Programm verfügbaren Daten sind nicht öffentlich zugänglich, aber es scheint, dass die von der Nationalen Agentur für Wissenschaft und Technologie (JST) der Nationalen Forschungs- und Entwicklungsgesellschaft (JST) errichtete Cissolus ebenfalls berühmt ist. Es gibt eine Suchseite für Begriffe mit dem Namen JST Sisorus map. Wenn Sie nach einem Begriff suchen, sehen Sie Abbildung 2-2 des Buches Ein solches Diagramm wird angezeigt. Es wird nicht nur die Cissolus, sondern auch die statistische Information über die Häufigkeit des gleichzeitigen Auftretens in der Literatur verwendet. Wenn Sie beispielsweise nach "Automobil" suchen, wird eine großartige Grafik einer Skala angezeigt, die ohne Scrollen nicht sichtbar ist. Sie können den Bedingungen folgen, indem Sie doppelklicken.
Ich habe die zählbasierte Methode vor ungefähr 3 Jahren bei Language Processing 100 Knock 2015 studiert und werde sie daher überprüfen. Es wurde eine Form zu tun. Kapitel 9: Vektorraummethode (I) dieser 100 Schläge ist die "2,3-Zählmethode" dieses Buches. "Und" 2.4 Verbesserung der zählbasierten Methode ", so dass es keinen besonderen Stolperstein außer der Singularwertzerlegung danach gab.
Abbildung 2-8 in "2.4.2 Dimensionsreduzierung" kann etwas verwirrend sein. Wenn Sie das Bild in dieser Abbildung nicht erhalten haben, @aya_taka [Begriff des maschinellen Lernens "Dimensionalitätsreduzierung", der in 30 Minuten verstanden werden kann](https: // Ich denke, das Beispiel für Größe und Gewicht am Anfang von qiita.com/aya_taka/items/4d3996b3f15aa712a54f) sollte leicht zu verstehen sein.
Ich bin auf Singularity Decomposition (SVD) gestoßen. Tatsächlich ist dies meine dritte Studie (Maschinelles Lernen über Courseras Online-Kurs, den ich vor ungefähr 4 Jahren durchgeführt habe, und die oben erwähnte [Sprache]. Bei der Verarbeitung von 100 Schlägen 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/) kann ich das Bild verstehen, aber ich verstehe den Inhalt der Berechnung immer noch nicht. Ich verstehe die Bedeutung der Erklärung nicht, indem ich ein wenig google, und es scheint, dass ich die Prozession genau neu studieren muss. NumPy (und das nächste Scikit-Lernen) wird es für mich berechnen, deshalb bin ich dafür dankbar und habe beschlossen, weiterzumachen: Schweiß:
"2.4.4 PTB Dataset" verwendet das englische PTB-Korpus als großes Korpus, aber ich liebe Japanisch, deshalb habe ich beschlossen, es auf Japanisch zu versuchen. Im Gegensatz zu Englisch hat Japanisch keine Leerzeichen an den Wortgrenzen, daher ist es notwendig, die Aufteilung mit Leerzeichen zu verarbeiten. Diesmal wurde dies jedoch getan Aozora Bunkos Aufteilungstext. / segavvy / wakatigaki-aozorabunko) wird verwendet.
In dem Buch wird der PTB-Korpus in "Dataset / ptb.py" verwendet, aber ich habe dies geändert, um "Dataset / aozorabunko.py" zu erstellen. Unten ist der Quellcode, aber vorher gibt es einige Hinweise.
――Die Zieldaten sind nur 13 Werke, die von 3 Autoren ausgewählt und verkettet wurden, sodass eine erhebliche Verzerrung besteht. Bitte beachten Sie, dass dies nicht als Benchmark für die Methode verwendet werden kann, sondern nur "Ich habe es versucht".
dataset/aozorabunko.py
# coding: utf-8
import sys
import os
sys.path.append('..')
try:
import urllib.request
except ImportError:
raise ImportError('Use Python3!')
import pickle
import numpy as np
#★ Diese URL ist die Download-URL für die verschiedenen Aozora Bunko-Werke, die auf GitHub hochgeladen wurden.
#Für Details https://github.com/segavvy/wakatigaki-Bitte beziehen Sie sich auf Aozora Bunko.
url_base = 'https://github.com/segavvy/wakatigaki-aozorabunko/raw/master/'
key_file = {
'train': '20200516merge.txt',
'test': '', #★ Ich habe es nicht vorbereitet, weil ich es noch nicht benutzt habe
'valid': '' #★ Ich habe es nicht vorbereitet, weil ich es noch nicht benutzt habe
}
save_file = {
'train': 'aozorabunko.train.npy',
'test': 'aozorabunko.test.npy',
'valid': 'aozorabunko.valid.npy'
}
vocab_file = 'aozorabunko.vocab.pkl'
dataset_dir = os.path.dirname(os.path.abspath(__file__))
def _download(file_name):
file_path = dataset_dir + '/' + file_name
if os.path.exists(file_path):
return
print('Downloading ' + file_name + ' ... ')
try:
urllib.request.urlretrieve(url_base + file_name, file_path)
except urllib.error.URLError:
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
urllib.request.urlretrieve(url_base + file_name, file_path)
print('Done')
#★ Da die Textteilung an zwei Stellen verwendet wird, wird sie zu einer Funktion. Die Implementierung ist super ad hoc ...
def _split_data(text):
return text.replace('\n', '<eos> ').replace('。', '<eos> ').strip().split()
def load_vocab():
vocab_path = dataset_dir + '/' + vocab_file
if os.path.exists(vocab_path):
with open(vocab_path, 'rb') as f:
word_to_id, id_to_word = pickle.load(f)
return word_to_id, id_to_word
word_to_id = {}
id_to_word = {}
data_type = 'train'
file_name = key_file[data_type]
file_path = dataset_dir + '/' + file_name
_download(file_name)
words = _split_data(open(file_path).read())
for i, word in enumerate(words):
if word not in word_to_id:
tmp_id = len(word_to_id)
word_to_id[word] = tmp_id
id_to_word[tmp_id] = word
with open(vocab_path, 'wb') as f:
pickle.dump((word_to_id, id_to_word), f)
return word_to_id, id_to_word
def load_data(data_type='train'):
'''
:param data_type:Datentyp:'train' or 'test' or 'valid (val)'
:return:
'''
if data_type == 'val': data_type = 'valid'
save_path = dataset_dir + '/' + save_file[data_type]
word_to_id, id_to_word = load_vocab()
if os.path.exists(save_path):
corpus = np.load(save_path)
return corpus, word_to_id, id_to_word
file_name = key_file[data_type]
file_path = dataset_dir + '/' + file_name
_download(file_name)
words = _split_data(open(file_path).read())
corpus = np.array([word_to_id[w] for w in words])
np.save(save_path, corpus)
return corpus, word_to_id, id_to_word
if __name__ == '__main__':
for data_type in ('train', 'val', 'test'):
load_data(data_type)
Legen Sie diese Datei in das Verzeichnis "dataset", importieren Sie "aozorabunko.py" anstelle von "ptb.py" und "aozorabunko.load_data ()" anstelle von "ptb.load_data ()" , Sie können die Daten von Aozora Bunko anstelle des PTB-Korpus verwenden.
Obwohl in der Erläuterung zu "2.4.5 Auswertung mit PTB-Datensatz" angegeben ist, dass "sklearn-Modul installiert sein muss", lautet dieses sklearn außerdem scikit-learn. Eine Python-Bibliothek für maschinelles Lernen namens /), die in Anaconda enthalten ist. Wenn Anaconda gemäß dem Verfahren in Kapitel 1 des vorherigen Volumes installiert ist, können Sie es daher verwenden, ohne etwas zu tun.
Die Berechnung des PPMI nimmt außerdem viel Zeit in Anspruch. In meiner Umgebung dauert es mehrere Stunden, daher habe ich es geändert, um es nach der Berechnung in einer Datei zwischenzuspeichern. Außerdem möchte ich verschiedene Abfragen ausprobieren, damit ich sie standardmäßig eingeben kann.
Unten ist das modifizierte ch02 / count_method_big.py
. Ich habe "★" in den Hauptteil des Umbaus eingefügt.
ch02/count_method_big.py
# coding: utf-8
import sys
sys.path.append('..')
import numpy as np
from common.util import most_similar, create_co_matrix, ppmi
from dataset import aozorabunko #★ Geändert, um das Korpus von Aozora Bunko zu verwenden
import os #★ Zum Zwischenspeichern der PPMI-Berechnungsergebnisse hinzugefügt
import pickle #★ Zum Zwischenspeichern der PPMI-Berechnungsergebnisse hinzugefügt
window_size = 2
wordvec_size = 100
corpus, word_to_id, id_to_word = aozorabunko.load_data('train') #★ Korpus wechseln
vocab_size = len(word_to_id)
print('counting co-occurrence ...')
C = create_co_matrix(corpus, vocab_size, window_size)
#★ Die PPMI-Berechnung benötigt Zeit. Wechseln Sie daher zum Zwischenspeichern des vorherigen Ergebnisses und verwenden Sie es erneut, wenn C dasselbe ist
print('calculating PPMI ...')
W = None
ppmi_path = os.path.dirname(os.path.abspath(__file__)) + '/' + 'ppmi.pkl'
if os.path.exists(ppmi_path):
#★ Cache lesen
with open(ppmi_path, 'rb') as f:
cache_C, cache_W = pickle.load(f)
if np.array_equal(cache_C, C):
W = cache_W #Wiederverwendung, da der Inhalt von C gleich ist
if W is None:
W = ppmi(C, verbose=True)
with open(ppmi_path, 'wb') as f:
pickle.dump((C, W), f) #Als Cache speichern
print('calculating SVD ...')
try:
# truncated SVD (fast!)
from sklearn.utils.extmath import randomized_svd
U, S, V = randomized_svd(W, n_components=wordvec_size, n_iter=5,
random_state=None)
except ImportError:
# SVD (slow)
U, S, V = np.linalg.svd(W)
word_vecs = U[:, :wordvec_size]
#★ Ändern Sie die Abfrage in Standardeingabe
while True:
query = input('\nquery? ')
if not query:
break
most_similar(query, word_to_id, id_to_word, word_vecs, top=5)
Nachfolgend finden Sie die Ergebnisse einiger Abfragen. Zunächst aus der japanischen Übersetzung der Abfrage im Buch.
[query]Sie
Ehefrau: 0.6728986501693726
Ehefrau: 0.6299399137496948
K: 0.6205178499221802
Vater: 0.5986840128898621
ich: 0.5941839814186096
[query]Jahr
Anti: 0.8162745237350464
hundert: 0.8051895499229431
Protokoll: 0.7906433939933777
Acht: 0.7857747077941895
Kreis: 0.7682645320892334
[query]Wagen
Tür: 0.6294019222259521
Tür: 0.6016885638237
Wagen: 0.5859153270721436
Tor: 0.5726617574691772
Vorhang: 0.5608214139938354
Toyota wird nicht gefunden
"Du" fühlt sich gut an. "Jahr" scheint als Einheit ein Synonym zu haben. "Auto" ist nicht gut, weil es in den für den Korpus verwendeten Werken selten vorkommt. "Toyota" gibt es überhaupt nicht, daher kann man ihm nicht helfen.
Hier sind einige andere Dinge, die ich versucht habe. Die erste Hälfte ist relativ gut und die zweite Hälfte ist nicht gut.
[query]Morgen
Nacht-: 0.7267987132072449
Um: 0.660172164440155
Mittag: 0.6085118055343628
Abend: 0.6021789908409119
Nächstes Mal: 0.6002975106239319
[query]Schule
Tokio: 0.6504884958267212
Höher: 0.6290650367736816
Junior High School: 0.5801640748977661
Universität: 0.5742003917694092
Einsteigen: 0.5358142852783203
[query]Zashiki
Studie: 0.6603355407714844
Sou Seite: 0.6362787485122681
Zimmer: 0.6142982244491577
Zimmer: 0.6024710536003113
Küche: 0.6014574766159058
[query]Kimono
Schädel: 0.5216895937919617
schwarz: 0.5200990438461304
Kleider: 0.5096032619476318
Kleider: 0.48781922459602356
Hut: 0.4869200587272644
[query]ich
Meister: 0.6372452974319458
Extra: 0.5826579332351685
Kaneda: 0.4684762954711914
Sie: 0.4676626920700073
Labyrinth: 0.4615904688835144
[query]Verbrecher
Phantom: 0.6609077453613281
Diebe: 0.6374931931495667
Mitglied: 0.6308270692825317
diese Person: 0.6046633720397949
Tauchen: 0.5931873917579651
[query]bestellen
Geschichte: 0.6200630068778992
Beratung: 0.5290789604187012
Beschäftigt: 0.5178924202919006
Freundlichkeit: 0.5033778548240662
Vorlesung: 0.4894390106201172
[query]Waffenlose Waffe
Obsolet: 0.7266454696655273
Altmodisch: 0.6771457195281982
sah: 0.6735808849334717
Nasenatem: 0.6516652703285217
Ignoranz: 0.650424063205719
[query]Katze
Amen: 0.6659030318260193
Nobujo: 0.5759447813034058
Sumi: 0.5374482870101929
Status: 0.5352671146392822
gewöhnlich: 0.5205280780792236
[query]Alkohol
Buch: 0.5834404230117798
Tee: 0.469807893037796
Sich ausruhen: 0.4605821967124939
Essen: 0.44864168763160706
Stange: 0.4349029064178467
[query]Küche
Strang: 0.5380040407180786
Zeichen: 0.5214874744415283
Original: 0.5175281763076782
Recht: 0.5082278847694397
Geschäft: 0.5001937747001648
Die Autoren der Zieldaten sind übrigens Soseki Natsume, Kenji Miyazawa und Ranpo Edogawa. Der Korpus ist etwas zu voreingenommen, aber das ist interessant. Wenn Sie möchten, probieren Sie es aus.
Es gab viele Bewertungen, so dass ich es relativ reibungslos lesen konnte. Das nächste Kapitel wird wahrscheinlich in Produktion sein.
Das ist alles für dieses Kapitel. Wenn Sie Fehler haben, wäre ich Ihnen dankbar, wenn Sie darauf hinweisen könnten.
Recommended Posts