一文章の要約システム(5) :深層学習による最適助詞の推定

色々考えてきたが、ここに及んで、深層学習に頼ることにした。アイデアをより詳しく語ると、word2vecと深層学習をつなげてみようということだ。

まず、日本語ウィキペディアから拾ってきた、名詞+助詞+(名詞・動詞)のデータは、4000万個になった。両脇の名詞、あるいは動詞から、それらをつなぐ間の助詞をどう推定するのか、データを眺めていてもさっぱりラチがあかない。前後の名詞と動詞を品詞化して、次のような感じにして、情報を集めたが、これでもパッとしない。

巡洋艦(名詞,一般,*,*):が(助詞,格助詞,一般):支援(名詞,サ変接続,*,*)
愛知県名古屋市西区(名詞,固有名詞,地域,一般):の(助詞,連体化,*):上小田井駅(名詞,固有名詞,地域,一般)
古代ローマ(名詞,固有名詞,一般,*):は(助詞,係助詞,*):ギリシア(名詞,固有名詞,地域,国)
インクジェットプリンター(名詞,固有名詞,一般,*):に(助詞,格助詞,一般):対象(名詞,一般,*,*)
祭神(名詞,一般,*,*):は(助詞,係助詞,*):博多区(名詞,固有名詞,地域,一般)
処理(名詞,サ変接続,*,*):が(助詞,格助詞,一般):いくつ(名詞,代名詞,一般,*)
キャピタルワン(名詞,固有名詞,一般,*):を(助詞,格助詞,一般):買収(名詞,サ変接続,*,*)
政権(名詞,一般,*,*):を(助詞,格助詞,一般):とる(動詞,自立,*,*)
婚姻(名詞,サ変接続,*,*):の(助詞,連体化,*):20%(名詞,固有名詞,一般,*)
10節(名詞,固有名詞,一般,*):に(助詞,格助詞,一般):定め(動詞,自立,*,*)
サッカー(名詞,一般,*,*):は(助詞,係助詞,*):0(名詞,数,*,*)
ヤン・ヴァーツラフ・ヴォジーシェク(名詞,固有名詞,人名,一般):の(助詞,連体化,*):作曲(名詞,サ変接続,*,*)
男子シングルス(名詞,固有名詞,一般,*):で(助詞,格助詞,一般):最初(名詞,一般,*,*)
たよっ(動詞,自立):て(助詞,接続助詞,*):霧(名詞,一般,*,*)
人物(名詞,一般,*,*):の(助詞,連体化,*):風景(名詞,一般,*,*)
板垣退助(名詞,固有名詞,人名,一般):が(助詞,格助詞,一般):第2次(名詞,固有名詞,一般,*)
前線(名詞,一般,*,*):に(助詞,格助詞,一般):なり(動詞,自立,*,*)
存廃(名詞,一般,*,*):の(助詞,連体化,*):判断(名詞,サ変接続,*,*)
連城(名詞,固有名詞,人名,姓):の(助詞,連体化,*):憧れ(動詞,自立,*,*)
型(名詞,接尾,一般,*):の(助詞,連体化,*):吸入(名詞,サ変接続,*,*)
地区(名詞,一般,*,*):も(助詞,係助詞,*):発生(名詞,サ変接続,*,*)
王座(名詞,一般,*,*):を(助詞,格助詞,一般):アグスティン(名詞,固有名詞,人名,一般)
ELMS(名詞,固有名詞,組織,*):の(助詞,連体化,*):LMP(名詞,一般,*,*)
たち(名詞,接尾,一般,*):は(助詞,係助詞,*):11月23日(名詞,固有名詞,一般,*)
舞台(名詞,一般,*,*):は(助詞,係助詞,*):ポルトガル(名詞,固有名詞,地域,国)
1944年(名詞,固有名詞,一般,*):に(助詞,格助詞,一般):主税局(名詞,固有名詞,組織,*)
現象(名詞,一般,*,*):について(助詞,格助詞,連語):幾分(名詞,一般,*,*)
湾(名詞,接尾,一般,*):の(助詞,連体化,*):北(名詞,一般,*,*)
代(名詞,接尾,一般,*):に(助詞,格助詞,一般):結婚(名詞,サ変接続,*,*)
上番(名詞,一般,*,*):や(助詞,並立助詞,*):平安時代(名詞,固有名詞,一般,*)
3月(名詞,固有名詞,一般,*):は(助詞,係助詞,*):永田鉄山(名詞,固有名詞,人名,一般)
シュテティーン(名詞,一般,*,*):で(助詞,格助詞,一般):商業(名詞,一般,*,*)
ホルティ(名詞,一般,*,*):は(助詞,係助詞,*):反共主義者(名詞,固有名詞,一般,*)
冏(名詞,一般,*,*):を(助詞,格助詞,一般):討つ(動詞,自立,*,*)
プラットフォーム(名詞,一般,*,*):の(助詞,連体化,*):合計(名詞,サ変接続,*,*)
ショパン(名詞,固有名詞,人名,姓):によって(助詞,格助詞,連語):フルート(名詞,一般,*,*)

