word2vecを使った謎かけ作成アルゴリズムの刷新

データベースを大きく改良したので、それに応じて、謎かけシステムを大幅に改良する。まだ、未完成だが、メモがわりに以下に基本的な手続きを書いておく。データベースとしては、国語辞典、類義語辞典、wikipediaの語彙、wikipedia日本語全文から作ったword2vecベクトル、2500万のツイートコーパスから作ったword2vecベクトルをつかう。どれも、mariadbでデータベース化している。raspberrypi3にも入れることができている。

あまりいい謎かけになっていないが、お題が「ロボット」の例で記述する。まず、出力を示して、のちに説明する。まだ、システム自体も荒削りなので仕方がない。

定義が [ 22 ] ありました
関連性ウェイトの計算に [ wikipedia ] を使います
最良定義 [ ロボット ] => (6:0.83665484)[ 自立歩行する小型ヒューマノイドロボット ]
関連性ウェイトの計算に [ wikipedia ] を使います
(0) 自立 => 0.47648025
(1) 歩行 => 0.61083984
(2) 小型 => 0.5767887
(3) ヒューマノイド => 0.83665484
(4) ロボット => 1.0000004
同音異義語を探します word = ヒューマノイド yomi = ひゅうまのいど
最良候補に同音異義語がなかったので、セカンドベストを試みます base:歩行 yomi:ほこう
同音異義語を探します word = 歩行 yomi = ほこう
kokugo word0:歩行 yomi:ほこう ==> word1:浦項
kokugo word0:歩行 yomi:ほこう ==> word1:補考
kokugo word0:歩行 yomi:ほこう ==> word1:補講
Wikipedia word0:歩行 yomi:ほこう ==> word1:葆康
同音異義語を解析します
-------------------------------------
定義が [ 1 ] ありました
定義が1個しかないので、それを最良とみなします
最良定義 [ 浦項 ] => [ ポハン ]
関連性ウェイトの計算に [ wikipedia ] を使います
(0) ポ => 0.2070303
(1) ハン => 0.32192305
語:歩行 読み:ほこう 同音異義語:浦項 句:ハン スコア:0.32192305
-------------------------------------
定義が [ 1 ] ありました
定義が1個しかないので、それを最良とみなします
最良定義 [ 補考 ] => [ 本論を補足する考察 ]
関連性ウェイトの計算に [ wikipedia ] を使います
(0) 本論 => NaN
(1) 補足 => 0.29759088
(2) 考察 => 0.3297671
語:歩行 読み:ほこう 同音異義語:補考 句:考察 スコア:0.3297671
-------------------------------------
定義が [ 1 ] ありました
定義が1個しかないので、それを最良とみなします
最良定義 [ 補講 ] => [ 補充のための講義 ]
関連性ウェイトの計算に [ wikipedia ] を使います
(0) 補充 => 0.22250648
(1) 講義 => 0.15278976
語:歩行 読み:ほこう 同音異義語:補講 句:補充 スコア:0.22250648
-------------------------------------
定義が [ 1 ] ありました
定義が1個しかないので、それを最良とみなします
最良定義 [ 葆康 ] => [ 中華民国・満州国の政治家 ]
関連性ウェイトの計算に [ wikipedia ] を使います
(0) 中華民国 => NaN
(1) 満州国 => 0.16425252
(2) 政治家 => 0.121589884
語:歩行 読み:ほこう 同音異義語:葆康 句:満州国 スコア:0.16425252
-------------------------------------
謎かけに使えそうな同音異義語とその定義文
同音異義語:補考 定義:本論を補足する考察
-------------------------------------
<<謎かけ>>
[ ロボット ] とかけて [ 本論を補足する考察 ] とときます
そのこころは
どちらも [ 歩行 (補考:ほこう) ] がつきものです

まず、お題のロボットの定義文は、先に記載のデータベースの中には、22個もある。ロボットと題するチャペックの小説もあり、いろいろだ。ただ、どれを選ぶかが非常に重要だ。お客さんからお題をロボットともらっても、チャペックの小説のことと受け取ったら駄目である。

