[PYTHON] Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 2

introduction

Une note que j'ai trébuché au chapitre 2 de "Deep Learning from scratch ❷ --- Natural language processing" est.

L'environnement d'exécution est macOS Catalina + Anaconda 2019.10, et la version Python est 3.7.4. Pour plus de détails, reportez-vous au Chapitre 1 de ce mémo.

Chapitre 2 Traitement du langage naturel et expression distribuée des mots

Ce chapitre commence l'histoire du traitement du langage naturel.

2.1 Traitement du langage naturel

On dit que le traitement du langage naturel est «une technologie (domaine) pour faire comprendre à un ordinateur nos mots», mais quand j'entends «faire comprendre à un ordinateur», l'image s'agrandit et j'imagine quelque chose comme Doraemon. Donc, je pense que l'expression "rendre le traitement par un ordinateur" est bonne.

Les données numériques peuvent être facilement traitées en additionnant, en calculant la moyenne et en comparant, en visualisant avec des graphiques, en prédisant l'avenir avec des données de séries chronologiques, etc. Vous pouvez également utiliser l'apprentissage en profondeur appris dans le volume précédent. Mais ce n'est pas le cas avec les données en langage naturel. C'est une technologie pour rendre cela possible.

De plus, l'abréviation PNL est la même que Programmation Neuro-Linguistique, et lorsque vous recherchez sur Google avec "PNL", l'histoire de la programmation en langage neuronal sort en premier. Je pense que cela peut être déroutant parce que les domaines sont différents, mais cela peut être lié pendant un moment quand cela sort en étudiant l'apprentissage profond. Veuillez noter que vous pensez peut-être que.

2.2 Sisolus

Je ne parlerai que l'anglais dans le livre, je ferai donc une note du système japonais.

--WordNet a une version japonaise de WordNet japonais. Cependant, il n'est pas confirmé s'il peut être utilisé avec NLTK comme dans "Annexe B Exécution de WordNet" dans le livre. ――Bien que les données disponibles du programme ne soient pas ouvertes au public, il semble que le système construit par l'Agence nationale de recherche et de développement pour la science et la technologie (JST) soit également célèbre. Il existe un site de recherche de termes appelé JST Sisorus map, et lorsque vous recherchez un terme, figure 2-2 du livre Un graphique comme celui-ci s'affiche. On utilise non seulement le cissolus mais aussi les informations statistiques de la fréquence de cooccurrence dans la littérature.Par exemple, si vous recherchez "automobile", un magnifique graphique d'une échelle qui ne peut être vue sans défilement est affiché. Vous pouvez suivre les termes en double-cliquant.

2.3 Approche basée sur le dénombrement

J'ai étudié la méthode basée sur le décompte à Language Processing 100 Knock 2015 il y a environ 3 ans, je vais donc l'examiner. C'est devenu une forme à faire. Chapitre 9: Méthode de l'espace vectoriel (I) de ces 100 coups est la «méthode basée sur le comptage 2,3» de ce livre. "Et" 2.4 Amélioration de la méthode basée sur le comptage ", il n'y avait donc pas d'obstacle particulier autre que la décomposition en valeur singulière après cela.

2.4 Amélioration de la méthode basée sur le comptage

La figure 2-8 dans "2.4.2 Réduction de dimension" peut être un peu déroutante. Si vous n'avez pas obtenu l'image dans cette figure, @aya_taka [Terme d'apprentissage automatique "Réduction de dimensionnalité" qui peut être compris en 30 minutes](https: // Je pense que l'exemple de la taille et du poids au début de qiita.com/aya_taka/items/4d3996b3f15aa712a54f) devrait être facile à comprendre.

Je suis tombé sur la décomposition de singularité (SVD). En fait, c'est ma troisième étude (Machine Learning, qui était un cours en ligne de Coursera que j'ai suivi il y a environ 4 ans, et la [Langue] mentionnée ci-dessus. Traitement de 100 coups 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)), je peux comprendre l'image, mais je ne comprends toujours pas le contenu du calcul. Je ne comprends pas le sens de l'explication juste en cherchant un peu sur Google, et il semble que je doive réétudier exactement la procession. NumPy (et le prochain scikit-learn) le calculera pour moi, alors j'en suis reconnaissant et j'ai décidé de passer à autre chose: suer:

Le corpus PTB anglais est utilisé comme un grand corpus dans "2.4.4 PTB Dataset", mais j'adore le japonais et j'ai décidé de l'essayer en japonais. Contrairement à l'anglais, le japonais n'a pas de blancs aux limites des mots, il est donc nécessaire de traiter le fractionnement avec des blancs, mais cette fois c'est fait Texte de fractionnement d'Aozora Bunko / segavvy / wakatigaki-aozorabunko) est utilisé.

Dans le livre, le corpus PTB est utilisé dans dataset / ptb.py, mais je l'ai modifié pour faire dataset / aozorabunko.py. Ci-dessous le code source, mais avant cela, il y a quelques notes.

――Les données cibles ne sont que 13 œuvres sélectionnées par 3 auteurs et concaténées, il y a donc un biais considérable. Veuillez noter que ce n'est pas quelque chose qui peut être utilisé comme référence pour la méthode, mais simplement "je l'ai essayé". --Dans ptb.load_data (), vous pouvez sélectionner train'`, test', `` valid' comme arguments, mais seul'train' utilisé cette fois est encore supporté. Je pense apporter une œuvre du même auteur que je n'ai pas utilisée cette fois.

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

#★ Cette URL est l'URL de téléchargement des diverses œuvres d'Aozora Bunko qui ont été téléchargées sur GitHub.
#Pour plus de détails https://github.com/segavvy/wakatigaki-Veuillez vous référer à Aozora Bunko.
url_base = 'https://github.com/segavvy/wakatigaki-aozorabunko/raw/master/'
key_file = {
    'train': '20200516merge.txt',
    'test': '',  #★ Je ne l'ai pas préparé car je ne l'ai pas encore utilisé
    'valid': ''  #★ Je ne l'ai pas préparé car je ne l'ai pas encore utilisé
}
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')


#★ La division du texte étant utilisée à deux endroits, elle est transformée en fonction. La mise en œuvre est 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:Type de données:'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)

Mettez ce fichier dans le répertoire dataset, importez ʻaozorabunko.py au lieu de ptb.py, et ʻaozorabunko.load_data () au lieu de ptb.load_data () , Vous pouvez utiliser les données d'Aozora Bunko au lieu du corpus PTB.

De plus, bien que l'explication de "2.4.5 Evaluation avec le jeu de données PTB" indique que "le module sklearn doit être installé", ce sklearn est scikit-learn. Une bibliothèque d'apprentissage automatique Python appelée /), qui est incluse avec Anaconda. Par conséquent, si Anaconda est installé selon la procédure du chapitre 1 du volume précédent, vous pouvez l'utiliser sans rien faire.

En outre, le calcul du PPMI prend beaucoup de temps. Cela prend plusieurs heures dans mon environnement, donc je l'ai changé pour le mettre en cache dans un fichier une fois qu'il a été calculé. Aussi, je veux essayer diverses requêtes, donc je rend possible la saisie en standard.

Ci-dessous se trouve le ch02 / count_method_big.py modifié. J'ai mis «★» dans la partie principale du remodelage.

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  #★ Changé pour utiliser le corpus d'Aozora Bunko
import os   #★ Ajouté pour mettre en cache les résultats des calculs PPMI
import pickle   #★ Ajouté pour mettre en cache les résultats des calculs PPMI

window_size = 2
wordvec_size = 100

corpus, word_to_id, id_to_word = aozorabunko.load_data('train')  #★ Changer de corpus
vocab_size = len(word_to_id)
print('counting  co-occurrence ...')
C = create_co_matrix(corpus, vocab_size, window_size)

#★ Le calcul PPMI prend du temps, alors changez pour mettre en cache le résultat précédent et réutilisez si C est le même
print('calculating PPMI ...')
W = None
ppmi_path = os.path.dirname(os.path.abspath(__file__)) + '/' + 'ppmi.pkl'
if os.path.exists(ppmi_path):
    #★ Lire le cache
    with open(ppmi_path, 'rb') as f:
        cache_C, cache_W = pickle.load(f)
    if np.array_equal(cache_C, C):
        W = cache_W  #Réutiliser car le contenu de C est le même