品詞を使うことも考えたが、品詞情報はとても弱い。助詞の選択は、品詞で機械的にも止まるものではなく、前後に使われている名詞や動詞の意味に連結しているのだ。

そこで、深層学習を利用しようということになった。前後の言葉を入れると、最適助詞を選び出すようなニューラルネットワークを構築すれば良い。深層学習のjavaプログラムはすでに作ってある。自己符号化型のものだが。

ただ、言葉膨大にある。入力ユニット数を数万に増やすわけには行かない。そこで、言葉をword2vecを用いて、200次元ベクトルで表し、前後の言葉で、合計400次元にすれば、難なく、深層学習で扱える。出力は、助詞のいずれか一つが選択されるように、助詞の数だけのユニットだから、それは、限られた数で良い。せいぜい数十個だろう。

4000万個のうち、3000万個くらいを学習させて、残りの1000万個でテストすれば良い。早速データを作ろう。

自然言語とコンピュータ言語

自然言語(日本語とか英語など)とコンピュータ言語(JAVAとかC++など)は、どう違うんだろうと考えることはままある。

が、ふと、同じようにできるのでないかと思った。

例えば「私は人間である」というのは自然言語だ。これをJAVA的に表すと

String watashi = "人間";

しかし、これが変なのは、「私は学生です」もありえるが、一旦、人間ですを入れると学生ですが入れられなくなるのだ。

だったら、watashiをクラスにすればいい。

class Watashi {
    List<String> attributes = new ArrayList<>();
}

こういうクラスを作っておいて、

Watashi watashi = new Watashi()

とインスタンス化すれば、

watashi.attributes.add("人間");
watashi.attributes.add("学生");

などと、いくらでも私という存在の属性を加えていくことができる。逆にこのインスタンスがあれば、

String reply(String question){
  switch(question){
    case "あなたは何ですか":
        return "私は"+attributes.get(0)+"です";
    case "あなたは学生ですか":
        if(attributes.contain("学生")){
            return "はいそうです";
        }else{
            return "いえ、私は学生ではありません";
        }
   }
   return "わかりません";
}

などと、質問に対して答えることができる。これで、do(する)、playなども関数としてクラスに組み込むことができる。

一文章の要約システム(4) : 助詞の使い方

(3)で書いたように、短くしたときに、重要でない言葉を削除した後の文章のつながりが悪くなって、そのままでは聞き取りにくいところができてしまうという問題の解決に取り組んでいるところだ。

基本的に、削った言葉の前と後の言葉を繋ぐのだが、助詞の使い方が重要だと考えている。そこで、日本語wikipediaから、名詞+助詞+名詞(動詞)というパターンを全て取り出してみた。本来どのような助詞で繋がるかは、文法上決まっていると言っていいのだが、現実には、繋がるべき名詞や動詞の内容というか意味に依存している。

問題は、コンピュータは必ずしも名詞の意味を理解していないので、言葉だけから助詞の選択がうまくいかないと思っている。実際に使われた助詞は、正しいと判断しなければならないので、そのような助詞の使い方を全部拾い出したのだ。

