[PYTHON] Überlebe Weihnachten mit CNN auf Charakterebene

Dieser Artikel ist der 18. Tag von Retty Advent Calendar. Gestern war @ YutaSakatas Ich möchte Kotlin 1.1 als Weihnachtsgeschenk.

Übrigens ist bald Weihnachten, aber haben Sie jemanden, mit dem Sie Zeit verbringen können? ICH? Ich bin natürlich Dieses Kind. mycat.jpg

Wenn du alleine bist, willst du mit Sake trinken gehen, oder? Es ist auch gut, in einem guten Geschäft feucht zu trinken. Aber was wäre, wenn das Geschäft, das Sie in diesem Sinne betreten haben, eine mit Hinterhöfen gefüllte Höhle wäre? Die einsame Gourmetzeit ist ruiniert.

Lassen Sie uns die Kraft des Deep Learning nutzen, um solche gefährlichen Geschäfte im Voraus zu vermeiden.

Was vorzubereiten?

keras kann entweder tensorflow oder theano sein. Eine Bibliothek für Deep Learning, die als Backend fungiert. Es ist ziemlich ärgerlich zu versuchen, komplizierte Dinge zu tun, aber für die meisten Modelle ist es ziemlich einfach zu schreiben. Ich werde dies dieses Mal verwenden.

(Hinzugefügt am 03.03.2017) Ich verwende Tensorflow für das Backend. Wenn dies der Fall ist, funktioniert der folgende Code aufgrund der unterschiedlichen Behandlung des Kanals in CNN nicht. Ein kleiner Fix wird es beheben. Weitere Informationen finden Sie im Kommentarbereich.

Wir verwenden Retty-Bewertungen für Shop-Bewertungen. Es ist ein Privileg der inneren Person, dass Sie nicht kriechen müssen.

Dinge die zu tun sind

Lassen Sie uns mit Deep Learning einen Klassifikator erstellen, weil wir Geschäfte in hintere und nicht hintere Höhlen unterteilen möchten. Als Fluss,

  1. Retty-Bewertungen von Geschäften, die für Dating-Zwecke eingerichtet wurden, werden als Store-Bewertungen für Dating-Zwecke verwendet
  2. Bewertungen von anderen Geschäften als den oben genannten gelten als andere Bewertungen von Zielgeschäften als Dating
  3. Machen Sie einen Mund-zu-Mund-Klassifikator mit den beiden oben genannten Bewertungen als Lehrer.
  4. Alle Mundpropaganda des Geschäfts wird sortiert, und der Ort mit der hohen Mundpropaganda des Datumszielgeschäfts wird als hintere Höhle erkannt.

Es ist wie es ist.

Es gibt verschiedene Möglichkeiten, einen Klassifikator zu erstellen, aber dieses Mal verwenden wir ** CNN auf Zeichenebene **.

character-level CNN

Wenn es um die Verwendung von Deep Learning für die Verarbeitung natürlicher Sprachen geht, wird LSTM oft erwähnt, aber dieses Mal werde ich es nicht verwenden. Ich benutze CNN. Das CNN auf Charakterebene hat sehr schöne Funktionen. Das bedeutet ** keine Notwendigkeit einer Fraktionierung **. Das CNN auf Zeichenebene arbeitet Zeichen für Zeichen, nicht Wort für Wort, sodass Sie Sätze nicht in Wörter aufteilen müssen. Der Umriss der Methode ist wie folgt.

  1. Teilen Sie Sätze in eine Reihe von Zeichen auf
  2. Konvertieren Sie jedes Zeichen in einen UNICODE-Wert
  3. Erstellen Sie ein Array mit fester Länge. (Bei Länge abschneiden, bei kurzer Polsterung 0)
  4. Machen Sie das UNICODE-Array zu einem Vektorarray mit keras.layers.embeddings.Embedding
  5. Multiplizieren Sie die Vektorzeichenfolge mit CNN
  6. Gibt das Klassifizierungsergebnis über die vollständig verbundene Ebene zurück

Implementierung

Von hier aus werde ich eine konkrete Implementierung vorstellen.

Modellbau

Zunächst aus dem CNN-Modell auf Zeichenebene. Es ist super einfach.

  1. Empfangen Sie eine Eingabe mit der Form (Stapelgröße, maximale Zeichenfolgenlänge).
  2. Durch das Einbetten wird jedes Zeichen in die Dimension embedded_size konvertiert. Wo die Emb-Form ist (Stapelgröße, maximale Stringlänge, embedded_size).
  3. Die von Convolution2D empfangene Form ist (Stapelgröße, maximale Zeichenfolgenlänge, embedded_size, Anzahl der Kanäle). Der Kanal kann 1 sein, daher fügen wir hier eine Achse mit Umformen hinzu.
  4. ** (hier wichtig) ** Falten Sie dieselbe Eingabe mit mehreren Kernelgrößen und kombinieren Sie die Ergebnisse.
  5. Glätten Sie das kombinierte Material und tragen Sie es auf die vollständig verbundene Ebene auf, um es eindimensional zu machen (0 ist eine andere Mundpropaganda als der Datumszielspeicher, 1 ist die Mundpropaganda des Datumszielspeichers).
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 = []
    #Faltung 2D multiplizieren
    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

