[PYTHON] Survivez à Noël avec CNN au niveau du personnage

Cet article est le 18e jour du Calendrier de l'Avent Retty. Hier, c'était @ YutaSakata Je veux Kotlin 1.1 pour les cadeaux de Noël.

Au fait, c'est bientôt Noël, mais avez-vous quelqu'un avec qui passer du temps? JE? Je le suis bien sûr. Cet enfant. mycat.jpg

Si vous êtes seul, vous aurez envie d'aller boire avec du saké, non? Il est également bon de boire humide dans un bon magasin. Mais que se passerait-il si le magasin dans lequel vous êtes entré dans cet esprit était une tanière remplie à l'arrière? Le temps gourmand solitaire est ruiné.

Utilisons la puissance du Deep Learning pour éviter à l'avance ces magasins dangereux.

Quoi préparer

keras peut être soit tensorflow ou theano Une bibliothèque pour le Deep Learning qui fonctionne comme un backend. C'est assez ennuyeux d'essayer de faire des choses compliquées, mais c'est assez facile à écrire pour la plupart des modèles. Je vais l'utiliser cette fois.

(Ajouté le 2017/3/1) J'utilise tensorflow pour le backend. Si c'est le cas, le code suivant ne fonctionnera pas en raison de la différence de gestion du canal dans CNN. Un petit correctif le résoudra. Voir la section des commentaires pour plus de détails.

Nous utilisons les avis Retty pour les avis de magasin. C'est un privilège de la personne intérieure que vous n'ayez pas à ramper.

Choses à faire

Faisons un classificateur avec Deep Learning parce que nous voulons classer les magasins en tanières remplies à l'arrière et en tanières non remplies à l'arrière. En tant que flux,

  1. Examen d'un ensemble de magasins à des fins de rencontre de Retty en tant qu'examen de magasin à des fins de rencontres
  2. Les avis sur les magasins autres que ceux ci-dessus sont considérés comme des avis sur les magasins de destination autres que les rencontres
  3. Créez un classificateur de bouche à oreille avec les deux évaluations ci-dessus en tant qu'enseignants.
  4. Tout le bouche-à-oreille du magasin est placé dans un classificateur, et l'endroit où le taux de bouche-à-oreille du magasin de destination est élevé est reconnu comme la grotte arrière.

C'est comme ça.

Il existe différentes manières de créer un classificateur, mais cette fois, nous utiliserons ** CNN au niveau des caractères **.

character-level CNN

Quand on parle de l'utilisation du Deep Learning pour le traitement du langage naturel, LSTM est souvent mentionné, mais cette fois je ne l'utiliserai pas. J'utilise CNN. Le CNN au niveau du caractère a de très belles fonctionnalités. Cela signifie ** pas besoin de fractionnement **. Le CNN au niveau des caractères fonctionne caractère par caractère, pas mot par mot, vous n'avez donc pas à diviser les phrases en mots. Les grandes lignes de la méthode sont les suivantes.

  1. Décomposez les phrases en un tableau de caractères
  2. Convertissez chaque caractère en une valeur UNICODE
  3. Créez un tableau de longueur fixe. (Coupé si long, 0 rembourrage si court)
  4. Faites du tableau UNICODE un tableau vectoriel avec keras.layers.embeddings.Embedding
  5. Multipliez la chaîne vectorielle par CNN
  6. Renvoie le résultat de la classification via la couche entièrement connectée

la mise en oeuvre

De là, je présenterai une mise en œuvre concrète.

Maquettisme

Tout d'abord, à partir du modèle CNN au niveau du personnage. C'est super facile.

  1. Recevoir une entrée dont la forme est (taille du lot, longueur de chaîne maximale)
  2. L'intégration convertit chaque caractère en dimension embed_size. Où se trouve la forme emb (taille du lot, longueur maximale de la chaîne, taille_embed).
  3. La forme reçue par Convolution2D est (taille du lot, longueur maximale de la chaîne, embed_size, nombre de canaux). Le canal peut être 1, donc ici nous allons ajouter un axe avec Reshape.
  4. ** (Important ici) ** Pliez la même entrée avec plusieurs tailles de noyau et combinez les résultats.
  5. Aplatissez le matériau combiné et appliquez-le au calque entièrement connecté pour le rendre unidimensionnel (0 est un bouche à oreille autre que le magasin de destination de date, 1 est le bouche à oreille du magasin de destination de date).
