COTOHAは人間を超えるのか？日本語検定に挑戦！

# COTOHA APIとは
NTTコミュニケーションズが提供する自然言語や音声を処理してくれるAPIで、主にできることは下記となります。

- 構文解析
- 固有表現抽出
- 固有名詞(企業名)補正
- 照応解析
- キーワード抽出
- 類似度判定
- 文タイプ判定
- ユーザ属性推定
- 言い淀み除去
- 音声認識誤り検知
- 感情分析
- 音声認識
- 音声合成
- 要約

詳しくは[こちら](https://api.ce-cotoha.com/contents/index.html)
今回はこの中から類似度判定を用いて日本語検定に挑戦してみました。

#日本語検定とは
日本語検定委員会が運営する総合的な日本語能力を測る試験です。
漢字、表記、敬語、言葉の意味、語彙、文法、総合の7項目がありますが
今回は[こちら](https://www.nihongokentei.jp/check/)に公開されている例題から語彙の類義語問題に挑戦してみます。

# いざ日本語検定にチャレンジ
使用するコードは下記のようになっています。
選択肢の数と問題を入力後、それぞれのスコアと最終的な解答を出力するようになっています。

```python:kentei.py
# -*- coding: utf-8 -*-
import os
import json
import requests
import pickle

CLIENT_ID = 'XXX'
CLIENT_SECRET = 'XXX'
API_BASE_URL = 'https://api.ce-cotoha.com/api/dev/nlp/'
ACCESS_TOKEN_PUBLISH_URL = 'https://api.ce-cotoha.com/v1/oauth/accesstokens'

def get_access_token():
    headers = {'Content-Type': 'application/json',
               'charset': 'UTF-8',}
    data = {'grantType':'client_credentials',
            'clientId':CLIENT_ID,
            'clientSecret':CLIENT_SECRET}
    data = json.dumps(data)
    response = requests.post(ACCESS_TOKEN_PUBLISH_URL, headers=headers, data=data)
    response = json.loads(response.text)
    return response['access_token']

if not os.path.isfile('./ACCESS_TOKEN.pickle'):
    ACCESS_TOKEN = get_access_token()
    with open('ACCESS_TOKEN.pickle', mode='wb') as f:
        pickle.dump(ACCESS_TOKEN, f)
with open('ACCESS_TOKEN.pickle', mode='rb') as f:
    ACCESS_TOKEN = pickle.load(f)

def similarity(s1,s2):
    global ACCESS_TOKEN
    headers = {'Content-Type': 'application/json',
               'charset': 'UTF-8',
               'Authorization': 'Bearer '+ACCESS_TOKEN}
    data = {'s1':s1,
            's2':s2}
    data= json.dumps(data)
    response = requests.post(API_BASE_URL+'v1/similarity', headers=headers, data=data)
    response = json.loads(response.text)
    if response['status'] == 99998:
        ACCESS_TOKEN = get_access_token()
        with open('ACCESS_TOKEN.pickle', mode='wb') as f:
            pickle.dump(ACCESS_TOKEN, f)
        return similarity(a,b)
    return response['result']['score']


if __name__ == "__main__":

    print('問題の単語を入力してください')
    question_word= str(input())
    best_score = 0
    print('選択肢を入力してください')
    words = list(map(str, input().split()))
    score = [0] * len(words)
    for i in range(len(words)):
        score[i] = similarity(question_word, words[i])
        if best_score < score[i]:
            best_score = score[i]
            ans = words[i]

    print(*score)
    print('解答: ', ans)
```

## まずは6級にチャレンジ
日本語検定は7級からですが、7級には語彙の問題がなかったので6級からスタートします。

```
$ python3 kentei.py 
問題の単語を入力してください
昼間
選択肢を入力してください
午後　正午　日中
0.9147314 0.5557229 0.96075547
解答:  日中
```

COTOHAは「日中」と解答し無事正解です。「午後」も比較的スコアが高いですが「日中」は0.96ととても類似度が高いことが伺えます。

## 5級にチャレンジ

```
$ python3 kentei.py 
問題の単語を入力してください
若者
選択肢を入力してください
成人　青年　学生
0.3319944 0.9027622 0.87224585
解答:  青年
```

「青年」と解答し、無事正解です！

## 4級にチャレンジ
4級で公開されている類義語問題は3問ありました。せっかくなので全部解いてみます。

```
$ python3 kentei.py 
問題の単語を入力してください
柔和
選択肢を入力してください
温厚　温暖　温情
0.9725942 0.13772435 0.41027611
解答:  温厚

$ python3 kentei.py 
問題の単語を入力してください
故国
選択肢を入力してください
列国　亡国　母国
0.39822352 0.55082643 0.95943063
解答:  母国

$ python3 kentei.py 
問題の単語を入力してください
つぶさに
選択肢を入力してください
うるさく　くわしく　ひらたく
0.05732418 0.059113827 0.133314
解答:  ひらたく
```

模範解答は順に「温厚」、「母国」、「くわしく」でした。
4級の3問目にしてCOTOHA初の不正解です。（でも「つぶさに」なんて滅多に使わないですよね）
2/3正解ということで続いて3級に挑戦

## 3級にチャレンジ

```
$ python3 kentei.py 
問題の単語を入力してください
横柄
選択肢を入力してください
誇大　偉大　尊大
0.2001897 0.6117739 0.99001247
解答:  尊大
```

圧倒的スコアで「尊大」を解答し、無事正解です。
横柄も難しいと思うのですがCOTOHAすごい・・・

## 2級にチャレンジ

```
$ python3 kentei.py 
問題の単語を入力してください
昵懇
選択肢を入力してください
懇篤　懇情　懇懇　懇意
0.05732418 0.05732418 0.05732418 0.05732418
解答:  懇篤
```

もはや僕が問題になっている単語の読み方すらわかりませんが「懇篤」で残念ながら不正解！
・・・と思いきや **全部のスコアが同一** になっています。
このようなことが起きるとは想定しておらず、先ほど掲載しているコードでスコアが今までの選択肢より大きかった場合、解答を更新するようにしていたため今回のように全て同一のスコアだと一番最初のものが出力されてしまいました。

```python:kentei.pyから一部抜粋
score[i] = similarity(question_word, words[i])
if best_score < score[i]:
    best_score = score[i]
```

COTOHAもお手上げの難易度で鉛筆を転がすしかないといった状況ですね。


## いよいよ1級にチャレンジ
ここまで来たのでせっかくだから1級にもチャレンジ

```
python3 kentei.py 
問題の単語を入力してください
余蘊がない
選択肢を入力してください
誤謬がない 不足がない 無理がない 不満がない
0.99806935 0.99449587 0.9970721 0.9951513
解答:  誤謬がない
```
もはや単語ですらありませんが残念ながら正解は「不足がない」で不正解！
1級はかなり難しいですね・・


# まとめ
今回はCOTOHA APIを使って日本語検定にチャレンジしてみました！
例題の数問しか解いていないので一概に〇級！とは言えませんが一般的な単語の類似度はかなり取れていたのではないかと思います。
今後は1級問題もクリアできるようCOTOHA APIの益々の成長を祈っております！