Eine Geschichte über das zufällige Erstellen eines kurzen Songs mit Sudachi Py

Was ist zufällig ein kurzes Lied?

Es ist Twitter Bot, der den Teil 57757 aus dem Text von Wikipedia extrahiert und veröffentlicht. Here wurde 2015 erstellt. Das Original scheint aus Ruby + MeCab zu bestehen, daher werde ich es dieses Mal mit Python und Sudachi nachdrucken. Vielen Dank und Respekt für Ihre Senioren.

Umgebung

Windows10 Home (64bit)

python 3.7.4 SudachiDict-full==20191224 SudachiPy==0.4.2

Die Umgebung wurde mit pipenv gebaut

Warum Sudachi?

In Sudachi können Sie den Teilungsmodus festlegen und die Teile in eine möglichst große Einheit zerlegen. Wenn Sie MeCab verwenden, wird es in recht kleine Teile zerlegt, sodass die Gefahr besteht, dass seltsame Unterteilungen wie "Tokyo Sky" in der oberen Phrase und "Tree" in der unteren Phrase aufgenommen werden. Sudachi reduziert dieses Risiko.

Unten aus Sudachis GitHub.

Split-Modus Sudachi bietet drei Split-Modi, A, B und C, beginnend mit dem kürzesten. A entspricht der kurzen UniDic-Einheit, C entspricht der richtigen Expression und B ist eine Zwischeneinheit zwischen A und C.

Ein Beispiel ist unten gezeigt.

(Bei Verwendung des Kernwörterbuchs)

A: Wahl / Management / Ausschuss / Sitzung B: Wahl / Verwaltung / Ausschuss C: Wahlkommission

A: Gästezimmer / Crew / Personal B: Gästezimmer / Crew C: Gästezimmerbesatzung

Es ist ein Gefühl, aber das Nesting A ist ungefähr das gleiche wie MeCab.

Installation von SudachiPy

Installieren Sie SudachiPy und das Wörterbuch unter GitHub of SudachiPy. Es gibt drei Arten von Wörterbüchern: klein, zentral und voll. Dieses Mal habe ich ein vollständiges Wörterbuch mit viel Wortschatz installiert.

pip install SudachiPy
pip install https://object-storage.tyo2.conoha.io/v1/nc_2520839e1f9641b08211a5c85243124a/sudachi/SudachiDict_full-20191224.tar.gz

Verknüpfen Sie das Wörterbuch

In Bezug auf das Wörterbuch scheint es eine Methode zu geben, die von json in der Quelle angegeben werden kann, und eine Methode, um das Standardwörterbuch über den Befehl zu verknüpfen. Diesmal habe ich mich für Letzteres entschieden. Ich habe es nicht in das Dokument geschrieben, aber als ich es normal gemacht habe, habe ich einen Berechtigungsfehler erhalten. Führen Sie daher den folgenden Befehl ** an einer Eingabeaufforderung mit Administratorrechten aus. Hamari Punkt hier. (Es ist unbestätigt, was unter Linux und Mac passiert.)

sudachipy link -t full

Quellcode

Da ich es locker gemacht habe, kann es einen Unsinn geben, wie man es macht. Ich denke, dort ist. Die Modi sind so unterteilt, dass sowohl Haiku als auch kurze Songs erkannt werden können. Zunächst bestand der Ansatz darin, einen Satz mit 31 Tönen zu extrahieren und zu prüfen, ob es 57757 sein würde. Aber als ich es versuchte, wurde es überhaupt nicht erkannt, so dass ich es möglich machte, auch nur einen Teil eines langen Satzes zu durchsuchen und ihn mit dem Flag settings.precision zu ersetzen. Ersteres, wenn Sie ein sauberes mit weniger Lärm wollen, letzteres, wenn Sie trotzdem eine Nummer wollen.

Die Grundrichtlinie besteht darin, die Messwerte beim Setzen eines Flags zu zählen und diejenigen zu extrahieren, deren Tonunterbrechungen in 57577 passen. Ablehnen, wenn es 579 oder 57578 wird. Wenn ein Hilfswort oder ein Hilfsverb am Anfang einer Phrase steht, wird es ebenfalls abgelehnt. Löschen Sie den Hauptteil des Textes und suchen Sie erneut. Außerdem werden [ya, u, yo] usw. nicht als Anzahl der Töne gezählt. Ich benutze importlib, weil ich es schließlich mit pyinstaller in eine exe verwandelt habe.