そこでどうするのか。22個のそれぞれの定義の中に、ロボットという言葉とword2vecで測って、一番近い距離を有する名詞を含んでいる定義を、定義として採用する。ここでは、6番目の定義が、distanceが0.83665484となって一番高く、ロボット一般というよりも、ヒューマノイドロボットの定義になっている。

次に、このロボットの定義の中にある6個の名詞に注目する。その中で、word2vecで測って、最も近い距離の名詞を取り上げる。ただし、お題のロボットと同じ名刺は距離1.0になって一番近くなることは明らかで、謎かけにならないから外す。

そうすると、ヒューマノイドという言葉が、最もロボットと近親性を持つ言葉であることがわかる。そこで、この言葉と同音異義語の言葉を探す。すなわち、先のデータベース全体の中で「ひゅーまのいど」という読みを持って、意味が異なる言葉を探すのである。

もちろん、そんなものはありそうにない。実際、なかった。そこで、セカンドベストで、先の6個の名詞の中で、次に良い、というかロボットとの距離が0.6以上のことばを調べる。すると「歩行」であることがわかる。そこで「ほこう」という同音を持つ異議語をデータベースの中から探す。

すると、4つあることがわかる。この中でまたどれを選ぶかが問題になる。本当は、私としては、大学の講義の補講を選んで欲しいが、その根拠をなかなか作れない。まずさしあたって、各同音異義語の言葉と、定義の中にある名詞の関係が強いものを選び出すというアルゴリズムにした。すなわち、同音異義語が定義の中にある最も高い関連性を持つ名詞の、その距離が一番近いものが、一番、世間的にありそうなもので、共感を得やすいだろうということである。この計算をすると、結局補講ではなく、補考がそれだということになる。

で、結局、最後に次のような謎かけになるわけである。

<<謎かけ>> [ ロボット ] とかけて [ 本論を補足する考察 ] とときます そのこころは どちらも [ 歩行 (補考:ほこう) ] がつきものです

講義を選べばもっと面白くなるが、これではあまり面白くない。ただ、講義の定義「補充のための講義」の補充も、講義も、補講との距離がそれほど近くないために選ばれなかった。もし選ばれたら、

<<謎かけ>> [ ロボット ] とかけて [ 補充のための講義 ] とときます そのこころは どちらも [ 歩行 (補講:ほこう) ] がつきものです

こちらも大して面白くないか(笑)

word2vecのベクトルをwikipediaのものばかりになっていて、それが補講が選ばれない理由のような気がする。wikipediaはある意味、フォーマルなものが、関連性が高くなるが、twitterは、より普段に使われることばを踏まえた関連性スコアになる。まあ、その辺りも改良の余地がある。

twitter データを最初から作り直す

この間、twitterやwikipediaのウェイトデータをmariadbのデータベースにしたり、言葉の距離の近いものをリストする場合のデータを事前作成したりしたが、データ量を減らすために、4文字以上のアルファベットのある言葉を排除してきたり、全てがアルファベットの言葉を排除したりした。この制約が、いろいろ面倒なことになってきた。ので、全て作り直す。10時間くらい浪費するような気がする。

Twitterデータは、その後集めたデータも含めて、最初のコーパスから作り直す。結局、利用する総ツイート数は、
25,188,425ツイート
になった。まだ1億個までは程遠い。ので、毎日せっせと収集スクリプトを動かして集めている。24時間動かし続けて、100万個程度集まるので、1ヶ月かけても1000万しか集まらない。スレッドを複数にして集めようとしたが、結局、twitterがサンプリングしているのは同じのようで、同じものを複数買い集めていることにしかならないので、一個のプログラムでひたすら集めている。

word2vecのdistanceで、入っている任意の言葉のすべてについて、相互の距離を計算するので、計算量は膨大であり、自宅の12コア、24スレッド動くmacで20スレッド程度を並列で動かしてまず、テキストデータを作成し、それを次にmariadbに登録する。

Word2vecをraspberrypiに組み込む方法

M-1が明日なので、ここまでのシステムで挑戦することにして、その後のことを考えている。

今回、他の辞書やwikipedia関連のデータはraspberrypiのmariadbデータベースに組み込めたが、word2vecは色々形を変えて組み込もうとしたが、結局うまくいかず断念した。