Ich werde etwas mehr über 4 schreiben. Die Spezifikationen der Argumente von Convolution2D lauten wie folgt.

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)

Hier wird 2,3,4,5 für nb_row und embedded_size für nb_col angegeben. Hierbei wird im Grunde ein Kernel mit einer Größe von 2,3,4,5 Zeichen angewendet. Dies ist wie das Nachahmen von 2 Gramm, 3 Gramm, 4 Gramm, 5 Gramm. Indem Sie diese Ergebnisse zu einem verbinden, können Sie die Ergebnisse mehrerer n-Gramm zusammen verwenden.

Daten lesen

Der Datenleseteil kann mithilfe eines Generators speicherfreundlich gestaltet werden, aber es ist kein Bild und es verbraucht nicht so viel Speicher. Lassen Sie uns also alles in den Speicher stellen.

def load_data(filepath, targets, max_length=300, min_length=10):
    comments = []
    tmp_comments = []
    with open(filepath) as f:
        for l in f:
            #Speichern Sie die ID für jede Zeile durch Tabulatoren getrennt,Annahme, dass Mundpropaganda geschrieben ist
            restaurant_id, comment = l.split("\t", 1)
            restaurant_id = int(restaurant_id)
            #Für jedes Zeichen in UNICODE konvertieren
            comment = [ord(x) for x in comment.strip().decode("utf-8")]
            #Der lange Teil ist abgeschnitten
            comment = comment[:max_length]
            comment_len = len(comment)
            if comment_len < min_length:
                #Zu kurze Bewertungen sind nicht zulässig
                continue
            if comment_len < max_length:
                #Füllen Sie die fehlenden Teile mit 0 aus, um eine feste Länge zu erhalten
                comment += ([0] * (max_length - comment_len))
            if restaurant_id not in targets:
                tmp_comments.append((0, comment))
            else:
                comments.append((1, comment))
    #Zum Lernen ist es besser, die gleiche Anzahl von Bewertungen für Dating-Ziele und andere zu haben
    random.shuffle(tmp_comments)
    comments.extend(tmp_comments[:len(comments)])
    random.shuffle(comments)
    return comments

Lernen

Lass uns lernen.

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

    #Versuchen Sie, die Lernrate nach und nach zu reduzieren
    start = learning_rate
    stop = learning_rate * 0.01
    learning_rates = np.linspace(start, stop, epoch_count)

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

    #Lernen
    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]),
              ])

    #Modell speichern
    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)

Als ich es ausprobierte, lag die Genauigkeit für die Trainingsdaten bei über 99% und für die Testdaten bei weniger als 80%.

Diskriminierung

Wenn Sie jetzt hier sind, können Sie die Mundpropaganda bestimmen.

# -*- 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 = "Großartig für ein Date!"
    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 "Hinterfüllung: {}%".format(predict_result * 100)

Musashi Koyamas gegrillter Hühnerweinladen. Es war im Allgemeinen sehr lecker! Der Preis ist nicht billig, aber alle Weine sind Bio-Weine. Es wurde gesagt, dass der Omakase-Kurs für Yakitori empfohlen wird, also gehen Sie dorthin. Der Kundenservice des Angestellten ist auch der beste, also gehen Sie bitte.

Als ich es oben versuchte, war es 99,9996066093%. Selbst wenn es ein Yakitori ist, können Sie den treibenden hinteren Geruch nicht verbergen. Diese Bewertung stammt übrigens von unserer Retty-Gründerin Takeda. Du wärst niemals alleine an einen so glitzernden Ort gegangen. Mit wem bist du gegangen?

Ich habe es gewählt, weil es direkt mit dem Bahnhof verbunden ist !! ✨ Ich habe nach gegrilltem Hühnchen, gekochtem Wasser usw. gefragt, aber die Vögel waren prall und lecker !! Das Bild ist, dass die Leute, die die Arbeit beendet haben, voll sind. Aber der Preis war angemessen und es war ziemlich gut ♫

Oben waren es 2,91604362879e-07%. Selbst mit den gleichen Yakitori fällt die hintere Füllung bis zu diesem Punkt ab, wenn sie sich wie eine Blume anfühlt. Dein Herz wird ruhig sein. Diese Bewertung stammt von einem Retty-Mitarbeiter, aber wir wissen nicht, wer es ist.

Sobald Sie dies getan haben, können Sie herausfinden, ob es sich um eine von hinten gefüllte Höhle handelt, indem Sie alle Bewertungen des Shops durchsuchen und den Durchschnitt der von hinten gefüllten Bewertungen ermitteln.

Zusammenfassung

Deep Learning ist auch eine hervorragende Technik, um den Seelenfrieden zu schützen. Das CNN auf Charakterebene erschien Anfang dieses Jahres, kam aber kürzlich [QRNN] heraus (http://metamind.io/research/new-neural-network-building-block-allows-faster-and -mehr-genaue-Text-Verständnis /) und so weiter, also würde ich es gerne versuchen.

Schöne Weihnachten.

Recommended Posts

Überlebe Weihnachten mit CNN auf Charakterebene
CNN-Implementierung mit nur Numpy
Versuchen Sie, CNN mit ChainerRL auszuführen
Erstellen Sie einfach CNNs mit Keras
Verwenden Sie Maxout + CNN mit Pylearn2
QR-Code mit CNN entschlüsseln