[PYTHON] Spielen Sie mit Dajare mithilfe der COTOHA-API

Einführung

[Qiita x COTOHA API präsentieren Plan] Lassen Sie uns Text mit COTOHA API analysieren!

Ich habe mich aufgrund der Gerüchte über das vorliegende Projekt entschlossen, die COTOHA-API zu berühren. Für mich, der Dajare liebt, habe ich mich gefragt, ob ich Dajare mit dieser API analysieren kann, also habe ich versucht, es zu berühren. Ich erwarte überhaupt kein Geschenk.

Vorbereitung

Registrieren Sie sich zunächst auf der COTOHA API-Seite für Developer. Sie können die API sofort aufrufen.

Solange Sie sich mit Dajare beschäftigen, wird es definitiv ein Versuch und Irrtum sein. Der For Developer-Plan ist jedoch auf 1000 Aufrufe pro Tag für jede API begrenzt. Versuchen Sie in diesem Fall, eine Klasse zu erstellen, die dieselbe Eingabe zwischenspeichert und die API nicht unnötig aufruft.

COTOHA.py (möglicherweise irgendwie überflüssig)
import os
import sys
import pathlib
import time
import requests
import json
import hashlib


class COTOHA:
    __BASE_URL = 'https://api.ce-cotoha.com/api/dev/'

    def __init__(self, id, secret, cache_dir='./COTOHA_cache'):
        self.id = id
        self.secret = secret
        self.cache_dir = cache_dir
        self._get_token()

    def _create_cache_path(self, func, key):
        hash = hashlib.md5(key.encode()).hexdigest()
        hashpath = "{}/{}/{}".format(hash[:2], hash[2:4], hash[4:])
        return self.cache_dir + '/' + func + '/' + hashpath

    def _save_cache(self, path, content):
        pathlib.Path(os.path.dirname(path)).mkdir(exist_ok=True, parents=True)
        with open(path, mode="w") as c:
            c.write(content)
        return

    def _load_cache(self, path):
        content = None
        if os.path.exists(path):
            with open(path, mode="r") as c:
                content = c.read()
        return content

    def _get_token(self):
        token_cache = self.cache_dir + '/token'  # format: token expired_time
        cache = self._load_cache(token_cache)
        if cache:
            token, expired_time = cache.split()
            if int(expired_time) > int(time.time()):
                self.token = token
                return

        # get new token
        token_url = 'https://api.ce-cotoha.com/v1/oauth/accesstokens'
        headers = {'content-type': 'application/json'}
        payload = {"grantType": "client_credentials",
                   "clientId": self.id,
                   "clientSecret": self.secret}
        res = requests.post(token_url, headers=headers, data=json.dumps(payload))
        res.raise_for_status()
        res_json = json.loads(res.text)

        self.token = res_json['access_token']
        expired_time = int(time.time()) + int(res_json['expires_in'])
        self._save_cache(token_cache, self.token + ' ' + str(expired_time))
        return

    #Spracherkennungsfehlererkennung(β)
    def detect_misrecognition(self, data):
        func = sys._getframe().f_code.co_name
        cache_path = self._create_cache_path(func, data)
        cache = self._load_cache(cache_path)
        if cache:
            print("[INFO] use '"+func+"' api cache", file=sys.stderr)
            return cache

        api_url = self.__BASE_URL + 'nlp/beta/detect_misrecognition'
        payload = {'sentence': data}
        headers = {'content-type': 'application/json;charset=UTF8',
                   'Authorization': 'Bearer ' + self.token}

        res = requests.post(api_url, headers=headers, data=json.dumps(payload))
        res.raise_for_status()

        self._save_cache(cache_path, res.text)
        return res.text

    #einpacken(β)
    def summary(self, data, sent_len=1):
        func = sys._getframe().f_code.co_name
        cache_path = self._create_cache_path(func, data+str(sent_len))
        cache = self._load_cache(cache_path)
        if cache:
            print("[INFO] use '"+func+"' api cache", file=sys.stderr)
            return cache

        api_url = self.__BASE_URL + 'nlp/beta/summary'
        payload = {'document': data, 'sent_len': sent_len}
        headers = {'content-type': 'application/json;charset=UTF8',
                   'Authorization': 'Bearer ' + self.token}

        res = requests.post(api_url, headers=headers, data=json.dumps(payload))
        res.raise_for_status()

        self._save_cache(cache_path, res.text)
        return res.text

    def keyword(self, data, type='default', max_keyword_num=5):
        func = sys._getframe().f_code.co_name
        cache_path = self._create_cache_path(func, data+type+str(max_keyword_num))
        cache = self._load_cache(cache_path)
        if cache:
            print("[INFO] use '"+func+"' api cache", file=sys.stderr)
            return cache

        if type != 'kuzure' and type != 'default':
            print("[ERROR] type must be default or kuzure! :" + type)
            return

        api_url = self.__BASE_URL + 'nlp/v1/keyword'
        payload = {'document': data, 'type': type, 'max_keyword_num': max_keyword_num}
        headers = {'content-type': 'application/json;charset=UTF8',
                   'Authorization': 'Bearer ' + self.token}

        res = requests.post(api_url, headers=headers, data=json.dumps(payload))
        res.raise_for_status()

        self._save_cache(cache_path, res.text)
        return res.text

    def parse(self, data, type='default'):
        func = sys._getframe().f_code.co_name
        cache_path = self._create_cache_path(func, data+type)
        cache = self._load_cache(cache_path)
        if cache:
            print("[INFO] use '"+func+"' api cache", file=sys.stderr)
            return cache

        if type != 'kuzure' and type != 'default':
            print("[ERROR] type must be default or kuzure! :" + type)
            return

        api_url = self.__BASE_URL + 'nlp/v1/parse'
        payload = {'sentence': data, 'type': type}
        headers = {'content-type': 'application/json;charset=UTF8',
                   'Authorization': 'Bearer ' + self.token}

        res = requests.post(api_url, headers=headers, data=json.dumps(payload))
        res.raise_for_status()

        self._save_cache(cache_path, res.text)
        return res.text

    : (Folgendes wird weggelassen)