冷静に考えると、80万語ものword2vecデータを、ある語の類似の言葉を探すために、ベクトル計算を全体にわたってやるというのがそもそも無理がある。word2vecがやっていることは、例えば、一つの後を200次元のベクトルにして、ある語が与えられた時に、同じように200次元のベクトルを持つ80万語との間の距離をベクトル積で計算して、あたいの大きい20語を選び出すという計算である。こんなことを、パワーのないraspberrypiでせいぜい1秒以内、100m秒くらいで計算させようとするのがそもそも無理なのである。

そこで考えたのは、(1)wikipediaから作ったword2vecのベクトルにも、twitterから作ったそれにも、言葉ではない、ほぼ記号のようなもの、とか、「の」「が」などの助詞系などが結構入っている。どれかはわからないが、それらを除外すること。ただ、大した数ではない可能性がある。

それよりも(2)に、そもそもそんなことをその場で、たとえネタの本番で計算させようとすることに無理があるので、類似語を、80万語の全部にわたって、事前に計算しておいて、それを組み込むといのがある。計算さえて着れば、mariadbに組み込むことができるだろう。そうすれば、近隣語の抽出は、ほぼ、即座にできるはずだ。

そのようなことをやっていけば、もっともっとロボットの漫才は面白くなると思う。基本的な、方向がすでにわかってきたので。

テレパシーでデータを受け取るときの仕様の変更

M-1目前で、昨日からグダグダになっている。その詳細は、余裕がないのでまたいずれ。

ここで、記憶のために書いておくことは、サリーやハル、あるいはそれぞれ同士の間でメッセージをやり取りする場合に、telepathyというプロトコルを使用している。元々は、qichatで制御されるnao同士の間でのやり取りの仕様として開発したが、その後、emilyを積んだhal型のロボットと規格を統一してやり取りできるようにしている。

基本、相手のイベントを発生させるような信号を送るシステムだったが、さらに、メッセージも送れるようにした。送られたメッセージは、$telepathy_dataという変数に自動的に格納されるようにしていたのだが、ここにきて、同時に複数のデータを送るときに、同じ、$telepathy_dataに入れておくと、当然バッティングしてしまう。

だから、以後発生させるイベント名に_dataを付けた変数に格納する。例えば、telepathy_hal_subjectというイベント発生を相手の求めた場合、それにつけている「お題は」(実際は、ネットワークの制約からurlencodeしたものを送っている)というデータは、
$telepathy_hal_subject_data という変数に格納される。こうすれば、同じイベントで違うデータを送ろうとしない限りバッティングしないし(これはあり得ない、訂正とかであり得るかもだが)、やり方も覚えやすい。

naoの組み込みライブラリーの改訂が必要になる。ああ、面倒。

システムが、ハードとソフトにまたがって複雑すぎて、覚えられなくなっている。ので、せめてここに書いて、記憶の助けにする。

word2vecのネットワークウェイトをmariadbに入れる in raspberrypi

raspberrypiのメモリ制約や、ディスク容量のおかげで丸一日、いや二日、苦労している。なんとか、辞書やwikipediaがらみのデータベースは、raspberrypiに収まったが、次は、word2vecのバイナリデータをラズパイ上で読み込もうとするとmapのサイズやそれと直結したラズパイのメモリ制約で、データを全部読み込めない。wikipediaから作ったもの90万語分、twitterから作ったもの50万語分あり、確かにこんなものをmapにするのは、ラズパイでは無理だと諦めた。代わりに、まだ、mariadbならなんとかなりそうだということで、バイナリデータを読み込んで、データベースへ登録した。小数点いか5位までしか入れていないのが若干不安だが、容量を大きくしないギリギリだった。

これでも二つのデータで、データベース上で2.5ギガくらいになるのだから。

何れにしても、こんな変換が簡単にできるのは、ウィトのバイナリデータをjavaで扱えるからだ。本当は自分で作らなければと思ったのだが、バイナリファイルから読み込むのがうまく行かなかった。それをちゃんとやっていただいている、javaプログラムが、以下のところにあったので、使わせていただいた。
https://gist.github.com/RoyZhengGao/1c8229413881cf551dd3
全く、優れたプログラムだ。とてもありがたい。

RaspberryPi にコマンドラインでbluetoothを制御する

