[PYTHON] Ich habe versucht, einen automatischen Charakterdialoggenerator für die Markov-Kette im N-Stock zu erstellen

Einführung

Normalerweise studiere ich Finanztexte als Studium der Verarbeitung natürlicher Sprache. Da der in der Forschung behandelte Inhalt der Inhalt gemeinsamer Forschung ist und nicht nach außen veröffentlicht werden kann und der Inhalt, der veröffentlicht werden kann, durch Präsentation auf einer Konferenz oder Einreichen eines Papiers zusammengefasst wird, war es nicht erforderlich, ihn als Artikel umzuschreiben, sodass es sich um einen neuen Artikel handelt Ich beschloss zu tun, was ich konnte. In diesem Artikel wird die Animation "[Kemono Friends](https://ja.wikipedia.org/wiki/%E3%81%91%E3%82%82%E3%81%AE%E3%83%95%E3" % 83% AC% E3% 83% B3% E3% 82% BA_ (% E3% 82% A2% E3% 83% 8B% E3% 83% A1))) So generieren Sie automatisch Servallinien in der Markov-Kette Ich möchte vorstellen. image.png (Stabiler Illustrator, weil ich das Copyright nicht kenne)

Wie für den Fluss des Artikels

  1. Datenerfassung
  2. Über die Markov-Kette im 9. Stock
  3. Implementierung
  4. Überlegung
  5. Zusammenfassung Es wird.

Erfassung von Textdaten von Kemono Friends

Für die Dialogdaten verwende ich die auf GitHub von akahuku. Ich tat. Ich bin wirklich dankbar für diese Art von Daten. Da diese Textdaten mit einem Etikett versehen sind, das angibt, welches Zeichen spricht, konnten nur die Servalzeilen extrahiert werden. Ursprünglich suchte ich nach diesen Daten, als ich nach Daten suchte, die für die Klassifizierung verwendet werden konnten, weil ich die Implementierung der Satzklassifizierung durch Pytorch untersuchen wollte, anstatt automatisch Zeilen zu generieren (der Artikel über die Zeilenklassifizierung ist ein anderer). Ich werde es bei dieser Gelegenheit schreiben). Der Grund für die Verwendung der automatischen Erzeugung von Servallinien liegt übrigens einfach darin, dass die Linien am häufigsten waren (812 lange Linien und kurze Linien zusammen). Eigentlich wollte ich es mit Tsuchinoko und Dr. schaffen, aber leider war die Anzahl der Daten überwiegend unzureichend. Eigentlich denke ich, dass ich eine gute Datenverarbeitung schreiben sollte, aber ich werde sie weglassen, weil der Artikel unnötig lang sein wird, aber ich habe keine spezielle Verarbeitung durchgeführt, außer alle Zeichen in voller Breite auszurichten. Die folgenden Daten wurden aus den gesammelten Daten extrahiert.

Ihr werdet das beim Arzt finden.
Dr. Es ist notwendig, wenn Sie an Land laufen. Benutze deinen Kopf.
Dr. Ähnliche Busse wurden auf mehreren Inseln beobachtet. Suchen Sie zuerst danach.
Doktor, ich kann nicht anders. Es gibt so etwas wie einen Bus im Vergnügungspark.
Dr. Das ist richtig für euch, das ist gut.
:
Serval Immerhin dachte ich, ich sollte ihm ein bisschen mehr folgen.
Serval Lass uns Freunde sein!
Serval Wow! Boss! ??
Serval redete! ??

Über Nth Stock Markov Kette