search_tanka.py


import re
import importlib
from sudachipy import tokenizer
from sudachipy import dictionary

setting = importlib.import_module('setting')
tokenizer_obj = dictionary.Dictionary().create()
#Stellen Sie die Teilungseinheit auf die längste ein
split_mode = tokenizer.Tokenizer.SplitMode.C
#Pfad der zu lesenden Textdatei
searchfile_path = "./search_text/" + setting.search_file_name
#Der Pfad der zu exportierenden Textdatei
savefile_path = "./result_text/" + setting.save_file_name
#Moduswechsel zwischen Haiku und kurzen Songs
if setting.mode == 1:
    break_points = [5, 12, 17]
else:
    break_points = [5, 12, 17, 24, 31]
#Katakana regulärer Ausdruck
re_katakana = re.compile(r'[\u30A1-\u30F4]+')

#Textdatei geöffnet
with open(searchfile_path, encoding="utf-8_sig") as f:
    #Lesen Sie alle Zeilen und Listen
    areas = f.readlines()
    for line in areas:
        # "。"Oder"."Oder mit einem Zeilenumbruch trennen
        sentences = re.split('[.。\n]', line)
        for sentence in sentences:
            #Durch bei der Suche nach Satz
            if setting.precision == 1:
                pass
            #Kurze Lieder, Haiku und Sätze mit mehr als jedem Zeichen werden nicht erkannt.
            else:
                if len(sentence) > break_points[-1]:
                    continue

            #Morphologische Analyse
            m = tokenizer_obj.tokenize(sentence, split_mode)
            #Verwandle Morphem-Liste in Liste
            m = list(m)

            retry = True
            while retry:
                break_point_header_flag = True
                retry = False
                counter = 0
                break_point_index = 0
                reading = ""
                surface = ""
                #Stellen Sie fest, ob der Satz bei der Unterbrechung jeder Phrase gebrochen ist
                for mm in m:
                    if break_point_header_flag == True:
                        text_type = mm.part_of_speech()[0]
                        #Wenn der Anfang jeder Phrase kein geeigneter Teil ist, wird er nicht erkannt.
                        if text_type in setting.skip_text_type:
                            #Suchen Sie erneut, wenn die lange Suche aktiviert ist
                            if setting.precision == 1:
                                retry = True
                                del m[0]
                                break
                            else:
                                counter = 0
                                break
                        else:
                            break_point_header_flag = False
                    #Messwerte analysieren
                    reading_text = mm.reading_form()
                    surface_text = mm.surface()
                    if len(reading_text) > 7:
                        #Suchen Sie erneut, wenn die lange Suche aktiviert ist
                        if setting.precision == 1:
                            retry = True
                            del m[0]
                            break
                        else:
                            counter = 0
                            break
                    #Wenn das Analyseergebnis ein Zeichen ist, das übersprungen werden soll, überspringen Sie es
                    if reading_text in setting.skip_text:
                        sentence = sentence.replace(mm.surface(), "")
                        continue
                    #Da der Personenname von Katakana nicht vorkommt, ergänzen Sie ihn mit der Oberfläche
                    if reading_text == "":
                        text_surface = mm.surface()
                        if re_katakana.fullmatch(text_surface):
                            reading_text = text_surface
                        #Überspringen, wenn ein Kanji angezeigt wird, das im Wörterbuch nicht gelesen werden kann
                        else:
                            #Suchen Sie erneut, wenn die lange Suche aktiviert ist
                            if setting.precision == 1:
                                retry = True
                                del m[0]
                                break
                            else:
                                counter = 0
                                break
                    #Zählen Sie die Anzahl der phonetischen Elemente beim Lesen
                    counter += len(reading_text)
                    reading = reading + reading_text
                    surface = surface + surface_text
                    #Abzüglich der Anzahl, wenn ein kompatibles Klangelement vorhanden ist, das nicht zählt
                    for letter in setting.skip_letters:
                        if letter in reading_text:
                            counter -= reading_text.count(letter)
                    #Hat sich die Anzahl um die Anzahl der Zeichen in jeder Phrase erhöht?
                    if counter == break_points[break_point_index]:
                        break_point_header_flag = True
                        #Wenn Sie noch nicht am Ende angelangt sind, fahren Sie mit dem nächsten Satz fort
                        if counter != break_points[-1]:
                            break_point_index += 1
                            reading = reading + " "
                    #Spielen Sie, wenn die in jeder Phrase angegebene Anzahl von Zeichen überschritten wird.
                    elif counter > break_points[break_point_index]:
                        #Suchen Sie erneut, wenn die lange Suche aktiviert ist
                        if setting.precision == 1:
                            retry = True
                            del m[0]
                            break
                        else:
                            counter = 0
                            break

                #Nehmen Sie diejenige, die genau mit der angegebenen Anzahl von Zeichen erkannt werden kann, und fügen Sie sie der Datei hinzu
                if counter == break_points[-1]:
                    with open(savefile_path, "a") as f:
                        try:
                            print(surface + " ")
                            print("(" + reading + ")" + "\n")
                            f.write(surface  + "\n")
                            f.write("(" + reading + ")" + "\n")
                            f.write("\n")
                        except Exception as e:
                            print(e)

                if len(m) < len(break_points):
                    break