HALは、一旦組み上げると、USBを新たにつなげることができないので、キーボードもマウスも使えない。ただ、どうしても必要な時(例えば、何かの拍子でどのIPで繋がっているかわわからない時など)があるので、bluetoothのキーボード(マウスパッド付きの小型のもの)を使っていた。
ただ、たまに、繋がらなくなる時がある。すると、マウスが使えないのでラズパイのウィンドウ操作で再接続ができなくなり、にっちもさっちも行かなくなる。sshでターミナルには接続できるので、それでbluetoothがコントロールできないかと思ったら、bluetoothctlというラインコマンドがあった。なぜか、すでに入っていたのでありがたい。使い方は簡単だ。

$ Bluetoothctl

で起動する。
詳細はこちらに記載されているhttps://qiita.com/propella/items/6daf3c56e26f709b4141

基本的なものは次のようになる。

[bluetooth]# show

で状態表示。スキャンは次のようにする

[bluetooth]# scan on

Discovery started
[CHG] Controller B8:27:EB:7D:14:E6 Discovering: yes
[NEW] Device 79:50:86:95:3F:CB 79-50-86-95-3F-CB
[NEW] Device 78:7B:8A:F3:B6:F7 78-7B-8A-F3-B6-F7
[CHG] Device 79:50:86:95:3F:CB RSSI: -68
[NEW] Device CC:C5:0A:28:6E:BA CC-C5-0A-28-6E-BA
[CHG] Device CC:C5:0A:28:6E:BA LegacyPairing: no
[CHG] Device CC:C5:0A:28:6E:BA Name: Bluetooth 3.0 Macro Keyboard
[CHG] Device CC:C5:0A:28:6E:BA Alias: Bluetooth 3.0 Macro Keyboard

接続対象のデバイスは、

[bluetooth]# devices
Device 79:50:86:95:3F:CB 79-50-86-95-3F-CB
Device 78:7B:8A:F3:B6:F7 78-7B-8A-F3-B6-F7
Device CC:C5:0A:28:6E:BA Bluetooth 3.0 Macro Keyboard
[CHG] Device 79:50:86:95:3F:CB RSSI: -68
[CHG] Device 78:7B:8A:F3:B6:F7 RSSI: -48
[CHG] Device 78:7B:8A:F3:B6:F7 RSSI: -69

接続は、次のようにデバイスアドレスを使う。

[bluetooth]# connect CC:C5:0A:28:6E:BA
Attempting to connect to CC:C5:0A:28:6E:BA
[CHG] Device CC:C5:0A:28:6E:BA Connected: yes
[CHG] Device CC:C5:0A:28:6E:BA Modalias: usb:v0A5Cp8502d011B
[CHG] Device CC:C5:0A:28:6E:BA UUIDs: 00001000-0000-1000-8000-00805f9b34fb
[CHG] Device CC:C5:0A:28:6E:BA UUIDs: 00001124-0000-1000-8000-00805f9b34fb
[CHG] Device CC:C5:0A:28:6E:BA UUIDs: 00001200-0000-1000-8000-00805f9b34fb
[CHG] Device CC:C5:0A:28:6E:BA ServicesResolved: yes
[CHG] Device CC:C5:0A:28:6E:BA Paired: yes
Connection successful

今まで、接続できずに結構パニックに陥ったが、これで随分助かる。

即興ロボット漫才システム・・・・自分への約束を果たすために

M-1の1回戦の一週間前になってようやく、即興ロボット漫才システムの全体が出来上がった。明日は、ロボットに実装して、細かい調整をしていこうと思う。

舞台でやることを前提に、基礎的なところをできるだけしっかりさせた。ネタ時間(尺)が2分しかない。お客さんからお題をもらうので、途中でデータができなかったではすまない。

一般の国語辞書、シソーラス辞書、wikipedia、twitterなどの膨大なデータを必要なだけ利用している。さらに、wikipediaの全部とtwitterの2千数百万ツイートを人工知能的手法 word2vecを利用して、言葉の意味を理解しているような共感を引き出すようにしている。