In Bezug auf die Markov-Kette und -Implementierung war @ k-jimons Artikel [Python] Satzgenerierung mit Markov-Kette im neunten Stock sehr hilfreich. Es war. Um ehrlich zu sein, habe ich nicht das Bedürfnis, in diesem Artikel von Grund auf neu zu schreiben. Eine intuitive und leicht verständliche Erklärung zur Satzgenerierung durch die Markov-Kette ist ["Satzgenerierung durch die Markov-Kette"](https://omedstu.jimdofree.com/2018/05/06/%E3%83%9E%E3%83 % AB% E3% 82% B3% E3% 83% 95% E9% 80% A3% E9% 8E% 96% E3% 81% AB% E3% 82% 88% E3% 82% 8B% E6% 96% 87 Es ist in% E6% 9B% B8% E7% 94% 9F% E6% 88% 90 /) geschrieben. Vorerst werde ich es in diesem Artikel kurz vorstellen, damit der verlinkte Artikel verschwinden kann.

Markov-Kette

Vorerst [Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%AB%E3%82%B3%E3%83%95%E9%80%A3%E9% Von 8E% 96).

Die Markov-Kette (Markov-Kette) ist eine Art stochastischer Prozess, bei dem die möglichen Zustände diskret (endlich oder zählbar) sind (diskreter Zustand Markov-Prozess). Insbesondere bezieht es sich oft auf diskrete Zeiten (Zeit wird durch Indizes dargestellt) (es gibt auch einen zeitkontinuierlichen Markov-Prozess, der zeitlich kontinuierlich ist). In der Markov-Kette wird das zukünftige Verhalten nur durch den aktuellen Wert bestimmt und ist für das vergangene Verhalten irrelevant (Markov-Eigenschaft). In Bezug auf die Zustandsänderung (Übergang oder Übergang), die zu jedem Zeitpunkt auftritt, ist die Markov-Kette eine Reihe, bei der die Übergangswahrscheinlichkeit nicht vom vergangenen Zustand, sondern nur vom aktuellen Zustand abhängt. Es wird auf verschiedene Bereiche als besonders wichtiger stochastischer Prozess angewendet.

Einfach ausgedrückt wird geschrieben, dass die Wahrscheinlichkeit, der nächste Zustand zu werden, unter Berücksichtigung des aktuellen Zustands bestimmt wird und die Ergebnisse der Vergangenheit die Wahrscheinlichkeit nicht beeinflussen. In Bezug auf das Wetter ist es wahrscheinlich, dass es morgen sonnig ist, wenn es heute sonnig ist, und wenn es heute regnet, wird es morgen bewölkt oder regnerisch sein. Nach der Markov-Naturannahme hat die Markov-Kette bei sonnigem Wetter keinen Einfluss darauf, ob das Wetter von gestern sonnig oder regnerisch ist.

Betrachten Sie bei der Satzgenerierung die folgenden drei Sätze als Beispiel. "Serval jagt gern" "Ich kann gut über Taschen nachdenken" "Dr. kann nicht gut kochen" Da wir diesmal nicht im Detail darauf eingehen werden, werden wir eine ausführliche Erklärung weglassen. Da der Satz jedoch in Worteinheiten unterteilt werden kann, kann die folgende Abbildung erstellt werden. image.png Dies ist ein Diagramm, das den Zustandsübergang zeigt, und Sie können einen Satz bilden, indem Sie von links nach rechts wechseln. Zum Beispiel durch Übergang wie folgt "** Bag ** ist ** nicht gut in der Jagd **" Sie können Sätze wie erstellen. image.png Auf diese Weise können durch Akkumulieren der Darstellung der Wörter in den Lerndaten verschiedene Sätze generiert werden.

Markov-Kette im 9. Stock

Die Markov-Kette N-Ordnung sagt den nächsten Zustand voraus, indem sie die N Zustände aus dem Zustand vor N-1 zum aktuellen Zustand hinzufügt. Wenn N = 1 ist, entspricht dies einer normalen Markov-Kette. Wenn möglich, können Sie im vorherigen Wetterbeispiel intuitiv verstehen, dass die Vorhersage von morgen besser ist, wenn auch das Wetter des vorherigen Tages berücksichtigt wird. Wenn es weiterhin sonnig und sonnig ist, besteht eine hohe Wahrscheinlichkeit, dass es morgen gut wird, und wenn es regnerisch und sonnig ist, ist die Wahrscheinlichkeit, dass es morgen gut wird, geringer als die von sonnig und sonnig. Die Satzgenerierung ähnelt eher dem generierten Text, wenn Sie berücksichtigen, was vor einiger Zeit angezeigt wurde. Zum Beispiel zusätzlich zum vorherigen Satz, "Curry ist am zweiten Tag lecker" Wenn es einen Satz wie diesen gibt und N = 1, "Curry ist gut in der Jagd" Wird generiert. Je größer N ist, desto schwieriger ist es jedoch, neue Sätze zu erzeugen. Ich wünschte ich hätte mehr Daten ...

Implementierung

Dies ist die lang erwartete Implementierung. In dieser Markov-Kette N-Ordnung wird das Modell jedoch nicht in Worteinheiten, sondern in Zeicheneinheiten erstellt. Da es sich bei den Daten diesmal um Dialogdaten handelt, handelt es sich um eine gesprochene Sprache, es gibt viele Hiragana und Katakana aufgrund der Eigenschaften der Arbeit und es gibt viele eindeutige Ausdrücke (Japari Park usw.), so dass es schwierig ist, die Morphologie mit MeCab usw. zu analysieren. Da die Anzahl der Daten gering ist, haben wir Sätze in Zeicheneinheiten generiert. Zum Beispiel "Dr. kann nicht gut kochen" Ist "Haku", "Shi", "Ha", "Fee", "Ri", "Ga", "Bitter", "Hand" Erstellen Sie ein Zustandsübergangsmodell separat wie folgt. Wir werden auch untersuchen, wie es sich abhängig von der Größe von N ändert. (~~ Es ist nicht mühsam, MeCab vorzustellen oder zu schreiben ~~)

Umgebung

・ Python3.7

Vorausgesetztes Wissen

Zur Modellerstellung ["Jetzt", "Tag"] → ["ist", "auch", ",", "ist", "ist", "ist", "ist", ",", "ist"] Es ist notwendig, eine solche Datenstruktur zu erstellen. Dies ist ein Beispiel, wenn N = 2 ist und wenn die Zeichen "jetzt" und "Tag" erscheinen, muss akkumuliert werden, welches Zeichen als nächstes kommt (beim Generieren von Sätzen). , Da "Zeichen" zufällig aus diesen ausgewählt werden, ist es wahrscheinlicher, dass die doppelteren ausgewählt werden. Es gibt auch eine Möglichkeit, eine Datenstruktur zu erstellen, um die Anzahl der Daten zu verringern. Dieses Mal erstellen wir jedoch einfach eine solche Datenstruktur.

Da diese Daten eine Liste (["ist", ...]) haben, die dem Schlüssel entspricht (["jetzt", "Tag"] oben)), verwenden Sie Pythons Diktat und Liste. Ich werde. Verwenden Sie auch deque, um den Schlüssel zu erstellen. Es kann im Sammlungsmodul verwendet werden, das eine Standardbibliothek von Python ist, und es ist auch in [Python] Satzgenerierung mit Markov-Kette N-ter Ordnung geschrieben, aber diese Implementierung Es ist praktisch in. Um kurz zu erklären, was sich von der Liste unterscheidet: Wenn Sie zuerst die Länge angeben, wenn Sie sie mit Anhängen hinzufügen, wenn die angegebene Länge überschritten wird, kann der Wert am Anfang herausgeschoben werden. Ich kann es schaffen Mit anderen Worten, wenn ["jetzt", "Tag"] in deque enthalten ist und "ha" am Ende mit Anhängen hinzugefügt wird, wird ["Tag", "wird"](sehr praktisch). Sie können es so implementieren.