集めたパターンは、例えば次のようなものである。名詞:助詞:名詞というフォーマットになっている。

医療:の:役割
マラソン:では:20km
先:にば:八坂神社
ベスゴ:は:54日間
オンライン:の:ビデオ
ゴム:といった:トラック
スロバキア国民党:と:人民党・民主スロバキア運動
胴:を:籐
心:などが:テーマ
度:か:巣内
観客:の:感情移入
乾隆帝:の:継
劇場:の:休演日
スカルノ:を:党首
サーバ:によって:ウェブ
千葉ロッテ:の:関谷亮太
第一次五カ年計画:による:経済開発
テッド・ターナー:の:MACW
一族:の:大胡
ウマル:は:兄
エミレーツ航空:と:カタール航空
948人:の:死者
一族:の:姓氏
主人公:と:観月
本人:が:原因
池ノ上:の:弥
エンディング:の:クレジット
国籍:が:メキシコ
庭:に:大砲
同法違反:で:罰金
3月:からの:テアトル
高屋窓秋:や:石橋辰之助
デンマーク:の:法学
殺人:の:ハードル
2016年:に:オリックス
リング:などの:精密機械
少将:を:理由
データ:の:数量
魚:を:産
240ドル:から:260ドル
ベスゴ:は:53日間
代用品:として:綿
事故:が:スキャンダラス
映画:が:興行成績
暗黒:の:堕天使
一番槍:の:勇者
ローグ:と:Gエグゼス
金日成:が:拠点
報道機関:が:市議会
間:に:チャナク危機
ネーデルラント:の:南部
車内:に:東京スカイツリー
農家:の:二男
二眼レフカメラ:の:Rollei
データ:の:末尾
魚:を:男
パレスチナ:の:キッチェル
ノズル:から:高圧
魚:を:町

集まった数は、全部で21,678,079対である。この2千万対を削除した前後の名詞に適応するというのが戦略である。

単一文章の要約システム(3) : 知的ロボットのセリフを自動で短くする

単文要約をスムースにすることは、当面する最も重要な課題だと思っている。すでに、過去二階の投稿で、初期の実行方法は示した。そして、実際それは即興漫才ロボットに組み込んでいる。しかし、先の投稿にも書いたように、まだ不十分で、単純にword2vecの距離で測って主語と関係性の薄いフレーズをバサバサと削って短くしているのでは、言葉としてつながりが悪くなって意味が伝わりにくくなってしまうのである。名詞と名詞、動詞と名詞などを繋いでいく助詞の選択が悪いなどの問題がある。

どうするのか?マルコフ連鎖を応用して、文章を生成していく手法があるが、それは、2つや3つの連続することがから、次の言葉を生成するシステムである。その発想を利用して、ある句を削除したときに、削除した前後の句をうまくつなげるように、前の句の助詞を改定していくのが良い。

それを実現するために、大量の文章コーパスから

〇〇□□〇〇

のように、挟まれた助詞に関するデータベースを作成すれば良い。これも、一つのマルコフ連鎖である。

ただ、データが膨大になってしまう可能性がある。あるいは逆にデータの欠落が大量に発生してしまうという可能性もある。どうするのか。少し考える。

ロボット即興漫才の到達点:事務所のネタ見せを終えて

事務所のネタ見せがあり、人前でロボット即興漫才を披露した三度目の機会となった。今回の機会は、全2回と決定的に違っている。単にこれまでの漫才よりもうまくいったということではない。確かに、その点ではよかったのだが、それよりもはるかに重要な意味があるパフォーマンスだった。

まず、漫才台本もその一部である謎かけも、完全にその場で作るものだった。前回は、基本、コアとなる言葉は、私が作るわけではなく、コンピュータが作るものだが、ロボットが聞き取れる言葉については、全て事前に釣らせていた。今回は、そのコアの言葉もすべて、その場でロボットに作成させた点で、私的には「画期的」なことなのだ。

というよりも、これこそ私がお笑いロボットをやりだしてから最もやりたかったことなのだ。それができたという点で、私的にはすごいことだった。