if W is None:
    W = ppmi(C, verbose=True)
    with open(ppmi_path, 'wb') as f:
        pickle.dump((C, W), f)  #Enregistrer comme cache

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]

#★ Changer la requête en entrée standard
while True:
    query = input('\nquery? ')
    if not query:
        break
    most_similar(query, word_to_id, id_to_word, word_vecs, top=5)

Voici les résultats d'essayer certaines requêtes. Tout d'abord, de la traduction japonaise de la requête dans le livre.

[query]tu
femme: 0.6728986501693726
femme: 0.6299399137496948
 K: 0.6205178499221802
père: 0.5986840128898621
je: 0.5941839814186096

[query]Année
Anti: 0.8162745237350464
cent: 0.8051895499229431
Minutes: 0.7906433939933777
Huit: 0.7857747077941895
Cercle: 0.7682645320892334
 
[query]voiture
porte: 0.6294019222259521
Porte: 0.6016885638237
Voiture: 0.5859153270721436
porte: 0.5726617574691772
rideau: 0.5608214139938354

Toyota est introuvable

"Vous" vous sentez bien. «Année» semble avoir un synonyme comme unité. «Car» n'est pas bon car il apparaît rarement dans les œuvres utilisées pour le corpus. «Toyota» n'existe pas en premier lieu, il ne peut donc pas être aidé.

Voici quelques autres choses que j'ai essayées. La première moitié est relativement bonne et la seconde moitié n'est pas bonne.

[query]Matin
nuit: 0.7267987132072449
Autour: 0.660172164440155
Le midi: 0.6085118055343628
soirée: 0.6021789908409119
La prochaine fois: 0.6002975106239319
 
[query]école
Tokyo: 0.6504884958267212
Plus haute: 0.6290650367736816
Lycée: 0.5801640748977661
Université: 0.5742003917694092
Embarquement: 0.5358142852783203
 
[query]Zashiki
Étude: 0.6603355407714844
Côté Sou: 0.6362787485122681
Chambre: 0.6142982244491577
chambre: 0.6024710536003113
cuisine: 0.6014574766159058
 
[query]kimono
Le crâne: 0.5216895937919617
noir: 0.5200990438461304
vêtements: 0.5096032619476318
vêtements: 0.48781922459602356
chapeau: 0.4869200587272644
 
[query]je
Maître: 0.6372452974319458
Supplémentaire: 0.5826579332351685
Kaneda: 0.4684762954711914
ils: 0.4676626920700073
Labyrinthe: 0.4615904688835144
 
[query]Criminel
Fantôme: 0.6609077453613281
Voleurs: 0.6374931931495667
Membre: 0.6308270692825317
cette personne: 0.6046633720397949
Se plonger: 0.5931873917579651
 
[query]commande
Parler: 0.6200630068778992
Consultation: 0.5290789604187012
Occupé: 0.5178924202919006
La gentillesse: 0.5033778548240662
Conférence: 0.4894390106201172
 
[query]Pistolet sans arme
Obsolète: 0.7266454696655273
Démodé: 0.6771457195281982
vu: 0.6735808849334717
Souffle du nez: 0.6516652703285217
ignorance: 0.650424063205719
 
[query]Chat
Amen: 0.6659030318260193
Nobujo: 0.5759447813034058
Sumi: 0.5374482870101929
Statut: 0.5352671146392822
d'habitude: 0.5205280780792236
 
[query]Alcool
livre: 0.5834404230117798
thé: 0.469807893037796
Du repos: 0.4605821967124939
Manger: 0.44864168763160706
barre: 0.4349029064178467
 
[query]cuisine
Écheveau: 0.5380040407180786
Signe: 0.5214874744415283
original: 0.5175281763076782
Loi: 0.5082278847694397
Boutique: 0.5001937747001648

À propos, les auteurs des données cibles sont Soseki Natsume, Kenji Miyazawa et Ranpo Edogawa. Le corpus est un peu trop biaisé, mais c'est intéressant, alors si vous le souhaitez, essayez-le.

2.5 Résumé

Il y avait beaucoup de critiques, donc j'ai pu le lire relativement facilement. Le prochain chapitre sera probablement en production.

C'est tout pour ce chapitre. Si vous avez des erreurs, je vous serais reconnaissant de bien vouloir les signaler.