python


from collections import deque
n_size = 2
queue = deque([], n_size)

Da deque jedoch nicht wie für key verwendet werden kann, wird es in den Tupeltyp konvertiert.

python


key = tuple(queue)

Dies sollte alles sein, was Sie für die erforderlichen Kenntnisse benötigen.

Daten lesen

Die extrahierten Daten sind Namenszeile Da es in "kemono_friends.txt" mit einem leeren Trennzeichen gespeichert wird, wird es zeilenweise gelesen, die Zeilenumbrüche werden entfernt und durch ein Leerzeichen geteilt. Und der mit dem Namen "Serval" wird zu text_list hinzugefügt.

data_load.py


text_list = []
with open("./data/kemono_friends.txt") as data:
    for line in data:
        char, text = line.rstrip('\n').split(" ")
        if char == "Serval":
            text_list.append(text)

Modellieren

Erstellen Sie ein Modell. "BOS" ist ein Tag, das den Anfang eines Satzes angibt und eine Abkürzung für Satzanfang ist, und "EOS" ist ein Tag, das das Ende eines Satzes angibt und eine Abkürzung für das Ende eines Satzes ist. n_size ist N der Markov-Kette N-ter Ordnung.

mk_model.py


from collections import deque
import pickle
n_size = 4
def mk_model(text_list):
    model = {}
    for text in text_list:
        queue = deque([], n_size)
        queue.append("[BOS]")
        for i in range(0, len(text)):
            key = tuple(queue)
            if key not in model:
                model[key] = []
            model[key].append(text[i])
            queue.append(text[i])
        key = tuple(queue)
        if key not in model:
            model[key] = []
        model[key].append("[EOS]")
    return model