今まで使っていなかった、類似語の距離計測モジュールも利用した。これもとても大事な役割をしている。記録しておく。レーベンシュタイン距離とジャロ・ウィンクラー距離という二つがあるが、ライブラリが問題なく利用できた後者を使った。
https://blogs.yahoo.co.jp/dk521123/36655532.html
ここのサイトの情報を利用させていただいた。luceneのサイトからダウンロードしたjavaライブラリでは、レーベンシュタイン距離の方を出す計算が、使わないようにという指示がされているようだった。

さて、M-1どうなることやら。去年は、謎かけだけやったのだが、その時、来年はもっと高いレベルのものをお客さんに見ると自分に約束した。今回の即興漫才がうまくいけば、その自分への約束を果たせことになる。

kuromojiをneologdの辞書に対応させる

デフォルトの辞書のままkuromojiを使うというのは、相当不利だということがわかってきて、新しい言葉に対応しているneologdを使えるようにしたいと思った。次のサイトが最終的に参考にできた。感謝いたします。
http://d.hatena.ne.jp/Kazuhira/20150814/1439565514
3年前のものだが、タイムスタンプなどを、ちょっと変えるだけで、結果的にうまく言ったのでそれを記載しておく。以下、macでやっているので誤解なく。

適当なフォルダに移動し、kuromojiのソースを取ってくる。

$ git clone https://github.com/atilika/kuromoji.git

CSV辞書を作成する。

$ git clone https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
$ libexec/make-mecab-ipadic-neologd.sh

先ほどのkuromojiのフォルダへ移動し、フォルダを作成し、CSVの辞書をコピーする。ここで、../mecab-ipadic-neologd/build/にある、辞書のタイムスタンプを確認しなければならない。この時点では、20180831となっていた。

$ mkdir kuromoji-ipadic/dictionary
$ cp -R /path/to/mecab-ipadic-neologd/build/mecab-ipadic-2.7.0-20070801-neologd-20180831 kuromoji-ipadic/dictionary

ビルドを行う前に、コンパイル時のヒープを広げておく。

$ export MAVEN_OPTS='-Xmx4g'

ビルドします。mavenが必要になる。

$ mvn -pl kuromoji-ipadic -am package -DskipTests=true -DskipDownloadDictionary=true -Dkuromoji.dict.dir=kuromoji-ipadic/dictionary/mecab-ipadic-2.7.0-20070801-neologd-20180831 -Dkuromoji.dict.encoding=utf-8

これで、kuromoji-ipadic/target/に、jarファイルができている。

-rw-r--r--  1 washida  staff  112358570  9  9 08:42 kuromoji-ipadic-1.0-SNAPSHOT.jar

これだけでいいかと思ったのが浅はかだった。これをまえのkuromojiと同じようにライブラリファイルとしてくっつければ動くかと思ったのだが、クラスが見つからないという激しいエラーが出て失敗。ここで使っている親クラスがないぜということだった。結局それが、kuromoji-coreフォルダにあることがわかったので、そこもビルドする。まえのコマンドラインのフォルダだけ変えた。それでいいのかどうかわからなかったが、まあ、ビルドが成功したのでOK。

$ mvn -pl kuromoji-core -am package -DskipTests=true -DskipDownloadDictionary=true -Dkuromoji.dict.dir=kuromoji-ipadic/dictionary/mecab-ipadic-2.7.0-20070801-neologd-20180831 -Dkuromoji.dict.encoding=utf-8

これで、kuromoji-core/targetにjarファイルができているので、これも同時に、ライブラリとして登録したら、うまくビルドできた。

import com.atilika.kuromoji.ipadic.Token;
import com.atilika.kuromoji.ipadic.Tokenizer;
public class KuromojiNeologdTest2 {

    public static void main(String[] args) {
        Tokenizer tokenizer = new Tokenizer();
        String phrase = "溺れる者は藁をも掴む";
        for (Token token : tokenizer.tokenize(phrase)) {
            System.out.println(token.getBaseForm());
            System.out.println(token.getConjugationForm());
            System.out.println(token.getConjugationType());
            System.out.println(token.getPartOfSpeechLevel1());
            System.out.println(token.getPartOfSpeechLevel2());
            System.out.println(token.getPartOfSpeechLevel3());
            System.out.println(token.getPartOfSpeechLevel4());
            System.out.println(token.getPronunciation());
            System.out.println(token.getReading());
            System.out.println();
        }
    }
}

