COTOHA APIを使ってDIOっぽいセリフを生成ッ！

# 背景ッ！

[オレ プログラム ウゴカス オマエ ゲンシジン ナル](https://qiita.com/Harusugi/items/f499e8707b36d0f570c4)
[「募ってはいるが、募集はしていない」 人たちへ](https://qiita.com/omiita/items/0f811f15e569bf2539b8)

上の二つの記事に感銘を受け、似たような記事を書いてみたくなりました
[COTOHA API](https://api.ce-cotoha.com/contents/index.html)を使って、漫画[『ジョジョの奇妙な冒険』](https://ja.wikipedia.org/wiki/ジョジョの奇妙な冒険)に登場するカリスマ的悪者DIOっぽいセリフの生成に挑戦しました
(初投稿です、お手柔らかに🙇‍♂️)

こんな感じになります

```
$ python TheWorld.py 僕はお腹が空いた。
このDIOはお腹が空いたッ！
$ python TheWorld.py 人生は楽しい！
人生は楽しいッ！最高に「ハイ！」ってやつだアアアアアアハハハハハハハハハハーッ 
$ python TheWorld.py 辛いよ。。。。
頭痛がする は...吐き気もだ... くっ...ぐう な...なんてことだ... このDIOが...... 気分が悪いだと？？辛いよッ！
```

# 環境
MacOS High Sierra
Python3
COTOHA API

# やったことッ！

COTOHA APIの処理結果を基に、ルールベースアプローチで入力文を修正していきます
主に5つの処理を行いました
1. 人称代名詞の修正
2. 文末修正
3. 無駄ラッシュ
4. 言い澱み処理
5. 感情分析

1.2.3.には「構文解析」
4.には「言い澱み除去」
5.には「感情分析」のAPIを使っています

### 1. 人称代名詞の修正
- DIOっぽさの一つの要素
- 特定単語のカタカナが一致した場合修正します

#### 一人称
私、僕、俺 → このDIO
#### 二人称
君、あなた → 貴様
#### 三人称
固有名詞の場合、「承太郎」に変更

### 2. 文末修正
- ジョジョキャラっぽさを出していきます
- 正規表現を用いて文末の？や！といった記号は削除され、「ッ！」になる

「〇〇だ。」 → 「〇〇だッ！」
「〇〇だ。、、、。。」 → 「〇〇だッ！」

### 3. ラッシュ
- DIOを表現する上で欠かせない要素
- 「無駄」一単語に付き、5回ラッシュする

「無駄。」　→ 「無駄無駄無駄無駄無駄。」

### 4. 言い澱み除去
- DIOは言い澱まないので、言い澱みを消去します

「えーとんーと元気です。」 → 「元気です。」

### 5. 感情分析
- DIOの感情(喜・哀)を表現
- テンションが上がると、*「最高に「ハイ！」ってやつだアアアアアアハハハハハハハハハハーッ」*が文末に発生
    - 条件：["result"]["sentiment"]がPositiveであり、["result"]["score"]が0.5を超える
- 逆に追い込まれてテンションが下がると、*「頭痛がする　は…吐き気もだ　…な…なんということだこのDIOが…気分悪いだと？」*が文頭に発生
    - 条件：["result"]["sentiment"]がNegativeであり、["result"]["score"]が0.5を超える

※ 例文は[背景ッ！](#背景ッ)参照

(ここの言葉選びが一番楽しかった、皆さんも是非お気に入りの言葉に差し替えてみてください笑)

#コード

<details><summary>クリックッ！</summary><div>

```python:TheWorld.py

import requests
import json
import sys
import re

DEVELOPER_API_BASE_URL = "https://api.ce-cotoha.com/api/dev/nlp/"
CLIENT_ID = "自分のID"
CLIENT_SECRET = "自分のシークレットコード"

def getAccessToken(client_id, client_secret):
    token_url = "https://api.ce-cotoha.com/v1/oauth/accesstokens"
    headers = {
        "Content-Type": "application/json",
        "charset": "UTF-8"
    }

    data = {
        "grantType": "client_credentials",
        "clientId": client_id,
        "clientSecret": client_secret
    }
    r = requests.post(token_url,
                    headers=headers,
                    data=json.dumps(data))
    return r.json()["access_token"]

# 言い淀み除去APIを実行
def remove_filler(text):
    url = DEVELOPER_API_BASE_URL + "beta/remove_filler"
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer "+ access_token
    }
    data = {
        "text": text,
        "do_segment": False
    }
    r_post = requests.post(url, headers=headers, json=data)
    r_json = r_post.json()
    return r_json

# 感情分析APIを実行
def sentiment(sentence):
    url = DEVELOPER_API_BASE_URL + "v1/sentiment"
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer "+ access_token
    }
    data = {
        "sentence": sentence
    }
    r_post = requests.post(url, headers=headers, json=data)
    r_json = r_post.json()
    return r_json

def parse(sentence):
    url = DEVELOPER_API_BASE_URL + "v1/parse"
    headers = {
        "Content-Type": "application/json",
        "Authorization": "Bearer "+ access_token
    }
    data = {
        "sentence": sentence       
    }
    r_post = requests.post(url, headers=headers, json=data)
    r_json = r_post.json()
    return r_json

if __name__ == "__main__":
    args = sys.argv
    if len(args) >= 2:
        sentence = str(args[1])

    access_token = getAccessToken(CLIENT_ID, CLIENT_SECRET)

    # 処理１：言い澱み除去
    rf_json = remove_filler(sentence)
    sentence2 = rf_json["result"][0]["fixed_sentence"]
    
    # 処理2：人称代名詞の変換
    parse_json = parse(sentence2)
    original_list = []
    result_list = []
    for chunk in parse_json["result"]:
        # 形態素ごとに分割
        for token in chunk["tokens"]:
            # 1人称修正
            if token["kana"] in ["ワタシ","オレ","ボク"]:
                # print("このDIO")
                result_list.append("このDIO")
            # 2人称修正
            elif token["kana"] in ["キミ","アナタ"]:
                result_list.append("貴様")
            # 3人称修正
            elif "固有" in token["features"]:
                result_list.append("承太郎")
            # 処理３：無駄ラッシュ処理
            elif token["kana"] == "ムダ":
                result_list.append("無駄無駄無駄無駄無駄")
            else:
                result_list.append(token["form"])
            original_list.append(token["form"])
    # 処理4：文末処理
    s=''.join(result_list)
    if re.search("([^一-龥ぁ-ん|ァ-ヶ|0-9|a-zA-Z]){1,}$",s):
        script = re.sub("([^一-龥ぁ-ん|ァ-ヶ|0-9|a-zA-Z]){1,}$","ッ！",s)
    else:
        script = s + "ッ！"

    # 処理５：感情分析
    sentiment_json_original = sentiment(sentence)
    if sentiment_json_original["result"]["sentiment"] == "Positive" and sentiment_json_original["result"]["score"] > 0.5:
        script = script + "最高に「ハイ！」ってやつだアアアアアアハハハハハハハハハハーッ "
    elif sentiment_json_original["result"]["sentiment"] == "Negative" and sentiment_json_original["result"]["score"] > 0.5:
        script = "頭痛がする は...吐き気もだ... くっ...ぐう な...なんてことだ... このDIOが...... 気分が悪いだと？？" + script
  
    print(script)
```
</div>

# 結果ッ！

<details><summary>クリックッ！</summary><div>

```
$ python TheWorld.py 今日も良い１日でした！君のお陰だよ！
今日も良い1日でした!貴様のお陰だよッ！
$ python TheWorld.py 明日は田中君と遊ぶ。
明日は承太郎君と遊ぶッ！
$ python TheWorld.py ﾎﾞｸは風呂に入るわ・・
このDIOは風呂に入るわッ！
$ python TheWorld.py 無駄無駄… 悲しいよ．．
無駄無駄無駄無駄無駄無駄無駄無駄無駄無駄... 悲しいよッ！
$ python TheWorld.py 僕は二郎ラーメンが好きです。
このDIOは承太郎ラーメンが好きですッ！最高に「ハイ！」ってやつだアアアアアアハハハハハハハハハハーッ 
```

</div>
# まとめと展望ッ！
今回はCOTOHAを使って、DIOっぽい文の生成を行いました
結果は、、、、多少はDIOぽくなったのかな…？笑
ルールベースとしては欠陥過ぎるプログラムでした…、もっと厳密に設定しないとダメですね
今後は、マルコフ連鎖ライブラリ等を使って自動生成にも挑戦してみたいです
データ量の問題がありそうですが笑

また、COTOHA APIの様々な機能に触れられたことは良い経験になりました

ありがとうございましたッ！