"""
Daten hier_load.Kopieren Sie py
"""

Automatische Dialoggenerierung

Das Programm, das mithilfe des erstellten Modells automatisch Sätze generiert, fügt dem vorherigen Programm den folgenden Code hinzu.

mk_serihu.py


import random
def mk_serihu():
    value_list = []
    queue = deque([], n_size)
    queue.append("[BOS]")
    key = tuple(queue)
    while(True):
        key = tuple(queue)
        value = random.choice(model[key])
        if value == "[EOS]":
            break
        value_list.append(value)
        queue.append(value)
    return value_list
#Derzeit werden automatisch 10 Zeilen generiert
for i in range(0, 10):
    serihu = ''.join(mk_serihu())
    print(serihu)

Als Programm wird "BOS" zuerst zum Schlüssel, und Zeichen werden zufällig aus dem Modell generiert. Danach ändert sich der Schlüssel allmählich, Zeichen werden nacheinander generiert, und wenn "EOS" angezeigt wird, endet die Generierung. Die Ausgabe sieht so aus.

Aber machst du so viel weiter?
Es ist mein erstes Mal. Du hast es geschafft.
Ah. Es ist kalt.
Tschüss.
Jep. Hey, Braunbär. Ich werde gehen.
Sagst du Idol und fängst an zu tanzen und zu singen?
Warte warte.
Auf keinen Fall.
Ich habe dir den Namen früher gegeben. Wofür.
I frage mich, was.

Es fühlt sich ziemlich gut an! Übrigens ist es schwierig, jedes Mal ein Modell zu generieren, wenn die Anzahl der Daten groß ist. Daher ist es praktisch, es als Binärdatei mit pickle zu speichern und sofort aufzurufen. Das Programm, das es als model.binaryfile speichert und aufruft, lautet wie folgt. (Wenn Sie die Datenverarbeitung überspringen und vorerst die automatische Generierung ausführen möchten, wenn Sie DM von Twitter usw. erhalten, übergeben Sie model.binaryfile.)

mk_serihu.py


from collections import deque
import random
import pickle
n_size = 4
f = open("data/model.binaryfile",'rb')
model = pickle.load(f)

def mk_serihu():
    value_list = []
    queue = deque([], n_size)
    queue.append("[BOS]")
    key = tuple(queue)
    while(True):
        key = tuple(queue)
        value = random.choice(model[key])
        if value == "[EOS]":
            break
        value_list.append(value)
        queue.append(value)
    return value_list
#Derzeit werden automatisch 10 Zeilen generiert
for i in range(0, 10):
    serihu = ''.join(mk_serihu())
    print(serihu)

Erwägung

Als ich den Wert von N auf verschiedene Weise änderte, konnte ich eine solche Linie mit N = 4 erstellen. Wenn N erhöht wird, sind die Daten dieselben wie die Trainingsdaten, und wenn N klein ist, ist der Satz ungültig und es wird schwierig (Schweiß). Nimm einen Guten auf, der nicht in den Trainingsdaten enthalten ist, wenn N = 4 ist.

