ギョギョ！すギョい！さかなクン語話せるんすか（笑）

<img width="1438" alt="スクリーンショット 2020-03-02 13.27.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208081/b8d493f5-e0e2-d7be-f9fc-e243a369c58d.png">
日本語のための自然言語処理・音声処理APIプラットフォーム [COTOHA APIキャンペーン](https://zine.qiita.com/event/collaboration-cotoha-api/)やってたんで、COTOHA APIでさかなクン語に変換するお楽しみサイトを作ってみました！ちなみに、最近の[COTOHA API記事一覧](https://dogakiitaa.site/api.html?q=COTOHA%20API&o=d)、キャンペーンの影響で、関連記事数増えてますね。

##さかなクン語とは
ハコブク帽子をかぶって国会にも登場した**お魚博士さかなクン**。ここまで成立したキャラは今までみたことがありません。魚への熱い情熱、深い知識、歩みを止めない行動力、エンジニアとして学ばさせていただく点が多いにある方だと思います。

ここでは、お魚博士**さかなクンが使う言葉を「さかなクン語」**と呼ぶことにします。会話や文書の中で「ギョギョ」と魚の「ぎょ」「ギョ」を匠に使うのが特徴です。さかなクン語にはいくつかパターンがあるようです。

- 基本的に**丁寧語**を使う
- **「ご」を「ギョ」**に変える。ただし地名や名称の場合は変えない。
- 「一期一会（いちごいちえ）」など読みに**「ご」が入っている漢字は、「魚」(ギョ)**に変える。
- テンションや驚いた時に「**ギョギョ！**」といいがち

このパターンから単に正規表現で「ご」を「ギョ」に変えるだけでは実現できないということがわかります。そのため、COTOHA APIで**固有表現抽出、構文解析と感情分析**を使用して次の処理をすることにしました。

1. 固有表現抽出で、「ORG:組織名」「PSN:人名」「LOC:場所」「ART:固有物名」を除きます。
2. 構文解析で「ご」を「ぎょ」に、読みに「ご」が入っている漢字は、「魚」(ギョ)に変えます。
3. 感情分析から「驚く」「興奮」と判定された文のはじめに「ギョギョ！」を追加します。

##COTOHA APIの使い方（PHP）

###COTOHA APIを使用する流れ

1. [for Developers 無料登録](https://api.ce-cotoha.com/contents/developers/index.html)から登録します。
<img width="1432" alt="スクリーンショット 2020-03-02 13.27.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208081/4b59b991-a6e9-7167-f0cc-0d2ccf1d971f.png">
登録してログインすると、「**Access Token Publish URL**」「**API Base URL**」や認証情報の「**Client ID**」「**Client secret**」がわかります。

2. アクセストークンを取得するため、認証情報の「**Client ID**」「**Client secret**」を「**Access Token Publish URL**」へ送信します。
3. 取得したアクセストークン利用して、各APIを呼び出します。

###アクセストークンを取得する

**アクセストークンの有効期間は24時間**なので、1日置きにアクセストークンを取得する必要があります。

```php:アクセストークン取得(PHP)
$url = [Access Token Publish URL];    //自分のに書き換えてください
$header = [
    'Content-Type:application/json'
];
$data = [
    'grantType' => 'client_credentials',
    'clientId' => Client_ID,    //自分のに書き換えてください
    'clientSecret' => Client_secret,    //自分のに書き換えてください
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

$json = curl_exec($ch);
curl_close( $ch );

//アクセストークン
$ac = $json["access_token"];

```

###固有表現抽出

固有表現抽出APIに文を送ります。オプションとして、「type」を選べます。SNSなどの崩れた文、kizunaを選んでみました。「ORG:組織名」「PSN:人名」「LOC:場所」「ART:固有物名」は、除外キーワードに入れます。

「権造さんこちらは、五所川原市でございますよ！」という文で試してみたいと思います。「権造さん」と「五所川原市」が固有表現として抽出されるのを期待します。

```php:固定表現抽出APIを呼ぶ(PHP)
$str = "権造さんこちらは、五所川原市でございますよ！";

$url = [API Base URL]/nlp/v1/ne;    //自分のに書き換えてください
$header = [
    'Content-Type:application/json;charset=UTF-8',
    'Authorization:Bearer '.$ac   //アクセストークン
];
$data = [
    'sentence' => $str,
    'type' => 'kuzure'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

$json = curl_exec($ch);
curl_close( $ch );

$NE = json_decode($json, true);

$exclude_words = [];
foreach($NE["result"] as $res){
  if($res["class"] == "LOC" || 
    $res["class"] == "ORG" || $res["class"] == "ART" || $res["class"] == "PSN"){
      $exclude_words[] = $res["form"];
  }
}
```

おお！ 「権造」は「人名」、「五所川原市」は「場所」として抽出されました！ 地名や名称は、さかなくん語に変換しないので、除外キーワードに入れます。


```php:固定表現抽出APIから返ってきた結果
array(0) {
}
array(3) {
  ["result"]=>
  array(2) {
    [0]=>
    array(7) {
      ["begin_pos"]=>
      int(0)
      ["end_pos"]=>
      int(2)
      ["form"]=>
      string(6) "権造"
      ["std_form"]=>
      string(6) "権造"
      ["class"]=>
      string(3) "PSN"
      ["extended_class"]=>
      string(0) ""
      ["source"]=>
      string(5) "basic"
    }
    [1]=>
    array(7) {
      ["begin_pos"]=>
      int(9)
      ["end_pos"]=>
      int(14)
      ["form"]=>
      string(15) "五所川原市"
      ["std_form"]=>
      string(15) "五所川原市"
      ["class"]=>
      string(3) "LOC"
      ["extended_class"]=>
      string(0) ""
      ["source"]=>
      string(5) "basic"
    }
  }
  ["status"]=>
  int(0)
  ["message"]=>
  string(0) ""
}
```

###構文解析

続いて、構文解析APIに文を送ります。こちらも「type」をkuzureにしてみました。除外キーワード以外、「ご」を「ぎょ」に、読みに「ご」が入っている漢字は、「魚」(ギョ)に変えます。「ご」と読む漢字をリスト化しました。

「権造さん出会いは、一期一会でございますね！」で試してみます。

```php:構文解析APIを呼ぶ(PHP)

$str = "権造さん出会いは、一期一会でございますね！";

$url = [API Base URL]/nlp/v1/parse;    //自分のに書き換えてください
$header = [
    'Content-Type:application/json;charset=UTF-8',
    'Authorization:Bearer '.$ac
];
$data = [
    'sentence' => $str,
    'type' => 'kuzure'
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

$json = curl_exec($ch);
curl_close( $ch );

$parse = json_decode($json, true);

$kanjis = ["互","五","伍","冱","冴","午","后","吾","呉","唔","圄","圉","娯","寤","巨","後","御","忤","悟","晤","朞","期","梧","棊","棋","檎","沍","牛","牾","珸","瑚","碁","禦","篌","糊","胡","茣","蜈","衙","語","誤","護","迓","醐","雇","麌","齬"];

$sentence = "";
foreach($parse["result"] as $res){
  foreach($res["tokens"] as $token){
    if(strpos($token["kana"], "ゴ") !== false && !in_array($token["form"], $exclude_words) ){
      $token["form"] = mb_ereg_replace("ご", "ギョ", $token["form"]);
      foreach($kanjis as $kanji){
        if(strpos($token["form"], $kanji) !== false){
          $token["form"] = mb_ereg_replace($kanji, "魚", $token["form"]);
        }
      }
    }
    $sentence .= $token["form"];  
  }
}

```
 「権造」の読みが、「ケンヅクリ」となっていますが(汗)、こういうのは、辞書の補完したらちゃんと認識してくれるものだと思うので問題ないですね（笑）「ござ」と「一期一会」を取得できたので、「ギョざ」、「一魚一会」に変えます。

```php:構文解析APIから返ってきた結果
array(3) {
  省略〜
      ["tokens"]=>
      array(2) {
        [0]=>
        array(7) {
          ["id"]=>
          int(0)
          ["form"]=>
          string(6) "権造"
          ["kana"]=>
          string(15) "ケンヅクリ"
          ["lemma"]=>
          string(6) "権造"
          ["pos"]=>
          string(6) "名詞"
          ["features"]=>
          array(0) {
          }
          ["attributes"]=>
          array(0) {
          }
        }
   省略〜
      ["tokens"]=>
      array(7) {
        [0]=>
        array(8) {
          ["id"]=>
          int(5)
          ["form"]=>
          string(12) "一期一会"
          ["kana"]=>
          string(18) "イチゴイチエ"
          ["lemma"]=>
          string(12) "一期一会"
          ["pos"]=>
          string(6) "名詞"
          ["features"]=>
          array(0) {
          }
  省略〜
        [2]=>
        array(7) {
          ["id"]=>
          int(7)
          ["form"]=>
          string(6) "ござ"
          ["kana"]=>
          string(6) "ゴザ"
          ["lemma"]=>
          string(9) "御座る"
          ["pos"]=>
          string(12) "動詞語幹"
          ["features"]=>
          array(1) {
            [0]=>
            string(2) "RX"
          }
          ["attributes"]=>
          array(0) {
          }
        }
  省略〜    
}
```
###感情分析

感情分析を「権造さん、精神が高揚していますね！」で試してみました。

```php:感情分析APIを呼ぶ(PHP)

$str = "権造さん、精神が高揚していますね！";

$url = [API Base URL]/nlp/v1/sentiment;    //自分のに書き換えてください
$header = [
    'Content-Type:application/json;charset=UTF-8',
    'Authorization:Bearer '.$ac
];
$data = [
    'sentence' => $str,
];

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);

$json = curl_exec($ch);
curl_close( $ch );

$addword = "";
$emotion = json_decode($json, true);
foreach($emotion["result"]["emotional_phrase"] as $phrase){
  if($phrase["emotion"] == "興奮" || $phrase["emotion"] == "驚く"){
      $addword = "ギョギョ! ";
  }
}

$sentence = $addword.$sentence;

```
これもいいですね！「高揚」という言葉が、「興奮」と捉えられたようです！（笑）

```php:感情分析APIから返ってきた結果
array(3) {
  ["result"]=>
  array(3) {
    ["sentiment"]=>
    string(7) "Neutral"
    ["score"]=>
    float(0.39264444089599)
    ["emotional_phrase"]=>
    array(1) {
      [0]=>
      array(2) {
        ["form"]=>
        string(6) "高揚"
        ["emotion"]=>
        string(6) "興奮"
      }
    }
  }
  ["status"]=>
  int(0)
  ["message"]=>
  string(2) "OK"
}
```

###感想
API叩くだけなので、手軽にすぐ使えちゃいますね。

###参考
- [COTOHA API | NTTコミュニケーションズが開発した日本最大級の日本語辞書を活用した自然言語処理、音声認識APIプラットフォーム](https://api.ce-cotoha.com/contents/)
- [ギョギョ！さかなクン用語まとめ](https://matome.naver.jp/odai/2141787974344490501)

###付録
あなたもさかなクン語話してみませんか😊
[ギョギョ🐟 さかなクン語に変換！](https://haix.xyz/sakana)

ギョギョ！ Thanks you！ チャオ！ 再見！