漫才も謎かけも、レベルは低いし言葉がちょっとおかしなところがあったりしたが、今回は、本当に漫才や謎かけになっていた、と私は思っている。

しかも、今回は、ロボットが認識できる言葉をこれまでの3000語弱から、8000語以上まで増やしたのだ。これも画期的だ。というよりも、その場でロボットが自由にネタを作る力を持ったから、単に、聞き取り語彙を増やすだけで、ネタ作りができるようになったのだ。つまり、ロボットが聞き取りできる言葉がいくら増えても、ロボットは基本、ネタを作ることができるシステムになっている。

現在、8000語を認識するために、サリーのtopicファイルをコンパイルする時間として1分以上かかるようになっている。前は10秒か20秒で終わっていたのに。

今後これを、サリー(ロボットnao)がどこまで認識できるかわからないが、数万程度に増やしたい。というよりも数十万、数百万個まで増やしたいのが本音だが。

じゃあ、次の課題は(1)ロボットの認識語彙を数万に増やす、(2)単文要約が、まだ不十分で、要約した文章が、理解しにくくなる時がある。(3)漫才と謎かけネタをよりレベルの高いものにする、などがすぐに思い浮かぶ。(1)は、ただ、語彙を増やしてそれがうまくいくかチェックすればいいだけで、うまくいくところの上限が限界なのであり、確かめるだけで良い。

問題は、(2)の単文要約である。これについては、次の投稿にする。

4000万ツイートから名詞を使用頻度の順に取り出す(2)

具体的な手順としては、ツイートファイルをまず一つにまとめるところからである。

$ cat tweets*.txt > all_tweets_181012.txt

5,358,925,973バイトあった。5Gbである。

集めたファイルを、mecabで分かち書きする。時間も測っている。名詞だけを取り出し、余計なものをカットし、改行を空白に取り替えると次のようなコマンドラインになる。

$ time mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd/ all_tweets_181012.txt | grep -e "名詞,一般" -e "名詞,固有名詞" -e "名詞,サ変接続" -e "名詞,接尾" | cut -f1 | tr '\n' ' ' > twitter_wakati_data_noun_181012.txt

これで、1時間40分くらいかけて、名詞だけわかち書きされたファイル出来上がる。名詞だけにしたので、2,459,139,485バイトになった。

20スレッドくらいで並列処理したいので、一個のファイルだと不便だ。次のコマンドで125メガくらいのファイルに分割する。パソコンの並列スレッド数は24だが、全部使って動かすと、パソコンがギクシャクしてくるので。

$ split -b 125m twitter_wakati_data_noun_181012.txt

あとは、javaで処理する。

4000万ツイートから名詞を使用頻度の順に取り出す(1)

その質は問わなければ、大体、どんなお題がきても即興漫才や謎かけがロボット自身のコンピュータで、その場で、数秒以内に作成することができるようになった。十分使える。

妻に「漫才やなどかけのレベルは大して高くないんだけれど」というと「それでいいのよ。それが面白いのよ」という。なるほどと、いい意味にとった。

ただ、ロボットが認識できる言葉自体が限られている。ワイルドカードで、どんな言葉でも文章にするほどの知的処理をロボットはローカルでできない。googleのクラウドなどを使えばできるかもしれないが、ライブ会場やテレビの収録場所がネットワークがつながっているとは限らない。

やっぱり、ロボット自身に言葉を認識する能力が欲しい。実は、現時点で約3000語を識別する力は持っている。これで、ずっとネタをやってきているが、それだけの言葉しか対応できないわけではない。多分数万、数十万語のお題に対応できるのだ。そう言うシステムにしたつもりだ。

この認識言葉数の壁、制約を外すためには、新たな言葉を重要性の順に追加する必要がある。で、一体何が重要な言葉なのか。端的に言えば、お客さんが「お題をお願いします」と言ったときに、思いつく言葉である。これを決めなければならない。お客さんは、普段使っている言葉からお題を言うだろう。その場で思いつく言葉である。その場が、どんな場かにも依存する。

