[PYTHON] Ich habe versucht, Herrn Saito zu reproduzieren, der in "Aine Kleine Nachtmusik" als Herr Sakurai von Mischil auftritt

Einführung

Kotaro Isakas Roman ["Aine Kleine Nachtmusik"](https://www.amazon.co.jp/%E3%82%A2%E3%82%A4%E3%83%8D%E3%82%AF% E3% 83% A9% E3% 82% A4% E3% 83% 8D% E3% 83% 8A% E3% 83% 8F% E3% 83% 88% E3% 83% A0% E3% 82% B8% E3% 83% BC% E3% 82% AF-% E5% B9% BB% E5% 86% AC% E8% 88% 8E% E6% 96% 87% E5% BA% AB-% E4% BC% 8A% E5% Kennen Sie die Arbeit 9D% 82% E5% B9% B8% E5% A4% AA% E9% 83% 8E-ebook / dp / B0746CS4T6)? Wenn Sie Romane mögen, wissen Sie vielleicht. Es ist eine kurze Bearbeitung, die sich wie jeden Tag anfühlt, aber Eine Person namens "Mr. Saito" erscheint in der Arbeit. Wenn Sie 100 Yen bezahlen und über "Ich fühle mich jetzt so" und "Ich bin in dieser Situation" sprechen, Herr Saito wird einige der Songs, die der Stimmung des Kunden entsprechen, am Computer spielen. Es gibt nur Mr. Saito in dem Lied und ein Teil von Kazuyoshi Saitos Lied wird gespielt.

Also dachte ich, ich könnte das Gleiche mit Emotionsanalyse tun. Ich habe beschlossen, es dieses Mal zu machen. Jedem Künstler geht es gut, aber ich bin selbst ein mysteriöser Fan Ich habe es mit einem Charakter namens Mr. Sakurai geschafft.

Dieses Mal verwenden wir die Emotionsanalyse von COTOHA API. Es scheint, dass sie auch [Kampagne] durchführen (https://zine.qiita.com/event/collaboration-cotoha-api/), und sie nehmen auch teil.

Was du gemacht hast

Es ist schneller zu sehen, ob Sie etwas gemacht haben, als zu erklären.

Sie:
Sie: Jeder Tag ist eintönig und langweilig. Ich frage mich, ob es etwas Gutes gibt.
Sie: Jeder Tag ist eintönig und langweilig. Ich frage mich, ob es etwas Gutes gibt.
Sakurai: Ich bin Ende zwanzig und habe ein glattes Segel zwischen Tokio und Paris. Ich habe die Welle des sprudelnden Generationswechsels weggeschoben und an meine Kunden verkauft.[Delmo]

Du kannst alles nehmen, Es scheint, dass Sie interpretieren können, dass Sie ein reibungsloses Segelleben haben können, wenn Sie einen Job machen, den Sie oft nach Paris gehen. Dies wird Teil des Textes von Mischils Song "Delmo" sein.

Systemübersicht

Es kann grob in (1) Datenkonstruktion und (2) Phrasensuchverarbeitung unterteilt werden.

sakuraisan-image.png

① Datenkonstruktion Die Texte aus dem Songnetz kratzen, In Sätze teilen. (Ein Absatz des gesamten Textes ist eine Phrase) Jede Phrase wird auf die Emotionsanalyse-API angewendet und das Analyseergebnis wird in der Datenbank gespeichert.

② Phrasensuche Der Kunde erklärt die Situation und wendet den Inhalt auf die Emotionsanalyse-API an, um das Analyseergebnis zu erhalten. Durchsuchen Sie danach die Datenbank nach Phrasen mit ähnlichen Ergebnissen. Die Suche ist eine Bereichssuche der Partitur, während der Bereich erweitert wird. Wenn mehrere Sätze erhalten werden können, wird einer zufällig ausgewählt und dem Kunden geantwortet.

Ausführungsergebnis

Hier sind einige der Dinge, die ich getan und interessant gefunden habe.

Sie: Ich bin so glücklich, heute bei der Arbeit gelobt zu werden!
Sakurai: Wenn Sie frustriert sind, füllen Sie Ihre Liebe wieder auf. Die Flammen der Liebe zu Ihnen brennen. Der Shiba-Hund im gegenüberliegenden Haus sagt auch "Hyponjour".!Ah, die Welt ist rosafarben, also bin ich hier das Zentrum des Universums. Ich bin das Zentrum. Ah, die Welt ist wunderbar[CENTER OF UNIVERSE]

Ist das frustrierend, wenn man nur die erste Hälfte betrachtet? Ich hab es geschafft, Ich singe in der zweiten Hälfte etwas wirklich Fröhliches. Die Arbeit läuft gut Ich bin der Weltmeister! Ziel.

Sie: Ich habe nicht für die Prüfung gelernt. Ich frage mich, ob ich nächstes Jahr mein Bestes geben werde. .. ..
Sakurai: Ich möchte tief durchatmen und dieses Gefühl in den Himmel entlassen. Ich möchte aus der trüben Stimmung herauskommen, in der ich in meiner eigenen Welt gefangen bin.[SUNRISE]

Atmen Sie vorerst ein und lassen Sie die trübe Stimmung hinter sich. Es fühlt sich negativ an, aber es gibt mir auch viel Ermutigung.

Sie: Ich werde nicht sagen, dass ich nicht mehr verliebt bin
Herr Sakurai: Ich kann Sie hören, die unkontrollierbaren Gefühle über Sie sind hier, selbst wenn Sie Ihre Ohren schließen, klingeln sie[365 Tage]

Die Gefühle, die ich liebe und die unwiderstehlich sind, passen zusammen.

Sie: Eigentlich denke ich daran, mit ihrer Datierung Schluss zu machen
Sakurai: Schon gut!?Beenden wir das!?Das denkst du auch!? [I]

Es kann Ihnen sagen, dass Sie es beenden können.

Code

Wenn Sie interessiert sind, schauen Sie bitte. Ich habe etwas gemacht, das vorerst funktioniert. Bitte beachten Sie, dass es nicht gut organisiert ist. .. ..

DB-Schema

Ich benutze MYSQL. Dieses Mal wird Mr.Children im Voraus als Künstlerinformation registriert.

create database sakurai;

create table artist
  (artist_id smallint auto_increment not null primary key,
  artist_name varchar(100));

insert into artist (artist_name) values('Mr.Children');

create table title
  (title_id smallint auto_increment not null primary key,
  title varchar(100),
  artist_id smallint);
 
create table lyric
 (title_id smallint,
  phrase_id int auto_increment not null primary key,
  phrase varchar(1000),
  score float,
  sentiment tinyint);
Python-Code

sakuraisan.py


# -*- coding: utf-8 -*-

import random, requests, json, sys, time
import urllib.request
import mysql.connector as mydb
import pandas as pd

from bs4 import BeautifulSoup

ARTIST_ID = 1 #Künstlerausweis im Voraus in der DB registriert
AGENT_NAME = 'Sakurai' #Der Name des Agenten, der antwortet

#COTOHA API-Klasse
class CotohaApi():
    def __init__(self):
        self.COTOHA_ACCESS_INFO = {
            "grantType": "client_credentials",
            "clientId": "<Ihre Kunden-ID>",
            "clientSecret": "<Ihr eigenes Kundengeheimnis>"
        }
        self.ACCESS_TOKEN_PUBLISH_URL = '<Ihre Zugriffstoken-Veröffentlichungs-URL>'
        self.BASE_URL = '<Ihre API-Basis-URL'

        self.ACCESS_TOKEN = self.get_access_token()

    #Zugriffstoken erhalten
    def get_access_token(self):
        headers = {
            "Content-Type": "application/json;charset=UTF-8"
        }
        access_data = json.dumps(self.COTOHA_ACCESS_INFO).encode()
        request_data = urllib.request.Request(self.ACCESS_TOKEN_PUBLISH_URL, access_data, headers)
        token_body = urllib.request.urlopen(request_data)
        token_body = json.loads(token_body.read())
        self.access_token = token_body["access_token"]
        self.headers = {
            'Content-Type': 'application/json;charset=UTF-8',
            'Authorization': 'Bearer {}'.format(self.access_token)
        }

    #Implementierte Emotionsanalyse-API und zurückgegebene Analyseergebnisse
    def sentiment_analysis(self, text):
        request_body = {
            'sentence': text
        }
        url = self.BASE_URL + 'nlp/v1/sentiment'
        text_data = json.dumps(request_body).encode()
        request_data = urllib.request.Request(url, text_data, headers=self.headers, method='POST')
        sentiment_result = urllib.request.urlopen(request_data)
        sentiment_result = json.loads(sentiment_result.read())
        return sentiment_result

    # Positive:1, Negative:-1, Neutral:In 0 konvertieren
    def convert_sentiment(self, sentiment_in_word):
        if sentiment_in_word == 'Positive':
            return 1
        elif sentiment_in_word == 'Neutral':
            return 0
        elif sentiment_in_word == 'Negative':
            return -1

#DB-Operationsklasse
class DBHandler():
    def __init__(self):
        self.conn = mydb.connect(
            host = '<DB-Hostname>',
            port = '<DB-Portnummer>',
            user = '<DB-Benutzername>',
            password = '<DB-Passwort>',
            database = '<DB-Name>',
            charset='utf8'
        )

        self.conn.ping(reconnect=True)
        self.cur = self.conn.cursor()

#Datenkonstruktionsklasse
class Learn():
    def __init__(self):
        self.FILE_NAME = 'list.csv'
        self.ARTIST_NUMBER = '684' #Uta Net Artist No..(Mr.Kinder 684)
        self.MAX_PAGE = 2 #Anzahl der Seiten der Songliste der Songnetzkünstler (Mr..Kinder haben 2 Seiten)

    #Sammle Texte aus dem Songnetz
    def gather_lyric(self):
        #Erstellen Sie eine Tabelle mit den Scraped-Daten
        list_df = pd.DataFrame(columns=['Song Titel', 'Text'])

        for page in range(1, self.MAX_PAGE + 1):
            #Top-Adresse der Song-Seite
            base_url = 'https://www.uta-net.com'

            #Textliste Seite
            url = 'https://www.uta-net.com/artist/' + self.ARTIST_NUMBER + '/0/' + str(page) + '/'
            response = requests.get(url)
            soup = BeautifulSoup(response.text, 'lxml')
            links = soup.find_all('td', class_='side td1')

            for link in links:
                a = base_url + (link.a.get('href'))

                #Lyrics Detail Seite
                response = requests.get(a)
                soup = BeautifulSoup(response.text, 'lxml')
                title = soup.find('h2').text
                print(title)
                song_lyrics = soup.find('div', itemprop='text')
                
                for lyric in song_lyrics.find_all("br"):
                    lyric.replace_with('\n')
                song_lyric = song_lyrics.text

                #Warten Sie 1 Sekunde, bis der Server nicht geladen ist
                time.sleep(1)

                #Fügen Sie die erworbenen Texte zur Tabelle hinzu
                tmp_se = pd.DataFrame([title, song_lyric], index=list_df.columns).T
                list_df = list_df.append(tmp_se)

        #CSV speichern
        list_df.to_csv(self.FILE_NAME, mode = 'a', encoding='utf8')

    #Teilen Sie die Texte in Phrasen und registrieren Sie die Daten einschließlich der Ergebnisse der Emotionsanalyse in der DB
    def add_lyric(self):
        db = DBHandler()
        df_file = pd.read_csv(self.FILE_NAME, encoding='utf8')
        song_titles = df_file['Song Titel'].tolist()
        song_lyrics = df_file['Text'].tolist()
        
        #Hinweis: Wenn viele Songs vorhanden sind, wird die Obergrenze der API erreicht, die in COTOHA pro Tag ausgeführt werden kann (ca. 100 Songs pro Tag sind Richtwerte).
        for i in range(len(song_titles)):

            #Titel hinzufügen
            title = song_titles[i]

            print("Info: Saving {}...".format(title), end="")
            db.cur.execute(
                """
                insert into title (title, artist_id)
                values (%s, %s);
                """,
                (title, ARTIST_ID)
            )
            db.conn.commit()
            db.cur.execute(
                """
                select title_id from title
                where title= %s
                and artist_id = %s;
                """,
                (title, ARTIST_ID)
            )
            title_id = db.cur.fetchall()[-1][0]

            #Registrieren Sie das Ergebnis der Emotionsanalyse der Textphrase
            #Phrasenbegrenzer, wenn zwei Zeilenumbrüche angezeigt werden
            lyric = song_lyrics[i]
            lyric_phrases = lyric.split('\n\n')
            lyric_phrases = [lyric.replace('\u3000', ' ').replace('\n', ' ') for lyric in lyric_phrases]
            
            #Verwenden Sie die Emotionsanalyse-API für jede Phrase und registrieren Sie die Ergebnisse der Emotionsanalyse in der Datenbank
            cotoha_api= CotohaApi()
            for phrase in lyric_phrases:
                sentiment_result = cotoha_api.sentiment_analysis(phrase)['result']
                sentiment = cotoha_api.convert_sentiment(sentiment_result['sentiment'])
                score = sentiment_result['score']
                
                db.cur.execute(
                    """
                    insert into lyric (title_id, score, sentiment, phrase)
                    values (%s, %s, %s, %s);
                    """,
                    (title_id, score, sentiment, phrase)
                )
                db.conn.commit()

            print("Done")
                
        db.conn.close()
        if db.conn.is_connected() == False:
            print("Info: DB Disonnected")

    def execute(self):
        print("Info:Texte sammeln...")
        self.gather_lyric()
        print("Info:Hinzufügen von Texten zur DB...")
        self.add_lyric()

#Phrasensuchklasse
class Search():
    def __init__(self):
        self.SEARCH_SCOPE = [0.01, 0.1, 0.3] #Breite der zu suchenden Punktzahl SCORE ± SEARCH_Suchen Sie in der Reihenfolge der Liste im Bereich von SCOPE

    def execute(self):
        print("Sie:", end="")
        input_data = input()
        print("{}:".format(AGENT_NAME), end="")
        
        cotoha_api= CotohaApi()
        sentiment_result = cotoha_api.sentiment_analysis(input_data)['result']
        sentiment = cotoha_api.convert_sentiment(sentiment_result['sentiment'])
        score = sentiment_result['score']
        
        db = DBHandler()

        find_flag = 0
        #Suchen Sie nach Phrasen mit ähnlichen Ergebnissen, während Sie den Suchbereich schrittweise erweitern
        for scope in self.SEARCH_SCOPE:

            #Bestätigen Sie, dass mindestens einer vorhanden ist
            db.cur.execute(
                """
                select count(phrase_id) from lyric
                join title on lyric.title_id = title.title_id
                where sentiment = %s
                and score between %s and %s
                and artist_id = %s;
                """,
                (sentiment, score-scope, score+scope, ARTIST_ID)
            )
            hit_num = db.cur.fetchall()[-1][0]
            if hit_num > 0:
                find_flag = 1
                break
        
        #Wenn es nur ein Suchergebnis gibt, rufen Sie das Suchergebnis ab und antworten Sie dem Kunden
        if find_flag == 1:
            db.cur.execute(
                """
                select phrase,title from lyric
                join title on lyric.title_id = title.title_id
                where sentiment = %s
                and score between %s and %s
                and artist_id = %s;
                """,
                (sentiment, score-scope, score+scope, ARTIST_ID)
            )
            search_result = db.cur.fetchall()
            phrase_chosen = random.choice(search_result)
            print("{} [{}]".format(phrase_chosen[0], phrase_chosen[1]))
        else:
            print("Ich konnte keine guten Texte finden.")
        
        db.conn.close()
        

if __name__ == "__main__":
    args = sys.argv
    if len(args) == 2:
        process = args[1] #Befehlszeilenargument lernen:Songtexte in DB registrieren, suchen:Extrahieren Sie ähnliche emotionale Sätze aus der DB
        if process == 'search':
            searcher = Search()
            searcher.execute()
        elif process == 'learn':
            learner = Learn()
            learner.execute()
        else:
            print("Error:Geben Sie ein Befehlszeilenargument an[learn/search]")
    else:
        print("Error:Geben Sie ein Befehlszeilenargument an[learn/search]")

Es gibt zwei Möglichkeiten, es auszuführen.

  • Beim Erstellen von Daten
python sakuraisan.py learn
  • Bei der Suche nach Phrasen
python sakuraisan.py search

abschließend

Dieses Mal habe ich es mit einem einfachen Algorithmus implementiert, der Phrasen mit Texten abruft, die ähnliche Ergebnisse in den Ergebnissen der Emotionsanalyse aufweisen. Die COTOHA-API kann auch die Emotionen von Wörtern aufnehmen. Zum Beispiel wie im offiziellen Beispiel Das Wort "Lied" gibt Gefühle wie "angenehm" und "erleichtert". Ich denke, dass bessere Ergebnisse zurückgegeben werden, wenn die Informationen hier gut in die Suche eingebettet werden können.

Ich denke auch, dass es interessant wäre, LINE Bot zu verwenden.

Referenz

Ich habe auf folgenden Artikel verwiesen!

Recommended Posts

Ich habe versucht, Herrn Saito zu reproduzieren, der in "Aine Kleine Nachtmusik" als Herr Sakurai von Mischil auftritt
Ich habe versucht, das Blackjack of Trump-Spiel mit Python zu implementieren
Ich habe versucht, in 3 Jahren 5 Muster der Analysebasis zu erstellen
Ich möchte meine Gefühle mit den Texten von Mr. Children ausdrücken
Ich habe versucht, verschiedene Muster von Datumszeichenfolgen in pandas.to_datetime einzugeben
Ich habe versucht, den Höhenwert von DTM in einem Diagramm anzuzeigen
Ich habe versucht, Trumps Kartenspiel in Python zu implementieren
Ich habe versucht, den Ortsnamen zu wecken, der in den Texten von Masashi Sada auf der Heatmap erscheint
Ich habe versucht, PLSA in Python zu implementieren
Ich habe versucht, Permutation in Python zu implementieren
Ich habe versucht, PLSA in Python 2 zu implementieren
Ich habe versucht, PPO in Python zu implementieren
Ich habe versucht, die Zusammenführungssortierung in Python mit möglichst wenigen Zeilen zu implementieren
[Azure] Ich habe versucht, eine virtuelle Linux-Maschine mit Azure von Microsoft Learn zu erstellen