Warum versuchst du es nicht?
Sag mir, was der Chef ist!
Gibt es da etwas?
Ja. Kaban-Chan ist geschickt.
Du machst Witze, Kaban-chan.
Sehen Sie, lass uns gehen!
Kaban-chan war so, oder?
Was ist das? Ich frage mich, wie ich es haben soll.
Du vergisst uns auch.

Sie können Linien, die nicht in den Trainingsdaten enthalten sind, um ca. 63% generieren! Als nächstes ist derjenige, der nicht in den Trainingsdaten enthalten ist, wenn N = 3 ist.

Was ist los? Was ist mit Kaban-Chan?
gut. Was soll ich machen?
Es waren Freunde ...
Es ist durcheinander. Ich freue mich darauf.
Ah! Nicht gut! Kannst du es nehmen?
Ich denke, jeder ist besorgt.
Nun, diese Stimme wurde von jemandem gegessen.

80% der Zeilen sind nicht in den Trainingsdaten enthalten, aber sie sind immer noch instabil. Als nächstes ist derjenige, der nicht in den Trainingsdaten enthalten ist, wenn N = 2 ist.

Okay, ist es okay, herumzulaufen, ohne mehr getäuscht zu werden?
irgendwo. Es ist eine Tasche ... Ich frage mich, ob jemand weiß ist. Hey, Lava?
Oder soll ich es einfach nennen?
Es geht mir gut. Ist es in Form von Freunden?

96% der Zeilen sind nicht in den Trainingsdaten enthalten ... Der letzte ist N = 5

Ich bin gestern unterwegs eingeschlafen.
Es gibt viel Sand.
Ja Ja. Was meinst du? Hier?

35% der Zeilen sind nicht in den Trainingsdaten enthalten. Es gibt ein Gefühl der Stabilität, aber ich möchte, dass Sie mehr Linien erstellen, die ursprünglich nicht vorhanden waren, sodass N = 4 genau richtig ist. Da die Zeilen wie "Kaban-chan" lang sind, ist es leicht, unverständliche Zeilen zu erstellen, wenn eine so lange Wortfolge kommt. Schließlich ist die Markov-Kette allein hart (Schweiß).

Zusammenfassung

Derzeit ist es ein Modell, das leicht erstellt werden kann, aber es ist schwierig, Sätze zu generieren. Es gibt noch viele Dinge, die leicht erledigt werden können, z. B. das Registrieren von Zeichenfolgen von Zeichen und Stellen mit eindeutiger Ausdrucksextraktion und das Ersetzen durch ähnliche Wörter durch word2vec. Außerdem gibt es in jüngster Zeit viele Satzgenerationen, die Deep Learning verwenden, daher würde ich es gerne ausprobieren. Persönlich möchte ich ein Modell erstellen, das mithilfe eines automatischen Dialoggenerators eine große Menge an Trainingsdaten generieren kann. Wenn ein geeigneter Dialog eingegeben wird, kann er in einen bestimmten zeichenartigen Dialog umgewandelt und ausgegeben werden. Schließlich möchte ich ein Modell erstellen, das einen kürzeren Dialog als einseitige Dialoge ermöglicht. Kemono Friends hatte gute Daten, aber in Wirklichkeit werden sie in @RemChabot verwendet. Unter Verwendung der von der API erfassten Textdaten des Romans wird es möglich sein, mit Rem zu interagieren ich will Die Daten des Romans haben keine Bezeichnung für den Dialog, daher hört sie an dem Punkt auf, an dem die Daten erstellt werden (Schweiß). ~~ Ich möchte, dass jemand Daten erstellt. ~~ In jedem Fall ist es schwierig, Lerndaten in natürlicher Sprache zu erstellen. Wenn Sie also zusammenarbeiten möchten, kontaktieren Sie uns bitte.