def create_model(embed_size=128, max_length=300, filter_sizes=(2, 3, 4, 5), filter_num=64):
    inp = Input(shape=(max_length,))
    emb = Embedding(0xffff, embed_size)(inp)
    emb_ex = Reshape((max_length, embed_size, 1))(emb)
    convs = []
    #Multiplier la convolution 2D
    for filter_size in filter_sizes:
        conv = Convolution2D(filter_num, filter_size, embed_size, activation="relu")(emb_ex)
        pool = MaxPooling2D(pool_size=(max_length - filter_size + 1, 1))(conv)
        convs.append(pool)
    convs_merged = merge(convs, mode='concat')
    reshape = Reshape((filter_num * len(filter_sizes),))(convs_merged)
    fc1 = Dense(64, activation="relu")(reshape)
    bn1 = BatchNormalization()(fc1)
    do1 = Dropout(0.5)(bn1)
    fc2 = Dense(1, activation='sigmoid')(do1)
    model = Model(input=inp, output=fc2)
    return model

J'écrirai un peu plus sur 4. Les spécifications des arguments de Convolution2D sont les suivantes.

keras.layers.convolutional.Convolution2D(nb_filter, nb_row, nb_col, init='glorot_uniform', activation='linear', weights=None, border_mode='valid', subsample=(1, 1), dim_ordering='default', W_regularizer=None, b_regularizer=None, activity_regularizer=None, W_constraint=None, b_constraint=None, bias=True)

Ici, 2,3,4,5 est spécifié pour nb_row et embed_size est spécifié pour nb_col. Cela signifie que vous appliquez un noyau de 2,3,4,5 caractères. C'est comme imiter 2 grammes, 3 grammes, 4 grammes, 5 grammes. En connectant ces résultats en un seul, vous pouvez utiliser les résultats de plusieurs n-grammes ensemble.

Lire les données

La partie lecture des données peut être rendue conviviale en utilisant un générateur, mais ce n'est pas une image et cela ne consomme pas beaucoup de mémoire, alors mettons tout en mémoire.

def load_data(filepath, targets, max_length=300, min_length=10):
    comments = []
    tmp_comments = []
    with open(filepath) as f:
        for l in f:
            #Identifiant de magasin séparé par tabulation pour chaque ligne,Hypothèse que le bouche à oreille est écrit
            restaurant_id, comment = l.split("\t", 1)
            restaurant_id = int(restaurant_id)
            #Convertir en UNICODE pour chaque caractère
            comment = [ord(x) for x in comment.strip().decode("utf-8")]
            #La partie longue est coupée
            comment = comment[:max_length]
            comment_len = len(comment)
            if comment_len < min_length:
                #Ne s'applique pas aux avis trop courts
                continue
            if comment_len < max_length:
                #Remplissez les parties manquantes avec 0 pour en faire une longueur fixe
                comment += ([0] * (max_length - comment_len))
            if restaurant_id not in targets:
                tmp_comments.append((0, comment))
            else:
                comments.append((1, comment))
    #Pour apprendre, il vaut mieux avoir le même nombre d'avis pour les destinations de rencontres et autres
    random.shuffle(tmp_comments)
    comments.extend(tmp_comments[:len(comments)])
    random.shuffle(comments)
    return comments

Apprentissage

Apprenons.