Recommended Posts

Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 5
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 2
Un amateur a trébuché dans le Deep Learning ❷ fait de zéro Note: Chapitre 1
Un amateur a trébuché dans le Deep Learning ❷ fait à partir de zéro Note: Chapitre 4
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 1
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 3
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 7
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 5
Un amateur a trébuché dans le Deep Learning à partir de zéro.
Un amateur a trébuché dans le Deep Learning à partir de zéro Note: Chapitre 2
[Mémo d'apprentissage] Le Deep Learning fait de zéro [Chapitre 7]
Deep learning / Deep learning made from scratch Chapitre 6 Mémo
[Mémo d'apprentissage] Deep Learning fait de zéro [Chapitre 5]
[Mémo d'apprentissage] Le Deep Learning fait de zéro [Chapitre 6]
Deep learning / Deep learning made from scratch Chapitre 7 Mémo
[Mémo d'apprentissage] Deep Learning fait de zéro [~ Chapitre 4]
Apprentissage profond à partir de zéro
Deep Learning from scratch ① Chapitre 6 "Techniques liées à l'apprentissage"
Deep Learning from scratch Chapter 2 Perceptron (lecture du mémo)
Apprentissage profond à partir de zéro 1 à 3 chapitres
Deep learning / Deep learning from scratch 2 Chapitre 4 Mémo
Deep learning / Deep learning made from scratch Chapitre 3 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 5 Mémo
Créez un environnement pour "Deep Learning from scratch" avec Docker
Apprentissage profond à partir de zéro (calcul des coûts)
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 7 Mémo
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 8 Mémo
Deep learning / Deep learning made from scratch Chapitre 5 Mémo
Deep learning / Deep learning made from scratch Chapitre 4 Mémo
Deep learning / Deep learning from scratch 2 Chapitre 3 Mémo
Mémo d'apprentissage profond créé à partir de zéro
Deep Learning / Deep Learning à partir de Zero 2 Chapitre 6 Mémo
Écrivez vos impressions sur l'édition du framework Deep Learning 3 créée à partir de zéro
Apprentissage profond à partir de zéro (propagation vers l'avant)
Apprentissage profond / Apprentissage profond à partir de zéro 2-Essayez de déplacer GRU
"Deep Learning from scratch" avec Haskell (inachevé)
[Windows 10] Construction de l'environnement "Deep Learning from scratch"
Enregistrement d'apprentissage de la lecture "Deep Learning from scratch"
[Deep Learning from scratch] À propos de l'optimisation des hyper paramètres
Mémo d'auto-apprentissage "Deep Learning from scratch" (partie 12) Deep learning
Python vs Ruby «Deep Learning from scratch» Chapitre 2 Circuit logique par Perceptron
Python vs Ruby "Deep Learning from scratch" Chapitre 4 Implémentation de la fonction de perte
Mémo d'auto-apprentissage "Deep Learning from scratch" (glossaire illisible)
"Deep Learning from scratch" Mémo d'auto-apprentissage (n ° 9) Classe MultiLayerNet
Un amateur a essayé le Deep Learning avec Caffe (Introduction)
GitHub du bon livre "Deep Learning from scratch"
Un amateur a essayé le Deep Learning en utilisant Caffe (Practice)
[Mémo d'apprentissage] Apprentissage profond à partir de zéro ~ Mise en œuvre de l'abandon ~
Un amateur a essayé le Deep Learning avec Caffe (Vue d'ensemble)
Résumé Python vs Ruby "Deep Learning from scratch"
Mémo d'auto-apprentissage «Deep Learning from scratch» (10) Classe MultiLayerNet
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 11) CNN
Deep Learning from scratch La théorie et la mise en œuvre de l'apprentissage profond appris avec Python Chapitre 3
Version Lua Deep Learning from scratch Part 5.5 [Rendre les fichiers pkl disponibles dans Lua Torch]
[Deep Learning from scratch] J'ai implémenté la couche Affine
Mémo d'auto-apprentissage «Deep Learning from scratch» (n ° 19) Augmentation des données
Application de Deep Learning 2 à partir de zéro Filtre anti-spam
[Deep Learning from scratch] J'ai essayé d'expliquer le décrochage