そこで、ツイッターで使われている名詞の頻度をカウントすることにした。この間、日々集めているツイート数は4000万ツイートを超えた。これを使うことにする。変な言葉もいっぱいあるが、それらを覗きながら、使用頻度の上位の言葉をロボットが認識できるようにしたい。

単一文章の要約システム(2) : 知的ロボットのセリフを自動で短くする

前回の続きということだが、単にもう一つの例を示すだけである。もう少し長い文章を先のシステムで要約させよう。

本当は前回で終わってよかったのだが、もう一つ例を描きたくなっただけである。次のような文章である。

「離婚とは、婚姻関係にある生存中の当事者同士が、有効に成立した婚姻を婚姻後に生じた事情を理由として将来に向かって解消することをいう」

これを30文字に要約するのは、人間でも一瞬考える。システムの答えは次のようになった。

「離婚とは、有効に成立した婚姻を婚姻後に将来に解消すること」

かなりいい線を言っているが、「将来に」を消さなかったために少し変だが。あるいは、「向かって」を残すべきだった。いや、向かうの点数は低すぎるので、やはり、将来も消すべきだった。向かってを消したときに、将来にも消すようにシステムを改良すべきだが、まあ、当面する、松竹芸能芸人としてのネタ見せが終わってからにしよう。

ログは以下のようになっている。

run:
元文章: 離婚とは、婚姻関係にある生存中の当事者同士が、有効に成立した婚姻を婚姻後に生じた事情を理由として将来に向かって解消することをいう
文字数[61]、目標文字数[30]
---------------------------------------------
<<< phrasesのデータ >>>
[0] => 15
    離婚:名詞:サ変接続:*:*:*:*:離婚:リコン:リコン
    と:助詞:格助詞:引用:*:*:*:と:ト:ト
    は:助詞:係助詞:*:*:*:*:は:ハ:ワ
    、:記号:読点:*:*:*:*:、:、:、
[1] => 2
    婚姻関係:名詞:固有名詞:一般:*:*:*:婚姻関係:コンインカンケイ:コンインカンケイ
    に:助詞:格助詞:一般:*:*:*:に:ニ:ニ
[2] => 3
    ある:動詞:自立:*:*:五段・ラ行:基本形:ある:アル:アル
[3] => 4
    生存:名詞:サ変接続:*:*:*:*:生存:セイゾン:セイゾン
    中:名詞:接尾:副詞可能:*:*:*:中:チュウ:チュー
    の:助詞:連体化:*:*:*:*:の:ノ:ノ
[4] => 14
    当事者:名詞:一般:*:*:*:*:当事者:トウジシャ:トージシャ
    同士:名詞:一般:*:*:*:*:同士:ドウシ:ドーシ
    が:助詞:格助詞:一般:*:*:*:が:ガ:ガ
    、:記号:読点:*:*:*:*:、:、:、
[5] => 6
    有効:名詞:形容動詞語幹:*:*:*:*:有効:ユウコウ:ユーコー
    に:助詞:副詞化:*:*:*:*:に:ニ:ニ
[6] => 7
    成立:名詞:サ変接続:*:*:*:*:成立:セイリツ:セイリツ
    し:動詞:自立:*:*:サ変・スル:連用形:する:シ:シ
    た:助動詞:*:*:*:特殊・タ:基本形:た:タ:タ
[7] => 9
    婚姻:名詞:サ変接続:*:*:*:*:婚姻:コンイン:コンイン
    を:助詞:格助詞:一般:*:*:*:を:ヲ:ヲ
[8] => 9
    婚姻:名詞:サ変接続:*:*:*:*:婚姻:コンイン:コンイン
    後:名詞:接尾:副詞可能:*:*:*:後:ゴ:ゴ
    に:助詞:格助詞:一般:*:*:*:に:ニ:ニ
[9] => 10
    生じ:動詞:自立:*:*:一段:連用形:生じる:ショウジ:ショージ
    た:助動詞:*:*:*:特殊・タ:基本形:た:タ:タ
[10] => 11
    事情:名詞:一般:*:*:*:*:事情:ジジョウ:ジジョー
    を:助詞:格助詞:一般:*:*:*:を:ヲ:ヲ