def train(inputs, targets, batch_size=100, epoch_count=100, max_length=300, model_filepath="model.h5", learning_rate=0.001):

    #Essayez de réduire petit à petit le taux d'apprentissage
    start = learning_rate
    stop = learning_rate * 0.01
    learning_rates = np.linspace(start, stop, epoch_count)

    #La modélisation
    model = create_model(max_length=max_length)
    optimizer = Adam(lr=learning_rate)
    model.compile(loss='binary_crossentropy',
                  optimizer=optimizer,
                  metrics=['accuracy'])

    #Apprentissage
    model.fit(inputs, targets,
              nb_epoch=epoch_count,
              batch_size=batch_size,
              verbose=1,
              validation_split=0.1,
              shuffle=True,
              callbacks=[
                  LearningRateScheduler(lambda epoch: learning_rates[epoch]),
              ])

    #Enregistrer le modèle
    model.save(model_filepath)


if __name__ == "__main__":
    comments = load_data(..., ...)

    input_values = []
    target_values = []
    for target_value, input_value in comments:
        input_values.append(input_value)
        target_values.append(target_value)
    input_values = np.array(input_values)
    target_values = np.array(target_values)
    train(input_values, target_values, epoch_count=50)

Lorsque je l'ai essayé, la précision était supérieure à 99% pour les données d'entraînement et inférieure à 80% pour les données de test.

La discrimination

Maintenant, quand vous arrivez ici, vous pouvez déterminer le bouche à oreille.

# -*- coding:utf-8 -*-

import numpy as np
from keras.models import load_model

def predict(comments, model_filepath="model.h5"):
    model = load_model(model_filepath)
    ret = model.predict(comments)
    return ret

if __name__ == "__main__":
    raw_comment = "Idéal pour un rendez-vous!"
    comment = [ord(x) for x in raw_comment.strip().decode("utf-8")]
    comment = comment[:300]
    if len(comment) < 10:
        exit("too short!!")
    if len(comment) < 300:
        comment += ([0] * (300 - len(comment)))
    ret = predict(np.array([comment]))
    predict_result = ret[0][0]
    print "Remplissage arrière: {}%".format(predict_result * 100)

Le caviste de poulet grillé de Musashi Koyama. C'était délicieux en général! Le prix n'est pas bon marché, mais tous les vins sont des vins Bio. Il a été dit que le cours Omakase est recommandé pour Yakitori, alors allez-y. Le service client du greffier est également le meilleur, alors allez-y.

Quand je l'ai essayé ci-dessus, c'était 99,9996066093%. Même s'il s'agit d'un yakitori, vous ne pouvez pas cacher l'odeur arrière à la dérive. À propos, cette critique est de notre fondateur Retty, Takeda. Vous ne seriez jamais allé seul dans un endroit aussi brillant. Avec qui es-tu allé?

Je l'ai choisi car il est directement relié à la station !! ✨ J'ai demandé du poulet grillé, de l'eau bouillie, etc., mais les oiseaux étaient dodus et délicieux !! L'image est que les gens qui ont fini de travailler sont pleins. Mais le prix était raisonnable et c'était assez bon?

Dans ce qui précède, il était de 2,91604362879e-07%. Même avec le même yakitori, si cela ressemble à une fleur, le remplissage arrière tombera à ce point. Votre cœur sera calme. Cet avis provient d'un employé de Retty, mais ne savons pas de qui il s'agit.

Une fois que vous avez fait cela, vous pouvez savoir s'il s'agit d'un repaire rempli à l'arrière en explorant toutes les critiques de la boutique et en prenant la moyenne des critiques remplies à l'arrière.

Résumé

Le Deep Learning est également une excellente technique pour protéger la tranquillité d'esprit. Le CNN au niveau du personnage est sorti au début de cette année, mais est sorti récemment [QRNN](http://metamind.io/research/new-neural-network-building-block-allows-faster-and -more-precise-text-Understanding /) et ainsi de suite, alors j'aimerais l'essayer.

Passez un bon Noël.

Recommended Posts

Survivez à Noël avec CNN au niveau du personnage
Implémentation CNN avec juste numpy
Essayez d'exécuter CNN avec ChainerRL
Créez facilement des CNN avec Keras
Utilisez Maxout + CNN avec Pylearn2
Décrypter le code QR avec CNN