[Python3] Automatische Texterzeugung mit janome und markovify

Einführung

Mit der in Pure Python geschriebenen japanischen morphologischen Analyse-Engine Janome und der Markov-Kettenbibliothek markovify werden japanische Sätze gelernt und automatisch generiert.

Grundsätzlich Lernen Sie japanische Sätze mit markovify und generieren Sie Sätze nach Markov-Kette Es basiert auf.

Es ist schon eine Weile her, dass ich Python berührt habe, also ist es ziemlich locker. Bitte beachten Sie.

Hintergrund Zweck

Tatsächlich gibt es keinen Präzedenzfall für das Lernen und die automatische Generierung japanischer Sätze mit markovify, aber die meisten von ihnen verwenden MeCab. Aufgrund seiner Einführung ist es in Windows-Umgebungen und einigen virtuellen Umgebungen trivial. Es kostet Zeit und Mühe (Heroku).

In dieser Hinsicht ist Janome auch unter Windows einfach zu installieren, und es gibt auch einen Artikel, in dem die Verwendung für die automatische Generierung [immerhin] vorgestellt wurde (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 /), aber ich konnte keine Kombination aus Markovify und Janome (zu Nische) finden. Es ist einfacher, markovify zu verwenden, um die Natürlichkeit des generierten Satzes zu verbessern. Daher möchte ich ihn nach Möglichkeit verwenden.

Also habe ich dieses Mal versucht, es möglich zu machen, Sätze mit beiden zu generieren, also werde ich es anstelle eines Memos einfügen. Nun, wenn Sie es zusammen verwenden möchten, können Sie es meiner Meinung nach selbst umschreiben, es ist also wirklich nur ein Memo ...

Vorbereitung

Sowohl janome als auch markovify können mit pip install` `installiert werden. ( Pip3`` je nach Umgebung)

Code

Als allererstes. Für den textGen-Teil wird Referenz 1 mehr als zur Hälfte umgeleitet.

janomeGen.py


#!/usr/bin/env python3
# -*- coding:utf-8 -*-
from janome.tokenizer import Tokenizer
import markovify

def split(text):
    #Zeilenumbrüche, Leerzeichen, Ersetzen problematischer Zeichen
    table = str.maketrans({
        '\n': '',
        '\r': '',
        '(': '(',
        ')': ')',
        '[': '[',
        ']': ']',
        '"':'”',
        "'":"’",
    })
    text = text.translate(table)
    t = Tokenizer()
    result = t.tokenize(text, wakati=True)
    #Schauen Sie sich jedes Formularelement an, fügen Sie einen halben Abstand dazwischen ein und fügen Sie am Ende des Satzes einen Zeilenumbruch ein.
    splitted_text = ""
    for i in range(len(result)):
        splitted_text += result[i]
        if result[i] != '。' and result[i] != '!' and result[i] != '?':
            splitted_text += ' '
        if result[i] == '。' or result[i] == '!' or result[i] == '?':
            splitted_text += '\n'
    return splitted_text

def textGen(file):
    f = open(file, 'r', encoding="utf-8")
    text = f.read()
    sentence = None
    while sentence == None: #Je nach Material können leere Sätze generiert werden, also Gegenmaßnahmen
        #In ein Formular aufteilen, das Text verarbeiten kann
        splitted_text = split(text)

        #Modellgenerierung
        text_model = markovify.NewlineText(splitted_text, state_size=3)

        #Generieren Sie Sätze basierend auf dem Modell
        sentence = text_model.make_sentence()   
    
    #Trainingsdaten speichern
    with open('learned_data.json', 'w') as f:
        f.write(text_model.to_json())
    
    #Bei der Wiederverwendung von Daten
    """
    with open('learned_data.json') as f:
        text_model = markovify.NewlineText.from_json(f.read())
    """

    #Gibt als eine Reihe kombinierter Zeichenfolgen zurück
    return ''.join(sentence.split())

Unten werden wir sie der Reihe nach betrachten.

Textvorbereitung

    table = str.maketrans({
        '\n': '',
        '\r': '',
        '(': '(',
        ')': ')',
        '[': '[',
        ']': ']',
        '"':'”',
        "'":"’",
    })
    text = text.translate(table)

Ersetzen Sie einige Zeichen, damit markovify gelesen werden kann. Da Zeilenumbrüche und Leerzeichen verwendet werden, um Satzumbrüche bzw. Wortumbrüche anzuzeigen, werden sie einmal gelöscht (japanische Sätze, die mit englischen Sätzen gemischt sind, können nicht gut verarbeitet werden, diesmal werden sie jedoch ignoriert).