以前のkuromojiだと、ことわざの中身を形態要素解析してしまっていたが、これは、丸ごと扱っている。

run:
溺れる者は藁をも掴む
*
*
名詞
固有名詞
一般
*
オボレルモノハワラオモツカム
オボレルモノハワラヲモツカム

最後に、kuromoji-ipadicの他にkuromoji-ipadic-neologdフォルダもあって、neologdが付いているのでそっちの方がいいかと思ったが、どう違うかわからない。ただ、こちらの方がneologdが付いているので、いいような気がして、そちらをコンパイルして、使って見たが、結果も同じものだった。後者を使おうと思っている。

twitterデータをword2vecで解析し、wikipedia と比較する

この間、wikipediaデータを元にword2vec用のデータベースを作成した。それはそれで、十分実用性があるが、さらに実際の言葉の、喋り口調の使われ方を見るためにTwitterのAPIを使ったサンプリングデータをコーパスにして作成してみることにした。

Twitterのサンプリングは、APIを使って、昨年末から今年にかけて2000万ツイートを集めていた。さらに最近200万ほど追加して、総計 24,173,335ツイートである。

手順はwikipediaの場合と同じである。ほぼ100万ツイートずつ分かれていたものを一つのファイルにまとめる。

$ cat tweets1* > tweets_all_180907.txt

という感じ。

これをneologdを使ったmecabで分かち書きをする。

$ mecab -Owakati -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/ tweets_all_180907.txt -o twitter_wakati_data.txt

これをword2vecにかけて、ウェイトデータを作成する。

$ word2vec -train twitter_wakati_data.txt -output twitter_wakati.bin -size 200 -window 5 -sample 1e-3 -negative 5 -hs 0 -binary 1

ウェイトデータは、477メガバイトになって、wikipediaの場合の795メガバイトよりもだいぶ小さい。

あとは、distanceで分析できる。関連語検索を、wikipediaの場合と比べてみるととても面白い。
例えば、コンビニを調べる。
wikipediaの場合

Word: コンビニ	Position in vocabulary: 16062
Word	 Cosine distance
-------------------------------
コンビニエンスストア	0.870578
量販店	0.772738
家電量販店	0.751852
ファーストフード店	0.721780
スーパーマーケット	0.720924
100円ショップ	0.718245
ファミリーレストラン	0.713548
キヨスク	0.712224
ホームセンター	0.709059
NEWDAYS	0.703931
自販機	0.699429
ディスカウントショップ	0.695208
玩具店	0.692847
セブンイレブン	0.689320
飲食店	0.687436
売店	0.687210
ドラッグストア	0.686923
キオスク	0.684569
パチンコ店	0.682252
セブン-イレブン	0.681514
小売店	0.679067
大型書店	0.676887
大衆食堂	0.674396
レンタルビデオ店	0.669804
パソコンショップ	0.669721
うどん店	0.669188
弁当店	0.668718
駄菓子屋	0.668227
ブックオフ	0.667262
外食チェーン	0.666742
ファストフード店	0.665017
トイザらス	0.662631
コインランドリー	0.661140
アニメショップ	0.659252
ゲームセンター	0.658729
デイリーヤマザキ	0.652585
ローソン	0.651909
ガソリンスタンド	0.650547
インターネットカフェ	0.650438
自動販売機	0.650044

となる。まあ、なるほどという感じ。これに対して、Twitterコーパスを使った場合は、次のようになる。

Word: コンビニ	Position in vocabulary: 1768
Word	 Cosine distance
---------------------------------
スーパー	0.667722
自販機	0.642148
セブイレ	0.633234
レジ	0.631955
ファミマ	0.627591
セブン	0.625176
ミスド	0.618061
ローソン	0.614712
西友	0.614702
業務スーパー	0.612738
マック	0.597435
スタバ	0.596482
ガソスタ	0.596407
ファミレス	0.593658
ブックオフ	0.592258
LAWSON	0.577262
ツルハ	0.571627
カルディ	0.570277
デパ地下	0.568725
マツキヨ	0.568646
セコマ	0.568199
ドンキ	0.568019
ホムセン	0.567909
生協	0.567643
スーパーマーケット	0.565221
喫茶店	0.565085
セブンイレブン	0.562578
本屋	0.561266
ドラッグストア	0.556287
売店	0.555747
飲食店	0.555709
ゲーセン	0.555684
マクド	0.550563
自動販売機	0.549253
すき家	0.549123
薬局	0.548373
売り場	0.548229
駅前	0.548090
コストコ	0.543193
イオン	0.540342