setting.py


# mode (Erkennungsmodus) 1:Haiku 2:Tanka
mode = 2
# precision (Richtigkeit) 1:Niedrig 2:Hoch
#Geringe Anzahl von Erkennungen:Viele,Lärm:Viele、実行時間:Hoch
#Hohe Anzahl von Erkennungen:Klein,Lärm:Klein、実行時間:Klein
precision = 1
#Zeichen, die nicht als Phoneme gelten
skip_letters = ['Turbolader','Yu','Yo']
#Zu erkennende Dateien
search_file_name = "jawiki-latest-pages-articles.xml-001.txt"
#Datei zum Speichern des Erkennungsergebnisses
save_file_name = "result.txt"
#Teilwörter, die nicht an den Anfang der Phrase kommen sollten
skip_text_type = ["Partikel", "Hilfsverb", "Suffix", "Hilfssymbol"]
#Zeichen, die nicht im Analyseziel enthalten sind
skip_text = ["、", "Kigo", "=", "・"]

Ausführungsergebnis

Gescannt gegen Wikipedia-Text. Einige Auszüge unten.

Platon änderte seinen Stil ab der mittleren Periode unter dem Einfluss von Isokrates (Platon Haisokuratesunoeikyowoukechuukiyoribuntaiwokae)

Ein Denkmal für den Geburtsort des Shofu wird errichtet, der der Anfang sein soll. (Hajimarit Iwareshofu Hasshono Chinoishibu Migata Terra Einzelhandel)

Besonderes Augenmerk auf die Blutlinie, eine individuelle Tradition im gegenseitigen Einvernehmen (Soushou ni Okerukobetsuno Densho de Arketsumyakuwo Tokuniomonji)

Nuakshot wurde als Stadt gebaut, um die zukünftige Hauptstadt zu werden (Shorino Stoninalbeki Toshitoshite Nuakushotga Kensetsu Saleta)

Oktopusfischen nach japanischer Art mit einem Glas in Zusammenarbeit mit Japan (Nippon no Kyoryokunyori Takotsubowo Tsukauni Nippon Shikinota Koryo)

Zukunftsaussichten

Wenn Sie es erneut tun, möchte ich Folgendes unterstützen.

・ Zum Lesen von Zahlen Bei Sudachi scheint das Lesen von Zahlen derzeit nicht zu funktionieren.

Beispiel) Es waren in der Regel zwischen 50 und 150 Autos. ↓ (Omuneha Gorei Ryokara Erdbeere Rei Ryo no Aida de Suiishitita)

Es gibt einen Plan, aber die Umsetzung ist unentschlossen. Es scheint, dass wir damit umgehen können, indem wir uns bemühen, ein Wörterbuch mit Plug-Ins zu schreiben oder nur Zahlen mit regulären Ausdrücken auszuschneiden und nur diese Wörter mit einer anderen Engine zu analysieren. (Es ist jedoch eine andere Geschichte, ob es möglich sein wird, gute kurze Songs durch Antworten zu extrahieren ...) ・ Bezüglich der Ausführungsgeschwindigkeit Ich habe es erwartet, aber es ist spät ... Dies ist ein Problem mit meiner Implementierung, bevor Sudachi langsam oder Python langsam war. Es tut uns leid. Da es ehrlich mit einer for-Anweisung gedreht wird, sollte es schneller sein, wenn Sie itertools richtig verwenden.

