COTOHA APIは漫才を理解できるのか、調査したらまずまずだった

#はじめに
本記事は、[Qiita x COTOHA APIプレゼント企画](https://zine.qiita.com/event/collaboration-cotoha-api/)にエントリーしています。

#COTOHA APIとは？
NTTコミュニケーションズ社が提供するNTTグループの40年以上の研究成果を活かした自然言語処理技術や音声認識・合成技術を、APIでお手軽に利用できるよう提供しているサービスです。

構文解析や固有表現抽出などの自然言語処理や、特徴的な「要約」や「ユーザ属性推定」なども利用可能。


■サービス紹介リンク
https://api.ce-cotoha.com/contents/index.html

#ミルクボーイさんとは？
ミルクボーイは、吉本興業に所属する男性お笑いコンビ。2007年7月結成。2019年M-1王者。

>M-1 1stステージでは「コーンフレーク」を題材に、コーンフレークに該当しそうな特徴と該当しなさそうな特徴を軽妙な掛け合いにあわせて展開するネタを披露。
歴代最高得点となる「681点」を記録！
[ネタはこちら](https://www.youtube.com/watch?v=VjBQtr4lH0k)

＝＝＝技術関係なくなるので割愛＝＝＝

#調査してみた
ようやく本題です。このミルクボーイの漫才は「対象物にあてはまりそうな特徴」と「あてはまらなさそうな特徴」を繰り返して笑いを生み出しています。
この漫才はもしかして、意味読解が得意なAI、つまりCOTOHAなら理解できるのでは？


*注釈：「理解できる」というだけで、面白さやユーモアは対象にしていません* 

**まずは認証しよう**
・COTOHA APIには無料のDeveloperプランがあるのでまずは登録。
・ポータルから、Client IDとClient Secretを取得

```python
#PythonでCOTOHA APIの認証

import requests,json

def authorization():
    cotoha_url_auth = "https://api.ce-cotoha.com/v1/oauth/accesstokens"
    headers = {"Content-Type" : "application/json"}
    data = {
        "grantType" : "client_credentials",
        "clientId" : cotoha_clientId,          #ここにユーザ固有の値
        "clientSecret" : cotoha_clientSecret   #ここにユーザ固有の値
    }

    res = requests.post(cotoha_url_auth, headers=headers, json=data)
    token = json.loads(res.text)["access_token"]
    #print("COTOHA API 認証しました")
    
    return token #アクセストークンの文字列を返して終わり
```

**類似度判定APIを使ってみる**
今回使うのはCOTOHA APIの中でも**「類似度判定」**を使います
>類似度判定とは？
2つの文における意味的な類似度を算出するRESTful API です。
>類似度は0-1の定義域で出力し、1に近づくほど２つの文において類似性が大きいことを示します。
>文章に含まれる単語の意味情報を用いて類似度を算出しているため、異なった単語を含むテキスト間の類似性も推定することができます。

```python
#類似度判定
def similar(sentence1, sentence2, token):
    url =  "https://api.ce-cotoha.com/api/dev" + "/nlp/v1/similarity"
    header = {
        "Content-Type" : "application/json;charset=UTF-8",
        "Authorization" : "Bearer "  +token
    }
    data = {
        "s1" : sentence1,
        "s2" : sentence2
    }
    req = requests.post(url, headers = header, json = data)
    return req.text
```
`token`には先ほどの認証で出力されたAccesstokenを使ってください。
文を2つ並べて、リクエストすれば類似度が返ってきます。

例　：（"私は運動が得意です", "僕はスポーツが大好きです"）
⇒類似度： {'result': {'score': 0.94150746}, 'status': 0, 'message': 'OK'}

同じ単語はほぼないのに、この一致率・・・！素晴らしい！


**さあいよいよコーンフレーク判定だ**
前置きが長くなりましたが、先ほどの二つを組み合わせて、さらっと加工して、
入力された文がコーンフレークかどうかを判定する関数を作りました。

```python
#コーンフレーク関数
def cornflake(sentence, obj = "コーンフレーク"):
    try: 
        token = authorization()
        sim = float(json.loads(similar(obj, sentence, token))["result"]["score"])
        if sim>0.4:
            rep = "それ、" + obj + "やないかい!（類似度:{:.2f}）".format(sim)
        else:
            rep = "ほな" + obj + "とちゃうなぁ（類似度:{:.2f}）".format(sim)
    except:
        rep = "APIリクエスト時にエラーが発生しました"
    return rep
```
作りました。無駄に、引数`obj`を指定すればコーンフレーク以外も判定できる仕様です。

**調査開始** 

**注意：ここから先は、「ミルクボーイ」さんのネタバレを含みます。ご注意ください！！**




>おかんの好きな朝ごはん一緒に考えてあげるから、どんな特徴言うてたかとか教えてみてよ。

 `cornflake("甘くてカリカリしてて牛乳とかかけて食べる")`
 
出力：'それ、コーンフレークやないかい!（類似度:0.74）'

 `cornflake("おかんが言うには、死ぬ前の最後のご飯もそれでいい。")`

出力：'ほなコーンフレークとちゃうなぁ（類似度:0.25）'


`cornflake("なんであんなに栄養バランスの五角形が広いのかわからない。")`

出力： 'ほなコーンフレークとちゃうなぁ（類似度:0.16）'

`cornflake("食べてるとき生産者の顔が浮かばない。")`
出力： 'それ、コーンフレークやないかい!（類似度:0.56）'

`cornflake("おかんが言うには、ジャンルでいうなら中華。")`

出力：'ほなコーンフレークとちゃうなぁ（類似度:0.15）'




# 結果講評

**コーンフレークのような気もしてきた。。。**
今回使った類似度判定は、あくまで  *「文と文の意味的類似度を判定する」* ものなのですが、それが *「対象物の特徴を持っているかどうかを判定する。」* という目的でも**まあまあの精度** になるようです。
（上記以外にもいろいろ試しましたが、全体的に類似度が低く出る傾向でした。

考えてみれば、「コーンフレーク」と「栄養バランスの五角形が広い」は同じ意味ではないので、それはそうですね。。。

#オチ
`cornflake("日本語に強いサービスを提供している会社があるらしい","NTT")`

出力：'それ、NTTやないかい!（類似度:0.44）'


どうも、ありがとうございましたー。