Ersetzen Sie außerdem "Bad-Zeichen", die den Betrieb von Markovify beeinträchtigen, durch harmlose Zeichen in voller Breite. (Seit markovify v0.7.2 können Sie mit dem Parameter well_formed von markovify.Text angeben, ob Sätze mit schlechten Zeichen ignoriert werden sollen. Es ist jedoch verschwenderisch, den gesamten Satz zu ignorieren, sodass er im Voraus ersetzt wird.)

Text teilen

t = Tokenizer()
    result = t.tokenize(text, wakati=True)
    splitted_text = ""
    for i in range(len(result)):
        splitted_text += result[i]
        if result[i] != '。' and result[i] != '!' and result[i] != '?':
            splitted_text += ' '
        if result[i] == '。' or result[i] == '!' or result[i] == '?':
            splitted_text += '\n'

Was Sie tun, ist fast dasselbe wie Referenzartikel 1, daher ist es genauer, darauf zu verweisen.

Wenn Sie mit Janomes Tokenizer wie folgt tokenisieren, wird es als durch Morphologie getrennte Liste zurückgegeben. Wenn "Ich esse einen Apfel", dann ist "[" Ich "," Ist "," Apfel "," Ist "," Eins "," Essen ",". Es fühlt sich an wie '] `` `. Es ist einfacher und bequemer als MeCab für diejenigen, die nur den Hauptteil der Morphologie wollen.

Lesen Sie diesmal die Morphologieelemente einzeln, damit markovify sie lesen kann, teilen Sie sie durch ein Feld mit halber Breite und trennen Sie sie am Ende des Satzes durch einen Zeilenumbruch (wie der englische Satz). Im Referenzartikel schneide ich es nur mit Satzzeichen, aber diesmal! Wann? Aber ich habe versucht, es zu schneiden. Wie Sie die Lesepunkte teilen, hängt von Ihrer Präferenz ab, aber hier haben wir sie als ein Wort geteilt. Wenn Sie es ähnlich wie Englisch machen möchten, ersetzen Sie die if-Anweisung

        if i+1 < len(result):
            if result[i] != '。' and result[i] != '!' and result[i] != '?' and result[i+1] != '、':
                splitted_text += ' '
            if result[i] == '。' or result[i] == '!' or result[i] == '?':
                splitted_text += '\n'
        else:
            if result[i] != '。' and result[i] != '!' and result[i] != '?':
                splitted_text += ' '
            if result[i] == '。' or result[i] == '!' or result[i] == '?':
                splitted_text += '\n'

Wenn Sie es irgendwie umschreiben, sollte es funktionieren. vielleicht.

Satzerzeugung

def textGen(file):
    f = open(file, 'r', encoding="utf-8")
    text = f.read()
    sentence = None
    while sentence == None: #Je nach Material kann keine zurückgegeben werden, daher Gegenmaßnahmen
        #In ein Formular aufteilen, das Text verarbeiten kann
        splitted_text = split(text)

        #Modellgenerierung
        text_model = markovify.NewlineText(splitted_text, state_size=3)

        #Generieren Sie Sätze basierend auf dem Modell
        sentence = text_model.make_sentence()   
    
    #Trainingsdaten speichern
    with open('learned_data.json', 'w') as f:
        f.write(text_model.to_json())
    #Gibt als eine Reihe kombinierter Zeichenfolgen zurück
    return ''.join(sentence.split())

Dieses Mal habe ich es für die Generierung aus etwas geschrieben, das nicht Aozora Bunko ist, also lasse ich die Verarbeitung dafür weg und lese es einfach. Da es sich ansonsten um ein Standardverfahren für die Markovifizierung handelt, folgt es grob Referenz 1.

