[PYTHON] Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 2

Einführung

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.

Kapitel 2 Verarbeitung natürlicher Sprache und verteilter Ausdruck von Wörtern

Dieses Kapitel beginnt die Geschichte der Verarbeitung natürlicher Sprache.

2.1 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.

2.2 Sisolus

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.

2.3 Zählbasierter Ansatz

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.

2.4 Verbesserung der zählbasierten Methode

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.

2.5 Zusammenfassung

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

Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 5
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 2
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 1
Ein Amateur stolperte über Deep Learning ❷ von Grund auf neu Hinweis: Kapitel 4
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 1
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 3
Ein Amateur stolperte in Deep Learning von Grund auf neu. Hinweis: Kapitel 7
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 5
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 4
Ein Amateur stolperte in Deep Learning von Grund auf neu Hinweis: Kapitel 2
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 7]
Deep Learning / Deep Learning von Grund auf neu Kapitel 6 Memo
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 5]
[Lernnotiz] Deep Learning von Grund auf neu gemacht [Kapitel 6]
Deep Learning / Deep Learning von Grund auf neu Kapitel 7 Memo
[Lernnotiz] Deep Learning von Grund auf neu gemacht [~ Kapitel 4]
Deep Learning von Grund auf neu
Deep Learning von Grund auf neu ① Kapitel 6 "Lerntechniken"
Deep Learning von Grund auf neu Kapitel 2 Perceptron (Memo lesen)
Deep Learning von Grund auf 1-3 Kapitel
Deep Learning / Deep Learning von Grund auf neu 2 Kapitel 4 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 3 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 5 Memo
Erstellen Sie mit Docker eine Umgebung für "Deep Learning von Grund auf neu"
Tiefes Lernen von Grund auf neu (Kostenberechnung)
Deep Learning / Deep Learning von Null 2 Kapitel 7 Memo
Deep Learning / Deep Learning von Null 2 Kapitel 8 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 5 Memo
Deep Learning / Deep Learning von Grund auf neu Kapitel 4 Memo
Deep Learning / Deep Learning von Grund auf neu 2 Kapitel 3 Memo
Deep Learning Memo von Grund auf neu gemacht
Deep Learning / Deep Learning von Null 2 Kapitel 6 Memo
Schreiben Sie Ihre Eindrücke von der Deep Learning 3 Framework Edition, die von Grund auf neu erstellt wurde
Tiefes Lernen von Grund auf neu (Vorwärtsausbreitung)
Tiefes Lernen / Tiefes Lernen von Grund auf 2-Versuchen Sie, GRU zu bewegen
"Deep Learning von Grund auf neu" mit Haskell (unvollendet)
[Windows 10] Aufbau einer "Deep Learning from Scratch" -Umgebung
Lernbericht über das Lesen von "Deep Learning von Grund auf neu"
[Deep Learning von Grund auf neu] Über die Optimierung von Hyperparametern
"Deep Learning from Grund" Memo zum Selbststudium (Teil 12) Deep Learning
Python vs Ruby "Deep Learning von Grund auf neu" Kapitel 2 Logikschaltung von Perceptron
Python vs Ruby "Deep Learning von Grund auf neu" Kapitel 4 Implementierung der Verlustfunktion
Selbststudien-Memo "Deep Learning from Grund" (unlesbares Glossar)
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 9) MultiLayerNet-Klasse
Ein Amateur versuchte Deep Learning mit Caffe (Einführung)
GitHub des guten Buches "Deep Learning von Grund auf neu"
Ein Amateur versuchte Deep Learning mit Caffe (Übung)
[Lernnotiz] Deep Learning von Grund auf ~ Implementierung von Dropout ~
Ein Amateur hat Deep Learning mit Caffe ausprobiert (Übersicht)
Python vs Ruby "Deep Learning von Grund auf neu" Zusammenfassung
"Deep Learning from Grund" Memo zum Selbststudium (10) MultiLayerNet-Klasse
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 11) CNN
Deep Learning von Grund auf neu Die Theorie und Implementierung des mit Python erlernten Deep Learning Kapitel 3
Lua-Version Deep Learning von Grund auf neu Teil 5.5 [Bereitstellung von pkl-Dateien in Lua Torch]
[Deep Learning von Grund auf neu] Ich habe die Affine-Ebene implementiert
"Deep Learning from Grund" Memo zum Selbststudium (Nr. 19) Datenerweiterung
Anwendung von Deep Learning 2 von Grund auf neu Spam-Filter
Ich habe versucht, Dropout zu erklären