しゃべり言葉の中で使われた関連語という感じが実によく出ている。セブイレなんて、私は使ったことがないが、使われているようだ。

使い分けが大事になる。

ロボット漫才の台本作成用のプログラミング言語(1)

M-1の日程が、9月23日(2018年)、約3週間後になりそうなので、少し余裕ができて、現状の記録を書いておくことにする。

お客さんからお題をもらってサリーに謎かけをやらせるというネタを始めてから一年半以上たった。ロボットお笑いのレベルをもう一つあげたいと思っていたが、どうするかをずっと考えあぐねていた。夏休みに入って、ロボット漫才についての研究があることを知って関係論文を結構読んだが、その中で行われている試みが使えそうだということがわかった。

主に参考にした論文をリストアップしておく。全てネットからダウンロードできる。
真下遼、2016、「Webニュースを用いた真名井台本自動生成にも続くコミュニケーションロボット」。
青木晢、梅谷智弘、北村達也、灘本明代、2017、「Word2vecを用いた対立後に基づく漫才台本の自動生成」、DEIM Forum 2017-F7-3。
真下遼、青木晢、秋山和寛、考橋一稀、「Webニュースを基にした漫才台本自動生成によるコミュニケーションロボットの開発」(特別賞)。
竹越哲也、萩原将文、2015「ロボット漫才自動生成システム--動作が漫才に与える影響の考察」、日本感性工学会論文誌。
吉田祐介、萩原将文、2012、「漫才形式の対話文自動生成システム」、日本感性工学会論文誌 Vol.11,No.2、pp265-272。

これらを参考にすると、基本的にボケとツッコミのフォーマットを先に用意しておいて、あとでキーワードなどをそれに当てはめるという方法が適切だということがわかった。これを応用すれば、お客様からお題をいただいて、その場で即興で漫才をロボットにやらせることができる。

そのフォーマットをまず用意してみると、この言葉に対して説明文を入れるとか、キーワードと無関係で、音が良く似た言葉を入れるなどの指示をさせる必要がある。これらは、一つのコンピュータ言語として作っておくととても便利に思えた。すなわち、ロボット漫才台本自動生成用のプログラミング言語である。

プログラミング言語の文法の作成はそれほど難しくないというか、初歩的なものはすぐに作れる。ただ、その言語の指示に基ずいて、言葉や文章を用意するインタープリターないしはコンパイラが必要になる。それのためには、実際に言語データや文章のデータベースを用意し、それをコントロールすることが必要になる。

それで、この間、まず、データを用意する作業をしてきた。用意できたものは次の4つだ。
(1)word2vecで解析可能なデータを、日本語wikipediaから作成する。これは、mecabのNeolog辞書を用いたものを作成した。これで、wikipedia上で、関連している言葉をリストアップできるようになった。データは1.02Gバイトある。これは、javaで類語をリストアップすることができるのでemilyに組み込みやすい。
(2)wikipediaのタイトル、読み、ローマ字、その概念の定義、さらに基本的説明をデータベース化してmariadbに乗せた。データの個数が500万以上(正確には5114451個)になった。mariadbはraspberrypiのjavaで制御可能である。
(3)シソーラス辞書データを、mariadbに乗せた。どのように載せるかが色々考えたが、結局ある語とその類語を一対にして読みやローマ字とともにデータ化するのが一番使いやすいと思ってそうした。一つの後にたくさんの類語があるときは、それぞれ一対にしてデータベースに載せるのである。mariadbから、それらをリストアップすることを細かく制御できる。38万個の対をデータベース化した。
(4)日本語辞書をmariadbに乗せた。タイトル、読み、ローマ字、基本説明、対語(あれば)をデータベース化した。約72万タイトルになった。

次に、これらを用いて、漫才スクリプトの処理プログラムを作成することが次の作業になる。