Machen wir also einen Befehl, damit Sie ihn nach Belieben aufrufen können. Ich bin neu in Python, daher bin ich mir nicht sicher, ob Argparse gut ist, aber im Moment ist es schnell. Es sind keine Optionen beigefügt.

coto.py
!/usr/bin/env python
import sys
import argparse
from COTOHA import COTOHA

parser = argparse.ArgumentParser()
parser.add_argument('api', choices=['summary', 'keyword', 'parse',
                    'detect_misrecognition'])
parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
                    default=sys.stdin)
args = parser.parse_args()

id = ''  #Geben Sie Ihre ID ein!
secret = ''  #Ein Geheimnis preisgeben!
coto = COTOHA(id, secret)

data = args.infile.read()
if args.api == "summary":
    sent_len = 1
    res = coto.summary(data, sent_len)
elif args.api == "keyword":
    type = 'default'
    max_keyword_num = 5
    res = coto.keyword(data, type, max_keyword_num)
elif args.api == "parse":
    type = 'default'
    res = coto.parse(data, type)
elif args.api == "detect_misrecognition":
    res = coto.detect_misrecognition(data)
elif args.api == "sentiment":
    res = coto.sentiment(data)
else:
    print("unexpected api:" + args.api, file=sys.stderr)
    sys.exit(1)

print(res)

Irgendwie werde ich versuchen, es mit einem Kissengras (Explosion) als Ausgangspunkt zu treffen.

$ cat makurano.txt 
Der Frühling ist Akebono. Die Berge, die endlich weiß werden, sind etwas heller und die lila Wolken flattern.
Sommer ist Nacht.... (Folgendes wird bis zum Winter weggelassen.)
$ [hoshino@localhost py_scrape]$ ./coto.py summary makurano.txt 
{"result":"Wenn Sie sich tagsüber warm entspannen, besteht das Feuer im Kohlenbecken aus weißer Asche.","status":0}
$ ./coto.py keyword makurano.txt 
{
  "result" : [ {
    "form" : "Sehen",
    "score" : 21.3012
  }, {
    "form" : "Itotsuki",
    "score" : 20.0
  }, {
    "form" : "Feuer",
    "score" : 17.12786
  }, {
    "form" : "Wo man schlafen kann",
    "score" : 11.7492
  }, {
    "form" : "Sonnenuntergang",
    "score" : 11.4835
  } ],
  "status" : 0,
  "message" : ""
}

Ja, plötzlich einen alten Satz zu werfen hat eine schlechte Persönlichkeit. Ich kenne die Gültigkeit des Ergebnisses nicht. W Lassen Sie es uns etwas deutlicher treffen.

$ echo "Ich bin heute Sukiyaki, ich freue mich darauf." | ./coto.py sentiment
{"result":{"sentiment":"Positive","score":0.6113335958534332,"emotional_phrase":[{"form":"Ich freue mich darauf","emotion":"P"}]},"status":0,"message":"OK"}

$ echo "Ich bin heute Sukiyaki, ich will es nicht essen." | ./coto.py sentiment
{"result":{"sentiment":"Neutral","score":0.2837920794741674,"emotional_phrase":[]},"status":0,"message":"OK"}