Impressionen

Immerhin habe ich die Originalquelle fast ohne sie angeschaut (Oi) gemacht. Gelegentlich gab es Lärm oder etwas, das an seltsamen Stellen abgeschnitten wurde, aber es funktionierte meistens richtig. Ich denke, die letzte Abholarbeit ist immer noch menschliche Kraft. Wie twittert man mit einem Bot oder holt die Quelle des Zitats?

Viele von ihnen werden entdeckt, aber im Moment ist mein Favorit der folgende.

** Ärgerlicher Akt des mehrfachen Kopierens und Schreibens von Inhaltsstunden ** ** (Naiyouno Reswonandomo Kopipeshite Kakikomutoi Meiwakukoui) **

Na dann.

Recommended Posts

Eine Geschichte über das zufällige Erstellen eines kurzen Songs mit Sudachi Py
Die Geschichte, mit Python eine Hanon-ähnliche Partitur zu machen
Eine Geschichte über einen Amateur, der mit Python (Kivy) einen Blockbruch macht ②
Eine Geschichte über die Implementierung eines Anmeldebildschirms mit Django
Geschichte rund um die Datenanalyse durch maschinelles Lernen
Ich habe versucht, einen x86-Bootloader zu erstellen, der vmlinux mit Rust booten kann
Geschichte der Verwendung von Resonas Software-Token mit 1Password
Eine Geschichte über die Vorhersage des Wechselkurses mit Deep Learning
Eine Geschichte über das Ausprobieren eines (Golang +) Python-Monorepo mit Bazel
Die Geschichte, wie theano mit TSUBAME 2.0 verwaltet wurde
Eine Geschichte über den Wettbewerb mit einem Freund in Othello AI Preparation
Eine Geschichte über die Installation von matplotlib mit pip mit einem Fehler
Die Geschichte, einen PyPI-Cache-Server (mit Docker) aufzubauen und mich wieder ein wenig glücklich zu machen
Eine Geschichte über eine Tragödie, die durch den Austausch von Befehlen im Chat verursacht wurde
Die Geschichte, wie man mit discord.py einen Fragenkasten-Bot erstellt
Eine Geschichte über einen Python-Anfänger, der mit dem No-Modul'http.server 'feststeckt.
Eine Geschichte über die Entwicklung eines weichen Typs mit Firestore + Python + OpenAPI + Typescript
Die Geschichte, ein Modul zu erstellen, das E-Mails mit Python überspringt
Eine erfrischende Geschichte über Slice in Python
Eine launische Geschichte über Slice in Python
Eine Geschichte, die von Super (A, Selbst) erschöpft ist
Die Geschichte der Verwendung von Python reduziert
Die Geschichte, wie man mit Python einen 100-Yen-Frühstücks-Bot für die Universität macht
Eine Geschichte über die Automatisierung von Online-Mahjong (Jakutama) mit OpenCV und maschinellem Lernen
Eine Geschichte über einen magischen Umbau, der Lubuntu in ein Chromebook bringt
Eine Geschichte über Python Pop und Append
Eine Geschichte, die ich als Programmieranfänger mit GeoDjango erstellt habe
[Anmerkung] Eine Geschichte darüber, dass es nicht möglich ist, den Proxy mit pip zu durchbrechen
Eine Geschichte zum Erstellen einer IDE-Umgebung mit WinPython unter einem alten Windows-Betriebssystem.
Automatisches Zakuzaku, Bitcoin. Eine Geschichte über einen Python-Anfänger, der ein 1-Minuten-Diagramm für Münzprüfungen erstellt
Die Geschichte der Erstellung einer Webanwendung, die umfangreiche Lesungen mit Django aufzeichnet
[Python] Eine Geschichte über das Erstellen eines LINE-Bots mit einer praktischen bemannten Funktion ohne Verwendung von Salesforce [Messaging-API]