[11] => 14
    理由:名詞:一般:*:*:*:*:理由:リユウ:リユー
    として:助詞:格助詞:連語:*:*:*:として:トシテ:トシテ
[12] => 13
    将来:名詞:副詞可能:*:*:*:*:将来:ショウライ:ショーライ
    に:助詞:格助詞:一般:*:*:*:に:ニ:ニ
[13] => 14
    向かっ:動詞:自立:*:*:五段・ワ行促音便:連用タ接続:向かう:ムカッ:ムカッ
    て:助詞:接続助詞:*:*:*:*:て:テ:テ
[14] => 15
    解消:名詞:サ変接続:*:*:*:*:解消:カイショウ:カイショー
    する:動詞:自立:*:*:サ変・スル:基本形:する:スル:スル
[15] => -1
    こと:名詞:非自立:一般:*:*:*:こと:コト:コト
---------------------------------------------
主語: [ 離婚とは、 ] 長さ: [ 2 ]
述語: [ 解消すること ] 長さ: [ 6 ]
削減すべき文字数 => [ 31 ]
関連性ウェイトの計算に [ wikipedia ] を使います
主語のウェイトを取得できました
(0) 婚姻関係 => 0.6353335
(1) ある => 0.15152802
(2) 生存 => 0.5595576
(3) 中 => 0.0
(4) 当事者 => 0.49850425
(5) 同士 => 0.2270397
(6) 成立 => 0.6794592
(7) する => 0.0
(8) 婚姻 => 0.76844364
(9) 婚姻 => 0.76844364
(10) 後 => 0.0
(11) 生じる => 0.3153609
(12) 事情 => 0.3992047
(13) 理由 => 0.37157512
(14) 向かう => 0.0
<<関連性レベルの順に並び替え>>
(0) 関連性:0.76844364 語:婚姻
(1) 関連性:0.76844364 語:婚姻
(2) 関連性:0.6794592 語:成立
(3) 関連性:0.6353335 語:婚姻関係
(4) 関連性:0.5595576 語:生存
(5) 関連性:0.49850425 語:当事者
(6) 関連性:0.3992047 語:事情
(7) 関連性:0.37157512 語:理由
(8) 関連性:0.3153609 語:生じる
(9) 関連性:0.2270397 語:同士
(10) 関連性:0.15152802 語:ある
(11) 関連性:0.0 語:中
(12) 関連性:0.0 語:する
(13) 関連性:0.0 語:後
(14) 関連性:0.0 語:向かう
---------------------------------------------
述語につながっていない句はありませんでした
---------------------------------------------
No.13 [ 向かって ] を削減します
No.2 [ ある ] を削減します
No.9 [ 生じた ] を削減します
No.11 [ 理由として ] を削減します
No.10 [ 事情を ] を削減します
No.4 [ 当事者同士が、 ] を削減します
No.3 [ 生存中の ] を削減します
No.1 [ 婚姻関係に ] を削減します
**** 目標の長さになるまで削減しました 長さ = 28 ****
縮減された文章
離婚とは、有効に成立した婚姻を婚姻後に将来に解消すること

単一文章の要約システム(1) : 知的ロボットのセリフを自動で短くする

ネタでは、セリフが冗長と感じさせないためには、セリフの語の長さをだいたい30語程度に抑えないといけない。

ロボットの即興漫才で、その場で与えられたお題に対してネタを作成する場合、あるいは、謎かけの答えを作る場合、自ら持っている様々な知識を駆使して台本にして行くのだが、知識から生成されるセリフが、それよりも長くなっている場合が少なくない。

どうやってそれを狩り込むか。9月の漫才の賞レースm-1では、「〜は」という冒頭から30文字のところで、ぶち切ってやった。これは無理があるので、改善しようということだ。

ここ2、3日色々考えて、ある文章を30文字にする技術は、結構難しい。たくさんの文章があって、その中から大事な文章を選び出して要約するというのはウェッブ上に色々情報があるが、単一文章を処理するというのは、情報が少ない。