$ echo "Es ist heute Sukiyaki, es ist schwer zu essen." | ./coto.py sentiment
{"result":{"sentiment":"Negative","score":0.7608419653662558,"emotional_phrase":[{"form":"Würzig","emotion":"N"}]},"status":0,"message":"OK"}

$ echo "Heute ist Sukiyaki. Warum isst du so etwas?" | ./coto.py sentiment
{"result":{"sentiment":"Neutral","score":0.3482213983910368,"emotional_phrase":[]},"status":0,"message":"OK"}

$ echo "Heute ist Sukiyaki. In Ordung." | ./coto.py sentiment
{"result":{"sentiment":"Positive","score":0.0976613052132079,"emotional_phrase":[{"form":"Yosha","emotion":"Jubeln"}]},"status":0,"message":"OK"}

Hmmm, die Emotionsanalyse scheint ohne leicht verständliche Ausdrücke nicht erfasst zu werden. Ich muss über viele Dinge nachdenken.

Mit diesem Gefühl können Sie die API jetzt frei aufrufen, wie sie ist. Ich dachte, nachdem ich es gemacht habe, aber wenn ich 1000 Anrufe tätige, brauche ich kein Bargeld (hey)

Schaben, um Dajare zu bringen

Übrigens werde ich einen verspielten Dajare aus dem verdammten Blog mitbringen, den ich früher geschrieben habe. Beim Scraping wird die bekannte (?) Schöne Suppe in "Lassen Sie Python die langweiligen Dinge tun" verwendet. Sie können diesen Artikel in 10 Minuten verstehen.

Es ist arm, also werde ich das auch zwischenspeichern. Lieblingsgeld. Ich werde mein Bestes tun, um mir die HTML-Quelle anzusehen und den Artikelteil zu extrahieren. Lassen Sie uns einen Artikelinhalt anzeigen, der von get_text analysiert wurde.

scrape.py


if not os.path.exists("hijili/top"):
    res = requests.get("https://ameblo.jp/hijili/")
    res.raise_for_status()
    os.makedirs("./hijili/")
    with open("./hijili/top", mode="w") as f:
        f.write(res.text)

with open("hijili/top", mode="r") as f:
    top_soup = bs4.BeautifulSoup(f, 'html.parser')

top_soup.find('entryBody')
bodies = [n.get_text() for n in top_soup.select('div#entryBody')]

print(bodies[1])
$ python scrape.py
Als ich über Katana sprach, fand ich es gut, zurückkehren zu können "Ich habe es vor langer Zeit gekauft" (1 Beleg). Ich dachte, ich hätte gewonnen, obwohl ich es nicht gesagt habe. (2 Slip) Es ist nicht ernst zu sagen, dass ich es gekauft habe. (3 Belege, die ernsthaft ansprechen)

Es gibt so viel scheißartigen Mist, also kannst du ihn so oft analysieren, wie du willst! Ich habe etwas gewählt, das relativ leicht zu verstehen scheint (ich bin mir nicht sicher, wie der "ernsthafte" Teil involviert ist ...). Der Teil "(N Slip)", der das Versprechen dieses Blogs ist, scheint jedoch die Analyse zu stören, also werde ich ihn schneiden.

# bodies = [n.get_text() for n in top_soup.select('div#entryBody')]
bodies = [re.sub('([^)]*Schieben)', '', n.get_text()) for n in top_soup.select('div#entryBody')]
$ python scrape.py
Als ich über Katana sprach, fand ich es gut, zu ihm zurückkehren zu können: "Ich habe es vor langer Zeit gekauft." Ich dachte, ich hätte gewonnen, obwohl ich es nicht gesagt habe. Selbst wenn ich sage, ich habe es gekauft, ist es nicht ernst.

In Ordnung, dies sollte COTOHA leicht lesbar machen.

Spielen Sie mit Dajare mit der COTOHA API

Lassen Sie es uns vorerst mit der COTOHA-Klasse durch die Gashigashi-API führen. Als Erwartung möchte ich einen Hinweis bekommen, der Dajare als Dajare beurteilt ...

#einpacken
{"result":"Als ich über Katana sprach, fand ich es gut, zu ihm zurückkehren zu können: "Ich habe es vor langer Zeit gekauft."","status":0}

#Schlüsselwortextraktion
{
  "result" : [ {
    "form" : "Ernst",
    "score" : 22.027
  }, {
    "form" : "Mund",
    "score" : 8.07787
  }, {
    "form" : "Geschichte",
    "score" : 7.23882
  } ],
  "status" : 0,
  "message" : ""
}