Ich bin es nicht gewohnt, Artikel zu schreiben, und ich denke, es gab viele Punkte, die schwer zu lesen waren, aber ich danke Ihnen, dass Sie bis zum Ende gelesen haben. Wenn Sie denken, "es war hilfreich" oder "Ich möchte mehr lesen", wäre ich Ihnen dankbar, wenn es Ihnen gefallen könnte. (Weil es motiviert wird).

Liste der Referenzseiten

Ich habe versucht, die Zeilen von TV-Anime Kemono Friends zu transkribieren Wikipedia [Python] Satzgenerierung mit Markov-Kette im 9. Stock ["Satzerzeugung durch Markov-Kette"](https://omedstu.jimdofree.com/2018/05/06/%E3%83%9E%E3%83%AB%E3%82%B3%E3%83%95 % E9% 80% A3% E9% 8E% 96% E3% 81% AB% E3% 82% 88% E3% 82% 8B% E6% 96% 87% E6% 9B% B8% E7% 94% 9F% E6 % 88% 90 /)

Recommended Posts

Ich habe versucht, einen automatischen Charakterdialoggenerator für die Markov-Kette im N-Stock zu erstellen
Ich habe versucht, durch Schaben ein Bild zu bekommen
Ich habe versucht, eine OCR-App mit PySimpleGUI zu erstellen
Ich habe versucht, eine Luftlippenerkennung und eine automatische Reaktion BOT für Fernarbeit zu machen
Ich habe versucht, automatisch einen Bericht mit der Markov-Kette zu erstellen
[Markov-Kette] Ich habe versucht, negative Emotionen in Python zu laden.
[Markov-Kette] Ich habe versucht, die Zitate in Python einzulesen.
Ich habe versucht, eine Aktivität zu erstellen, die gemeinsam die Positionsinformationen festlegt
Ich habe versucht, das automatische Senden einer E-Mail durch Doppelklicken auf das Symbol [Python] zu ermöglichen
Ich habe versucht, in 3 Jahren 5 Muster der Analysebasis zu erstellen
[Python] Einfaches Japanisch ⇒ Ich habe versucht, ein englisches Übersetzungswerkzeug zu erstellen
Ich habe versucht, mit Python + OpenCV eine Bildähnlichkeitsfunktion zu erstellen
Ich habe versucht, das automatische Senden einer E-Mail durch Doppelklicken auf das Symbol [GAS / Python] zu ermöglichen
Ich habe mit TWE-Lite-2525A einen Öffnungs- / Schließsensor (Twitter-Link) erstellt
[Markov-Kette] Ich habe versucht, Zitate und negative Emotionen in Python einzulesen.
Ich möchte ein Automatisierungsprogramm erstellen!
Ich habe eine Web-API erstellt
Ich habe mein Bestes versucht, um eine Optimierungsfunktion zu erstellen, aber es hat nicht funktioniert.
Ich habe versucht, die Blasensortierung nach Sprache zu programmieren
Ich habe versucht, KI für Smash Bra zu machen
Ich habe versucht, ein Objekt mit M2Det zu erkennen!
Ich habe versucht, eine zufällige Zeichenfolge zu generieren
Ich habe versucht, Drachenkugeln nach Adalin zu klassifizieren
Ich habe ein ○ ✕ Spiel mit TensorFlow gemacht
Fortsetzung ・ Ich habe versucht, Slackbot zu erstellen, nachdem ich Python3 studiert habe
Ich habe versucht, künstliches Perzeptron mit Python zu implementieren
Ich habe versucht, mit AWS Lambda einen AMI zu erhalten
Ich habe versucht, mit OpenCV Ann Man zu werden
Ich habe versucht, die alternative Klasse mit Tensorflow zu finden
Ich habe versucht, einen automatischen Nachweis der Sequenzberechnung zu implementieren
[Python] Ich habe versucht, mit tkinter eine Anwendung zu erstellen, die das Gehalt anhand der Arbeitszeit berechnet
Ich habe versucht, einen Generator zu erstellen, der mit Python eine C # -Containerklasse aus CSV generiert
Ich habe versucht, Othello AI zu machen, dass ich 7,2 Millionen Hände durch tiefes Lernen mit Chainer gelernt habe