菊池 悠太氏が、2016年、東京工業大学に提出した博士論文「 単一文書要約の高度化に関する研究」がある。まだ、ちょっとしか読んでいない。が、参考にさせていただいた。

そんな本格的なものを作ることはさしあたって保留しなければならない。そこでやったことは、簡単なものだ。例えば、肥満の定義が次のようにあったとしよう。

「肥満は一般的に、正常な状態に比べて体重が多い状況、あるいは体脂肪が過剰に蓄積した状況を言う」(wikipediaより)

45文字くらいある。最後は体言止めでいいので、「を言う」は無条件に削る。42文字で、12文字削らなければならない。

これを短くすることを考える。cabochaという自然言語の係り受け解析、構文解析ツールを使って、この文章をparseする。すると、こんな情報を得られる。

[0] => 11
    肥満:名詞:サ変接続:*:*:*:*:肥満:ヒマン:ヒマン
    は:助詞:係助詞:*:*:*:*:は:ハ:ワ
[1] => 10
    一般的:名詞:固有名詞:一般:*:*:*:一般的:イッパンテキ:イッパンテキ
    に:助詞:格助詞:一般:*:*:*:に:ニ:ニ
    、:記号:読点:*:*:*:*:、:、:、
[2] => 3
    正常:名詞:形容動詞語幹:*:*:*:*:正常:セイジョウ:セイジョー
    な:助動詞:*:*:*:特殊・ダ:体言接続:だ:ナ:ナ
[3] => 4
    状態:名詞:一般:*:*:*:*:状態:ジョウタイ:ジョータイ
    に:助詞:格助詞:一般:*:*:*:に:ニ:ニ
[4] => 6
    比べ:動詞:自立:*:*:一段:連用形:比べる:クラベ:クラベ
    て:助詞:接続助詞:*:*:*:*:て:テ:テ
[5] => 6
    体重:名詞:一般:*:*:*:*:体重:タイジュウ:タイジュー
    が:助詞:格助詞:一般:*:*:*:が:ガ:ガ
[6] => 7
    多い:形容詞:自立:*:*:形容詞・アウオ段:基本形:多い:オオイ:オーイ
[7] => 8
    状況:名詞:一般:*:*:*:*:状況:ジョウキョウ:ジョーキョー
    、:記号:読点:*:*:*:*:、:、:、
    あるいは:接続詞:*:*:*:*:*:あるいは:アルイハ:アルイワ
[8] => 10
    体脂肪:名詞:固有名詞:一般:*:*:*:体脂肪:タイシボウ:タイシボー
    が:助詞:格助詞:一般:*:*:*:が:ガ:ガ
[9] => 10
    過剰:名詞:形容動詞語幹:*:*:*:*:過剰:カジョウ:カジョー
    に:助詞:副詞化:*:*:*:*:に:ニ:ニ
[10] => 11
    蓄積:名詞:サ変接続:*:*:*:*:蓄積:チクセキ:チクセキ
    し:動詞:自立:*:*:サ変・スル:連用形:する:シ:シ
    た:助動詞:*:*:*:特殊・タ:基本形:た:タ:タ
[11] => -1
    状況:名詞:一般:*:*:*:*:状況:ジョウキョウ:ジョーキョー

[ ]に入った番号が、句の番号で、矢印の後の数字は、その句がどの句にかかっているかを示している。その下にある情報は、句内の語の構文解析結果である。ここは、多分mecab を使っているのだと思う。ただし、この出力は、cabochaのそのままではなく、parseして、情報を組み直していることをご了解くださいね。こんな出力じゃないなって言わないで。

まず、述語を確定する。これは、主語の最終係り先である。[11]であり、そこが-1になっているのは、それ以上どこにもかかっていないということである。

さらに、どこまでいっても、述語にかからない句は無条件に削除する段取りだが、この文章に、そういう遊びのフレーズはないことがわかる。