Außerdem kann manchmal aufgrund von state_size und der Menge des Materialtextes None zurückgegeben werden (markovify Issue # 96, [Issue # 22]. ](Https://github.com/jsvine/markovify/issues/22)), also habe ich es umgedreht, bis ich leicht etwas zurückgebe, das nicht None ist. Ich denke nicht, dass es eine Endlosschleife sein wird, wenn es eine bestimmte Textmenge gibt.

Darüber hinaus ist es möglich, bis zu einem gewissen Grad damit umzugehen, indem die Anzahl der Versuche im Schlüsselwortargument try of make_sentence angegeben wird. (Code unten)

    #In ein Formular aufteilen, das Text verarbeiten kann
    splitted_text = split(text)

    #Modellgenerierung
    text_model = markovify.NewlineText(splitted_text, state_size=3)

    #Generieren Sie Sätze basierend auf dem Modell
    sentence = text_model.make_sentence(tries=100)   

Generierungsergebnis

Zum Testen von Bochan von Aozora Bunko bis delruby.exe Ich habe den Ruby mit delruby.html gelöscht und versucht, ihn basierend auf dem zu generieren, der unnötige Teile ausschließt.

  • Wenn Sie glauben, dass es an einer Person mangelt, ist jeder auf der Welt wie dieser Student. Derjenige, der keine Insekten mag, ist freundlich und elegant, aber es gibt keine andere Wahl, als mit einem armen Mann zu kommen. Machen Sie also eine laute Stimme Ich werde es löschen.

Es scheint, dass der Zweck erreicht wurde.

Nachwort

Sowohl Janome als auch MeCab haben ähnliche Funktionen in dem Sinne, dass sie eine japanische morphologische Analyse durchführen, sodass ich sie mit nur geringfügigem Umschreiben implementieren konnte. Es scheint, dass es beim Erstellen eines Bots verwendet werden kann.

Referenz

  1. Japanische Sätze mit markovify lernen und Sätze nach Markov-Kette generieren
  2. So lernen Sie Sätze und generieren sie automatisch mit [Python] MeCab und Markov Chain Library Markovify
  3. [Satzerzeugung durch Markov Chain-Knowledge-Salatschüssel](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

[Python3] Automatische Texterzeugung mit janome und markovify
Clustering und Visualisierung mit Python und CytoScape
[PyTorch] Japanische Satzgenerierung mit Transformer
[Lass uns mit Python spielen] Ziel ist die automatische Satzgenerierung ~ Abschluss der automatischen Satzgenerierung ~
[Lass uns mit Python spielen] Ziel ist die automatische Satzgenerierung ~ Lies .txt und mache daraus eine Satzeinheit ~
Hinweise zur Verwendung von cChardet und python3-chardet in Python 3.3.1.
Automatische Erfassung von Aktienkursen mit Python
Von Python bis zur Verwendung von MeCab (und CaboCha)
Verwenden von Python und MeCab mit Azure Databricks
[Lass uns mit Python spielen] Ziel ist die automatische Satzgenerierung ~ Morphologische Analyse durchführen ~
Ich verwende Tox und Python 3.3 mit Travis-CI
Schätzung der Kopforientierung mit Python und OpenCV + dlib
Ich habe versucht, Web-Scraping mit Python und Selen
Hinweise zur Installation von Python3 und zur Verwendung von pip unter Windows7
Entwickeln und Bereitstellen von Python-APIs mit Kubernetes und Docker
Python-Entwicklungsablauf mit Poetry, Git und Docker
Ich habe versucht, Objekte mit Python und OpenCV zu erkennen
Erstellen Sie eine Webmap mit Python und GDAL
[Kurzer Satz] [Python] Listen und Wörterbücher formatieren und drucken
Versuchen Sie es mit Tensorflow. ① Erstellen Sie eine Python-Umgebung und führen Sie Tensorflow ein
Generierung der Vorlagen-Netzwerkkonfiguration mit Python und Jinja2
Versuchen Sie, die ChatWork-API und die Qiita-API in Python zu verwenden
Starten Sie Python
Automatische Mosaikerzeugung
Scraping mit Python
Grundeinstellungen für die Verwendung von Python3.8 und pip unter CentOS8
Durchsuchen von Pixiv-Tags und Speichern von Illustrationen mit Python
Erweiterbare Skelette für Vim mit Python, Click und Jinja2
Versuchen Sie, eine komprimierte Datei mit Python und zlib zu erstellen
Aggregieren Sie Git-Protokolle mit Git Python und analysieren Sie Assoziationen mit Orange
Automatisches Folgen auf Twitter mit Python und Selen! (RPA)
Implementieren eines Generators mit Python> Link> Yield und next ()> Yield
Holen Sie sich die ASP Datepicker-Steuerung mit Python und Selen und automatisieren Sie sie
Lesen und schreiben Sie NFC-Tags mit Python mit PaSoRi
Sprachtranskriptionsverfahren mit Python und Google Cloud Speech API
Holen Sie sich Dateien von Linux mit paramiko und scp [Python]
HTTP-Server und HTTP-Client mit Socket (+ Webbrowser) - Python3