#Emotionsanalyse
{"result":{"sentiment":"Positive","score":0.06420815417815495,"emotional_phrase":[{"form":"War gut","emotion":"P"},{"form":"ich habe gewonnen","emotion":"P"},{"form":"Nicht ernsthaft","emotion":"PN"}]},"status":0,"message":"OK"}

#Benutzerattributschätzung(β)
{
  "result" : {
    "age" : "20-29 Jahre alt",
    "civilstatus" : "verheiratet",
    "hobby" : [ "CAMERA", "COOKING", "INTERNET", "MUSIC", "SHOPPING" ],
    "location" : "Kanto",
    "moving" : [ "WALKING" ],
    "occupation" : "Mitarbeiter"
  },
  "status" : 0,
  "message" : "OK"
}

Hmmm, was ist der Unterschied zwischen dem, was formatiert und zurückgegeben wird und dem, was nicht ... Nun, es ist okay, weil es von Python verarbeitet wird.

Fasst die Zusammenfassungs-API nicht zusammen, sondern gibt nur das zurück, was in einem langen Satz wichtig zu sein scheint?

Keyword-Extraktion, ich wollte, dass Sie Katana für diesen Satz extrahieren, aber es scheint, dass Sie das Dajare-Keyword nicht finden können ...

Es war nützlich, auch wenn ich meine Emotionen analysiert habe! Die Person selbst schreibt nur schlampig, also ist es immer positiv.

Schätzung der Benutzerattribute, hmm, ich habe das Gefühl, dass Spezifikationen, die dumm erscheinen, herauskommen, aber Sman, ich bin älter und Single.

Mit diesem Gefühl konnte ich die Wirksamkeit von Dajare nicht bestätigen ... (Das ist selbstverständlich).

Es besteht jedoch Hoffnung auf eine Erkennung von Spracherkennungsfehlern! Ein Wort, das ähnlich wie "ernst" klingt, kommt heraus!

#Spracherkennungsfehlererkennung(β)
{"result":{"score":0.7298996038673021,"candidates":[{"begin_pos":76,"end_pos":78,"form":"Ernst","detect_score":0.7298996038673021,"correction":[{"form":"Prüfung","correct_score":0.7367702251579388},{"form":"Literatur","correct_score":0.7148903980845676},{"form":"Nervös","correct_score":0.6831886720211694},{"form":"Shinken","correct_score":0.6443806737641236},{"form":"Nintendo","correct_score":0.6403453079473043}]}]},"status":0,"message":"OK"}

Nimm den Test ernst! (1 Beleg) Konzentrieren Sie Ihre Nerven auf den Test! !! (2 Slip) Ninken hat ernsthaft etwas untersucht (Nein, was ist Ninken wirklich !?)! !! !! (3 Slip)