そして最後にすることは、各句内の動詞や名詞の語が、主語とどれほど関係が深いかをword2vecという人工知能的ツールを使って分析する。word2vecは、このサイトのいたるところに書いているが、言葉を数字のベクトルに変換するものである。私の場合は、日本語wikipediaの全情報を処理したウェイトと、twitterの2千数百万ツイートを使ったウェイトの二つのデータ(どちらも膨大)を持っている。ウェイトは、200次元ベクトルである。つまり、数十万という言葉が、200次元の数値ベクトルで表されるのである。言語という、魑魅魍魎をベクトルにしてしまう。何という発想。そこは、特殊なニューラルベットワークになっている。

本当に、word2vecはすごいツールなのだが、この考え方やプログラムを無償で公開しているgoogleさんには感謝したい。

word2vecは、近い言葉探しに使われることが多いが、それよりも、与えられた言葉の親近度合い測るのに使うのが、至極便利なのだ。ロボット謎かけ生成でも、散々使った。

そのウェイトを使って、主語のウェイトと各句内にある名詞、動詞との関連性の強さを測って(ベクトル積をとって、平方根を取った)、関連性が弱いものから削っていくということである。

これは、本来、ナップサック問題として解くべきだが、ここでは単純に、文字数が30文字以内になるまで、関係の薄いくから順番に削っていくという方法にしている。

関連性ウェイトの計算に [ wikipedia ] を使います
主語のウェイトを取得できました
(0) 一般的 => 0.5375686
(1) 状態 => 0.4457973
(2) 比べる => 0.39656168
(3) 体重 => 0.67140776
(4) 状況 => 0.4373728
(5) 体脂肪 => 0.6685157
(6) 蓄積 => 0.49764314
(7) する => 0.24754475
<<関連性レベルの順に並び替え>>
(0) 関連性:0.67140776 語:体重
(1) 関連性:0.6685157 語:体脂肪
(2) 関連性:0.5375686 語:一般的
(3) 関連性:0.49764314 語:蓄積
(4) 関連性:0.4457973 語:状態
(5) 関連性:0.4373728 語:状況
(6) 関連性:0.39656168 語:比べる
(7) 関連性:0.24754475 語:する

これが結果で、後半部は、ウェイトの大きな順に並び替えるようにしている。肥満に最も関連性の強い言葉は、体重である。OK!OK!いいじゃない。実に妥当な計算結果になっている。

これで削るのであるが(1)主語は削ってはならない!(2)述語も削ってはならない!(3)同じくに二つのウェイトを持った語がある場合は、そのウェイトの大きな語を尊重しなけばならない。この三つのルールで、句の削除を行った結果は次のようになる。

---------------------------------------------
No.4 [ 比べて ] を削減します
No.7 [ 状況、あるいは ] を削減します
No.3 [ 状態に ] を削減します
**** 目標の長さになるまで削減しました 長さ = 29 ****
縮減された文章
肥満は一般的に、正常な体重が多い体脂肪が過剰に蓄積した状況

というわけで、
肥満は一般的に、正常な状態に比べて体重が多い状況、あるいは体脂肪が過剰に蓄積した状況を言う
を30字以内に要約すると、
肥満は一般的に、正常な体重が多い体脂肪が過剰に蓄積した状況
となる。

日本語の文法的には、「多い」を「多く」に変えるだけで、全く問題なく、ほとんどの情報を失わず、短くなっている。結局、何を削除するのかという問題である。ここに、人工知能的手法が必要なのである。

ロボットのHALに移植したが、正常に稼働した

さしあたって、新しい謎かけのシステムをロボットHALに移してみた。お題をちゃんと素早く解くことができた。(会話などのインターフェイスは、サリーが得意だが、知的処理はHALにやらせる、HALも会話はできるのだが・・・・・・)

ただ、ロボットのjavaのヒープ領域を500mに増やさなければならなかった。システムがでかくなった。

これまで、パソコンでシミュレートしているときにOKだったのに、ロボットに移していろいろな問題を発生するというのが何度もあったので、その都度、ロボットで確認することにしているのだ。特にデータベース絡みでは色々あった。

謎かけは、これで、一連の処理が一段落したので、即興漫才の本体の改良、さしあたって、言語的に自然な文章要約のシステムに移ろうと思う。

ロボットの、コンソール上の出力。ログが多すぎる(笑)