分野限定型ルーチン文章自動生成装置

本屋でニューラルネットワークを使った文章自動生成をネタにした本を立ち読みして失望した今日このごろです。本1冊書いて、結びで無茶苦茶な文章の出力例を出しておいてよく金取れるな、と思うよ。
リカレントニューラルネットワークを使った自然言語処理は興味深いですがね。完全自動生成は永遠のブルーオーシャンだと思いました。

唐突ですが分野限定型ルーチン文章自動生成方法について検討をしてみた。

といっても、株式情報のように、限定された範囲で事なる事実が大量に発生し、それをルーチンで文書化する、みたいなシーンに限定されちゃう案ですけど。

このブログなら、Fitbitのヘルスデータから、毎日違う内容のエントリを自動投稿するような用途に使える機能です。

前提条件

前提条件はキツイです。スミマセン。

  1. 同じ内容に関して事なる事実が日々発生しルーチンで文書化するケースであること。
  2. 「事実」に関する多岐にわたる言及について、言及を特徴付ける要素が有限であること。
  3. 「事実」の積み重ねにより「結果」がある、という状況を記述する内容であること。

なんのこっちゃ、ですかね。

大まかに説明すると

「青汁は甘くて苦い」、という言及を直交した特徴「商品名=青汁, 甘い=1, 苦い=1」という3つの要素で特徴付けるとしたとき、
「青汁ってとっても甘くてかなり苦いんだよね」、という言及も、少なくとも「商品名=青汁, 甘い=1, 苦い=1」という3つの要素で特徴づけられるだろう、ということです。ここで、「甘い」にかかる「とっても」を、言及を特徴づける要素としてカウントしないことが重要です。

「甘い」と「苦い」は直交してるのか、は別問題ですけどね。商品名は特徴じゃないかもしれない。

文章全体がn個の分から構成されていて、1つの文がm個の特徴を言及しているとする。特徴の種類の数がk個とする。
1つの文をk次元のベクトルと考え、その要素のうち、m個が1、k-m個が0であると考える。それらのベクトルがn個連接していると考える。

全く同じ分野から、過去の言及をもってきて、それぞれを特徴ベクトル化します。
「青汁クッソ甘いんだけどいい加減にしろ、苦さパねぇ」も、「青汁は甘くて苦い」と同じ特徴ベクトルになるようにします。

お気づきかも、ですが、文体とか、言及バイアスとか、見えない特徴量があるんですね。ヤンキー風とか、ガリ勉君風とか、見えない特徴が。これも特徴ベクトルに含めておきます。

連接

文章には文脈というのがありまして、AならばB、BならばC、よってAならばCみたいな感じになっていきます。
未来の状態が過去の状態に依存しないような文章に予めしておきます。つまり、A->Zの間で逆方向の遷移はダメだけどハショルのはOKみたいにしておきます。
過去の文章を特徴ベクトル化したときに、特徴ベクトル間の連接を記録していきます。
すると、特徴ベクトル間の状態遷移確率が決まりますよね。隠れマルコフモデルです。

ノードの遷移が新しい文章の文脈を表すようになります。
ノードの選び方ですが、状態遷移確率の積を最大にするよう(最尤推定)に選んでもいいですし、
何らかのルールを作って、探索中に後戻りする(バックトラック)のでもいいです。
現実的には、NG遷移は存在するので、NG遷移をバックトラックで回避させることになりそうです。(NG遷移に確率0を振っておけばいいかも)。

ノード数が文章の文字列長に直結するか、というとそうでもなく、一つの言及が長ければ、連接数が少なくても長くなります。
文字列長は言及の特徴量にすべきかと思います。

文章完成

連接が決まったら、特徴ベクトルを自然言語化していきます。
特徴ベクトルの要素を、これから書こうとする事実に置き換えるだけです。
だけ、といっても、実際は、「事実」箇所にタグを振っておかないと、単純に置き換えできないので、特徴ベクトル化のときに同時にやっておきます。
これから書こうとする事実の特徴の種類の数が過去の記事の特徴の種類の数以下でないといけません。

あ、もし未知の特徴を追加したい場合、過去の特徴ベクトルを更新すると良いかもしれません。
そうすれば、どんどん特徴が増えていきますしね。

類似事実と同一事実

「青汁は甘くて苦い」について「甘い」と「苦い」を過去の文書から見つける際、必ず満たしていないといけません。同一性ですね。
対して、文体やバイアスは、同一性を満たした上で、どちらが良いかを決定づけます。類似性ですね。

単純にベクトルのコサイン類似度を取ると、類似事実も同一事実も「類似度」として扱われてしまいます。
未知の事実の特徴ベクトルを左、過去の事実の特徴ベクトルを右として内積とって、左が維持されれば「同一」ですね。まぁANDの計算です。

文体、バイアス等の特徴をうまく活用すると、全連接で継続して同じ文体、バイアスを実現できますので、かなり「自然」になります。

まとめ、課題

過去文書を特徴ベクトル化するのを手作業でやらないといけないので、超大変です。
gensimを使って自動化する案とかもあるんですけど、やってみる価値はあるかもしれません。
gensimで自動化できるなら、言及する内容すらも固定しないでよくなるかもしれません。

過去文書の数が増えれば増えるほど、文章のバリエーションが増えていきます。
うまく特徴量でコントロールしないと突然別人格が現れるかもしれません。

ということで、まとめでした。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする