(ﾃｯﾃｹﾃｯﾃｰﾃｰﾃﾃｰ)ミニドラ語翻訳機～

日本語を入力するだけで、ミニドラ語に翻訳してくれるひみつ道具を開発しました!

# はじめに

ミニドラが話すミニドラ語、という言葉をご存知ですか?
アニメでは「ドラドラ」とか「ドララ～」など、正規表現で表すと`^(ドー*ラ+ー*)+$`くらいのレパートリーです
しかし、漫画のほうでは
![10644063_761250850582759_516278085_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/56006/49a357b7-9fba-9c7d-d66d-ba60cf082131.jpeg)
と、`^(ドー*ラ+ー*)+$`に当てはまらない「スースーシーシーワーワーナーナー」と喋っているではありませんか!
ドラミちゃんのセリフから日本語に訳すると「すっかり調べて、悪いところを直しました」を言ってそうです

この「すっかり調べて、悪いところを直したよ」から「スースーシーシーワーワーナーナー」を開発しました

# 使用技術及び環境

* Python 3.7.0
* [COTOHA API](https://api.ce-cotoha.com/)

# 翻訳機の仕様

ドラえもん公式にミニドラ語のルール的なものは見つからなかったので、さっきの1コマからひねり出します
もし、ミニドラ語のルールがあったら教えて下さい

## 1コマからわかること

「スースーシーシーワーワーナーナー」 = 「すっかり調べて、悪いところを直したよ」
であるのはほぼ確定っぽそうです(「直したよ」は「直しました」や「直した」など、表記ゆれの可能性はあります)

否定も会話の流れからして、考えにくいです
「直しませんでした(直せませんでした)」と言っている人に「直してくれたの?」と聞き返すのは不自然かなと

## ミニドラ語と日本語を紐付け

次に、ミニドラ語と日本語が紐付けてみました
法則性として、単体で意味のある単語(自立語)の頭文字を繰り返すルールがありそうです
表にまとめると以下のようになります

|ミニドラ語|日本語|発声する音の頭文字
|---|---|---|
|スースー|すっかり|ス|
|シーシー|調べて|シ|
|ワーワー|悪いところを|ワ|
|ナーナー|直したよ|ナ|

## 日本語を解析

自立語の頭文字を繰り返すルールが分かったとなれば、あとはどれが自立語なのかがわかれば翻訳機の完成です
ここで、「すっかり調べて、悪いところを直したよ」をCOTOHA APIを使って解析してもらいました
COTOHA APIが提供するAPI一覧は[こちら](https://api.ce-cotoha.com/contents/api-all.html)になりますが、今回は構文解析を使いました
解析した結果をすべて載せたいところですが、冗長なので重要な部分だけをまとめました

|表記|品詞|
|---|---|
|すっかり|連用詞|
|調べ|動詞語幹|
|悪|形容詞語幹|
|直|動詞語幹|

どうやら、上の3品詞はミニドラ語の対象になりそうです
最初に言ってた自立語にも含まれてそうです(高校時代で勉強した内容の覚えている範囲で)
他にも自立後になりそうな品詞は以下くらいなので、それも対象にしています

* 名詞
* 連体詞
* 独立詞

## 名詞の精度を上げる

これで完成・・・かと思いきや、今回たまたま「すっかり調べて、悪いところを直したよ」の解析で見つけたので、対処できたのですが、「ところ」が名詞として判定されました
つまり、このまま実装すると「スースーシーシーワーワートートーナーナー」と、余計なものが出てきてしまいます
なので、この「トートー」を除外します
「ところ」の解析結果を見ると、以下のようになります

```json
{
    "id": 6,
    "form": "ところ",
    "kana": "トコロ",
    "lemma": "所",
    "pos": "名詞",
    "features": [],
    "dependency_labels": [
        {
            "token_id": 4,
            "label": "amod"
        },
        {
            "token_id": 7,
            "label": "case"
        }
    ],
    "attributes": {}
}
```

除外の判定に使えそうな部分が`dependency_labels`、依存関係ラベルのみなので、こちらを利用します
[リファレンス](https://api.ce-cotoha.com/contents/reference/apireference.html#parsing_io_dependency)を見ると、「ところ」は`token_id`が4の形態素に修飾されているとのこと
`token_id`が4、つまり`id`が4となっているのはここには載せていませんが「悪」です
どうやら、修飾対象になるものはミニドラ語からは発音されないルールになっていそうなので、`amod`は除外します

# 最終的なコード

以上を踏まえて実装したコードは以下になります

```py:minidorago.py
import requests
import json
import sys
import configparser

config_ini = configparser.ConfigParser()
config_ini.read('config.ini', encoding = 'utf-8')
BASE_URL = "https://api.ce-cotoha.com/api/dev/nlp/"
# 払い出されたCLIENT_IDとCLIENT_SECRETを直書きしてもOKです(コピペで誤って晒すのを防ぐためにconfigparser使いました)
CLIENT_ID = config_ini['CONOHA_CLIENT']['ID']
CLIENT_SECRET = config_ini['CONOHA_CLIENT']['SECRET']

def auth(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"]

def parse(sentence, access_token):
    base_url = BASE_URL
    headers = {
        "Content-Type": "application/json",
        "charset": "UTF-8",
        "Authorization": "Bearer {}".format(access_token)
    }
    data = {
        "sentence": sentence,
        "type": "default"
    }
    r = requests.post(base_url + "v1/parse",
                      headers=headers,
                      data=json.dumps(data))
    return r.json()

def exist_dependency_labels(labels, tag):
    for label in labels:
        if label["label"] == tag:
            return True
    return False

if __name__ == "__main__":
    # ミニドラ語に翻訳する文章
    sentence = "すっかり調べて、悪いところを直したよ"
    # 実行時に引数で翻訳する文章が与えられていたら、そっちを翻訳します
    args = sys.argv
    if len(args) >= 2:
        sentence = str(args[1])

    access_token = auth(CLIENT_ID, CLIENT_SECRET)
    parse_sentence = parse(sentence, access_token)
    result_list = list()
    # 翻訳対象の品詞を設定
    targets_pos = list()
    targets_pos.append("名詞")
    targets_pos.append("動詞語幹")
    targets_pos.append("形容詞語幹")
    targets_pos.append("連体詞")
    targets_pos.append("連用詞")
    targets_pos.append("独立詞")
    for chunks in parse_sentence['result']:
        for token in chunks["tokens"]:
            if token["pos"] in targets_pos:
                if not exist_dependency_labels(token["dependency_labels"], "amod"):
                    result_list.append(token["kana"][0] + 'ー')
                    result_list.append(token["kana"][0] + 'ー')

    # 翻訳結果を出力
    print(sentence)
    print('↓')
    print(''.join(result_list))
```

[オレ プログラム ウゴカス オマエ ゲンシジン ナル](https://qiita.com/Harusugi/items/f499e8707b36d0f570c4#%E3%82%B3%E3%83%BC%E3%83%89)にあるコードをベースに作成しています

# 実演

いろんな文章をミニドラ語にしてみました

```sh
$ python minidorago.py なんだ、いつものパターンか
なんだ、いつものパターンか
↓
ナーナーイーイーパーパー

$ python minidorago.py みんなのハート打ち抜くぞー
みんなのハート打ち抜くぞー
↓
ミーミーハーハーウーウー

$ python minidorago.py 俺の隣がインスタ映え
俺の隣がインスタ映え
↓
オーオートートーイーイーハーハー
```

ものによってはうなされているような・・・w

# 終わりに

これを使えばみんなもミニドラ語を話せるので、ミニドラのような可愛さで会話ができるように(?)なりました

```sh
$ python minidorago.py 最後までありがとうございました
最後までありがとうございました
↓
サーサーアーアー
```
~~伝わるかどうかは保証できません~~

# 参考

* [実はミニドラって喋れるぞ！【ドラえもん雑学】](https://www.youtube.com/watch?v=XWnXEz5xoIs)(Youtube)
* [COTOHA API リファレンス](https://api.ce-cotoha.com/contents/reference/apireference.html)
* [オレ プログラム ウゴカス オマエ ゲンシジン ナル](https://qiita.com/Harusugi/items/f499e8707b36d0f570c4)(Qiita)