Es scheint, dass COTOHA über Kandidaten für Dajare nachdenkt! Ich verstehe, sollte ich es so benutzen! (Falsch

Ich werde Dajare richtig entdecken

Ich habe einige dajare-ähnliche Ergebnisse erzielt, aber es scheint schwierig zu sein, dajare zu finden. Ich war jedoch der Meinung, dass es möglich sein würde, die Ergebnisse der Syntaxanalyse-API gut zu verwenden.

Das Ergebnis der Syntaxanalyse-API wird weggelassen, da es lang ist ... Sie können es schnell auf der Demo-Seite ausprobieren.

Was ich dachte war, wenn ich den längsten Teil mit demselben Vokal zwischen den durch diese syntaktische Analyse getrennten Klauseln finden würde, wäre es nicht verrückt? darüber.

Ich dachte, ich würde es vorerst versuchen, aber wie wäre es, "den längsten Teil mit demselben Vokal zu finden"? Ich frage mich, ob es möglich sein wird, es in Romaji zu konvertieren und [aiueo] zu extrahieren und es durcheinander zu bringen ... Suche ... Ich sehe, Pykakashi ist in der Python-Implementierung von KAKASI. Dann probieren wir mal die Konvertierung!

Versuchen Sie es mit pykakashi
kakasi = kakasi()  # Generate kakasi instance
kakasi.setMode("H", "a")  # Hiragana to ascii
kakasi.setMode("K", "a")  # Katakana to ascii
kakasi.setMode("J", "a")  # Japanese(kanji) to ascii
kakasi.setMode("r", "Kunrei")   #Einweisungszeremonie
conv = kakasi.getConverter()

res = coto.parse(data, 'default')
j = json.loads(res)

org_sentence = []
ascii_sentence = []
tmp_org_sentence = []
tmp_ascii_sentence = []
org_chunk = ""
kana_chunk = ""
for chunk_info in j['result']:
    for token in chunk_info['tokens']:
        is_end = False
        if token['form'] == '。' or token['form'] == '.' or token['form'] == '!':
            is_end = True
            break
        else:
            # chunk += conv.do(token['kana'])
            org_chunk += token['form']
            kana_chunk += token['kana']

    tmp_org_sentence.append(org_chunk)
    tmp_ascii_sentence.append(conv.do(kana_chunk))
    org_chunk = ""
    kana_chunk = ""
    if is_end:
        org_sentence.append(tmp_org_sentence)
        ascii_sentence.append(tmp_ascii_sentence)
        tmp_org_sentence = []
        tmp_ascii_sentence = []

print("org")
print(*org_sentence, sep='\n')
print("ascii")
print(*ascii_sentence, sep='\n')

Ergebnis.

org
['Katana', 'Sich unterhalten', 'War', 'manchmal', '"Alte Zeiten', 'Ich kaufte es. "', 'In Eile', 'Ich konnte zurückkehren', 'Es war gut', 'habe gedacht']
['ich habe gewonnen', 'habe gedacht,', 'Im Mund', 'Ich habe es nicht gelöscht']
['ich kaufte es', 'Nach alldem', 'Nicht ernsthaft']
ascii
['katanano', 'hanasio', 'siteita', 'tokini', 'mukasi', 'kattanaato', 'tossani', 'kaesetanoha', 'yokattato', 'omoimasita']
['kattanato', 'omoimasita', 'kutiniha', 'dasanakattakedo']
['kattanaato', 'ittemo', 'sinkendehaarimasen']

Oh, ich konnte es auf schöne Weise zerlegen. Dann werde ich das versuchen.

for i, osen in enumerate(org_sentence):
    c = find_dajare_candidate(ascii_sentence[i], osen)  #Ich kann es nicht so oft zeigen, wenn es sich in Zukunft gut anfühlt ...
    if not c:
        continue
    dump_candidate(c)
    print('----')

In find_dajare_candidate wird davon ausgegangen, dass ein Satz vorerst Dajare enthalten sollte, die Vokale jeder Phrase im Satz verglichen werden und der Teil mit der höchsten Anzahl von Übereinstimmungen als Kandidatendaten zurückgegeben wird.

Katana
Ich kaufte es. "
vowel: aaao  score:4
----
ich habe gewonnen
Ich habe es nicht gelöscht
vowel: aaao  score:4
----
ich kaufte es
Nicht ernsthaft
vowel: aaa  score:3
----

Nun, der erste ist richtig, aber der Rest ist subtil. Ich meine, ['Ich habe gewonnen', 'Ich dachte', 'in meinem Mund', 'Ich habe es nicht gesagt'] Im zweiten Satz enthält es kein Dajare, sondern nur den ersten Satz "Katana".

Wenn Sie dann versuchen, für einen Moment ein Vergleichsschlüsselwort einzugeben, damit Sie suchen können, indem Sie "katana" angeben ...

c = find_dajare_candidate(ascii_sentence[1], org_sentence[1], "katana")
dump_candidate(c)
print('----')
c = find_dajare_candidate(ascii_sentence[2], org_sentence[2], "katana")
dump_candidate(c)
ich habe gewonnen
vowel: aaa  score:3
----
ich kaufte es
vowel: aaa  score:3

Ich kann Sie bis zu einem gewissen Grad führen! Wenn Sie die Ähnlichkeit der Konsonanten richtig damit vergleichen können, scheint sich die Genauigkeit zu verbessern, okay, ich werde mein Bestes geben! !! !! !!








Das…?





** COTOHA ist nicht mehr relevant! Es ist im Herzen ziemlich irrelevant! !! ** (Haraichi-Geschmack)



Ende Produktion / Schreiben          ━━━━━           ⓃⒽⓀ

abschließend

Wie war der Artikel "Verwenden der COTOHA-API ~~, um mit Dajare ~~ zu spielen"? Es schien COTOHA unmöglich, Dajare zu entdecken, aber es schien, dass er Hinweise für Dajare bekommen und es als Grundlage für die Analyse verwenden konnte.

Ich hoffe, jemand wird ein Kind, das COTOHA verwendet. (1 Beleg)

Mein Engagement für einen solchen Dajare ist in Mach New Book Like Fucking beschrieben. Bitte sehen Sie, ob Sie zu frei sind, um zu sterben.

Ich meine, ich interessiere mich für das vorliegende Projekt und bin dankbar dafür, weil es viel mehr Spaß macht. Ich werde diese schillernde Analyse für eine Weile fortsetzen (obwohl ich es satt habe).

Recommended Posts