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.
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 ...
Sowohl janome als auch markovify können mit pip install` `installiert werden. (
Pip3`` je nach Umgebung)
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.
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.)
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.
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)
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.
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.
Recommended Posts