2017年12月22日

物語自動生成プログラム『ジェネジェネちゃん』の作り方 パート書き分け編

前回 物語自動生成プログラム『ジェネジェネちゃん』の作り方 基礎編

■出力するサンプルの作風の決定

今回、この物語自動生成プログラム『ジェネジェネちゃん』を
作るにあたって、以下のような内容のサンプルを出力するという
目標を立てました。

・ライトノベル風
・1万冊分出力する
・現代とファンタジーが入り交じった世界観
・学園が舞台
・登場人物は基本的に学生のみ
・学生達が能力を使って戦うバトルモノ



■パートの書き分け

バトルモノとはいえ、常に戦闘シーン(パート)ばかりではなく、
日常パートもあるのが一般的なので、そのパートの書き分けが
必要です。それに、混じりすぎると文章がグチャグチャになりますしね。

まず、小説1冊分を4章構成と考え、さらに1章は4節に
分かれるとし、1節は15ページほど出力すると決め、
その各節は「戦闘パート」または「日常パート」のどちらかに
なるようにしたいと考えました。

しかし、前回の記事までの手法では、多少の偏りは生まれても、
戦闘・日常パートの違いまで分けてくれるほどの知性(?)は
有していません。


■文の判定

そこで、前段階の文分割の直後の処理として、文の判定を
おこなうことにしました。

まず、戦闘パート・日常パートそれぞれでしかほぼ登場しない
であろう単語のリストを手動で作成します。

戦闘パート用を一部列挙すると、

衝撃, 爆発, 爆散, 炸裂, 一撃, 秘技, 増幅, 突進, 撃破, 咆哮, 唱え, 距離をと, 切り裂, 回避, 剣, 結界, 芒星, 発動


こんな感じです。

それらの文字列が含まれるかどうかで、その1文が戦闘パート
なのかを判定します。

ちなみに、形態素解析した後の形態素で判別する方が
確実のように思われるかもしれませんが、ライトノベルスタイルの
元のテキストデータでは、特に戦闘パートだと特殊な用語の
オンパレードで、しかもその作品にしか登場しない用語もあり、
ユーザー辞書を作成してもうまく形態素解析できない場合があるため、
単純な文字列検索で判断することにしました。

このあたりは別途改めて研究したいところです。

日常パート用も同様に、

洗濯, 調理, テレビ, スマホ, ぬいぐるみ, 焼肉, 宿題, ネコ, ただいま, あひゃひゃ


などの単語リストを作成しておきます。

ただ、たとえば戦闘パート用の「衝撃」などは、「衝撃を受けた」という
日常的な表現にも含まれる場合があり、どこまで登録するかの匙加減は必要です。


■文へのスコア割り当て

その1文が戦闘パートまたは日常パートと判定された場合、
その文に対してスコアを割り当てます。

「後方で爆発が生じた」


という文章なら、

戦闘スコア=1.0、日常スコア=0.0

と、なり、

「彼女はぬいぐるみを抱きかかえた」


なら、

戦闘スコア=0.0、日常スコア=1.0


です。

そして、元のそれらの文章の前後数行に対してもスコアを与えます。

0.3 「その時だった」
0.8 「何者かの気配を感じた」
1.0 「後方で爆発が生じた」
0.8 「受け身を取る暇もなく吹き飛ばされた」
0.3 「息が詰まる」


どのような値を与えるかは、ガウス関数でも線形でも何でもいいかと
思います。行数の範囲もですね。

そして、そのスコアは加算していきます。なので、戦闘パート用の
単語が含まれている2つの文に挟まれた文は、たとえ類似の単語が
含まれていなくても、

1.0+0.3=1.3 「魔術の発動を捉えた」
0.8+0.8=1.6 「その時だった」
0.3+1.0=1.3 「後方で爆発が生じた」


このように高いスコアとなります。


■文の出力生成時の処理

そして、出力生成時の各節で戦闘・日常パートどちらを出力するかを
決めたら、元の文に割り当てられているスコアを参照し、
閾値(たとえば0.5とか)以上ならそのパートだと判断して出力し、
満たしていなければ別の文をランダムで選択して再度判断する処理を
おこなうことで、パートの書き分けが可能となります。

また、戦闘スコアから日常スコアを減算するなどの計算式の調整も
有効だと思います。


■まとめ

基本的にはこのような処理ですが、『ジェネジェネちゃん』では
「食事パート」や「お色気パート」の判断をおこなっていたり、
細かな調整はおこなっています。

同様の方法で、「青空」や「満月」といった単語で時間帯を判断したり、
「教室」「コンビニ」などで場所を判断することもある程度は
出来ると思いますが、「あ、教室にカバンを忘れた」などの文章を
誤認識する可能性もあるため、形態素解析の後に意味解析を
おこなわないのであれば、参考程度の利用にとどめておくのが
好ましいかもしれません(形態素解析が十分に正しくおこなわれているのが
前提ですが)。

もしくは、文章生成時に単語置き換えによって強制的に
整合性を取るのがよさそうですが、その辺りは今後研究して
いきたい部分ではあります。


posted by 妹尾雄大 at 21:06| Comment(0) | 物語自動生成 | このブログの読者になる | 更新情報をチェックする

2017年12月20日

物語自動生成プログラム『ジェネジェネちゃん』の作り方 基礎編

前回の記事 ラノベ1万冊分を自動生成してみても、人工知能は産まれない

昨日公開しましたラノベ1万冊分の出力サンプルの元となる
物語自動生成プログラム『ジェネジェネちゃん』の技術的な
解説をしていきたいと思います。

といっても、人工無脳とそこまで変わらないですが、
いくつかの細かなアイディアが同じような研究をおこなっている
方々の参考になれば幸いです。


■データ収集と文データの保存

まず、インターネット上にある小説テキストをクローリングして
収集します。

次にそのテキストを文単位に分割します。終端は、「。」(句点)や
「!」「?」になりますが、

「ば、バカな?!」

など、複数個連続する場合もあるので、注意が必要です。

また、

「まあ、そうですよね」


のように、カギ括弧のセリフ終端には「。」が付かないので
(たまに付いている文章もありますが)、そこも注意です。

それと、その文が「地の文」か「セリフ内」かのフラグも
文と一緒に保存しておきます。


■文の解析

次に、1文ずつ形態素解析をおこないます。形態素解析とは、
単語やそれよりも小さい形態素に文を分割し、各形態素ごとの
品詞を判別する処理です。

ここでは、

MeCab
http://taku910.github.io/mecab/

という、オープンソース形態素解析エンジンを利用します。

たとえば、

織田は杯を持ち上げた


という文を解析させると、

織田 名詞,固有名詞,人名,姓,*,*,織田,オダ,オダ
は 助詞,係助詞,*,*,*,*,は,ハ,ワ
杯 名詞,一般,*,*,*,*,杯,ハイ,ハイ
を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
持ち上げ 動詞,自立,*,*,一段,連用形,持ち上げる,モチアゲ,モチアゲ
た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ


と、なります。

物語自動生成プログラム『ジェネジェネちゃん』では、
この左から2列目の品詞情報に着目します。この品詞だけを
順番に取り出すと、

名詞,助詞,名詞,助詞,動詞,助動詞


と、なります。ただ、「織田」などの人名は、後々の処理で
特別に扱いたいので、ここでは「姓」に置き換えます。結果、

姓,助詞,名詞,助詞,動詞,助動詞


と、なります。これをここでは「品詞列」と名付けます。

そして、この情報を元の文データと合わせてワンセットとします。

文=「織田は杯を持ち上げた」
品詞列=「姓,助詞,名詞,助詞,動詞,助動詞」


このような感じです。これをすべての文に対して処理します。


■連続する文の関連性

ある文と、すぐ直後に続く文との関連性を考えてみたいと
思います。

たとえば、

織田は杯を持ち上げた。
「では、飲むか」


このような連続する文があったとして、両方を先ほどの
形態素解析による品詞列も合わせて表すと、

織田は杯を持ち上げた。(姓,助詞,名詞,助詞,動詞,助動詞)
「では、飲むか」(接続詞,記号,動詞,助詞)


に、なります。

次にこれとは別の文章を解析してみると、

羽柴は箸を持った。(姓,助詞,名詞,助詞,動詞,助動詞)
「まずは、食うか」(接続詞,記号,動詞,助詞)


と、先ほどと同じ品詞列になりました。

ここで一つの仮説を立てます。同じ品詞列が連続するのであれば、
文章の流れというかノリが似ているのではないか、と。試しに、
2番目の文を入れ替えてみます。

織田は杯を持ち上げた。
「まずは、食うか」

羽柴は箸を持った。
「では、飲むか」


そこまで違和感はないですね。

……はい、かなり強引な仮説だと思いますよね。まあでも、
完全にランダムに別の文を選択して文同士を連結させるよりかは、
多少のノリが生み出せます。

たとえば、

信長が攻撃を仕掛ける。
ザンッ!
「ギャアア」
秀吉が倒れた。
「おのれぇ!」
家康が突進する。


というような、短い文の連続で擬音が多い文章と、

信長は秀吉を睨み付けながら、刀に手をかけた。
家康はこれから起こるであろう惨事を本能的に察知した。
響き渡る断末魔を聞き終わる前に、獣と化した体が動いていた。
自らが咆吼を上げていることにも気づかずに。


というダラダラ長い文章とがランダムで混ぜ合わされると、
文体のリズムのようなものが失われてしまいます。


■実装

話が長くなったので、さっさと実装の話に移りたいと思います。

形態素解析を終えて「文」と「品詞列」がワンセットになったものが
出来ていると思いますが、そこから「品詞列」をキーとして
文のリストを作成します。

文=std::string
品詞列=std::string
文リスト=std::vector<文>
品詞列/文リスト辞書=std::map<品詞列, 文リスト>


みたいな感じです。C++っぽく書くと。

そして、品詞列と次に来る品詞列との連結性を表す辞書を作成します。

品詞列リスト=std::set<品詞列>
品詞列/品詞列リスト辞書=std::map<品詞列, 品詞列リスト>


あとは、

1.ランダムに品詞列を選択する
2.品詞列/文リスト辞書からランダムに文を選択して出力する
3.品詞列/品詞列リスト辞書からランダムに次の品詞列を選択する
4.2に戻る


を、実行すると無限に文章が出力されていきます。

ただ、元の小説データが少なかったり、品詞列に偏りがあると、
元の小説がそのまま出力されてしまう場合がありますので、
元データのインデックスなどを参照して、任意回数連続する
ようなら、上記の1~3番のランダム選択をやり直すなどの
処理が必要です。

また、品詞列の遷移が短期間で循環したり、終端に到達した
場合も同様です。


■まとめ

まあ、いわゆる単純マルコフ連鎖なのですけど、形態素や単語や
品詞や文章をそのまま状態として利用せず、文を一段抽象化した
品詞列をキーとしているところが『ジェネジェネちゃん』のミソです。

ただ、これだけでは、まだまだ文章がランダム的なので、
「戦闘パート」「日常パート」などを生成する方法や、
その他の細かな調整テクニックを加味していくのですが、
その辺はまた後日書きたいと思います。


posted by 妹尾雄大 at 21:37| Comment(0) | 物語自動生成 | このブログの読者になる | 更新情報をチェックする

2017年12月19日

ラノベ1万冊分を自動生成してみても、人工知能は産まれない

人工知能研究の一分野である物語自動生成のプログラムを試しに作ってみたので、
それを使って出力したラノベ1万冊分のテキストを以下にアップしました。

・第1~130巻までのお試し版

・第1~10000巻フルセット(zipファイルで775MB、展開後は1.35GBになります)


■小説『アーティフィシャル・バトル・クライシス』について

この小説『アーティフィシャル・バトル・クライシス』(以下『ABC』)は、
私(妹尾雄大)が開発した物語自動生成プログラム『ジェネジェネちゃん』から
生成して出力したものです。

分量は、ライトノベル1万冊分になります。

ジャンルは、学園+ファンタジー+バトルロイヤルです。


■一部テキストの抜粋

1巻あたり4章×4節構成となっており、各節は「戦闘パート」「日常パート」
「日常食事パート」「日常お色気パート」のどれかになっています。ただ、
食事・お色気パートについては、あまりうまく出力できておりません。

一部テキストを紹介しますと、

第5巻4章4節(日常パート)

「うわ、何この人、きもちわるっ!!」
「いやぁぁぁぁぁぁっ!!!」
「所長」
「ヘルプぅ!?」
 どんな速度で入って来るんだよ!!
 でも、うん。
 他者に優しく、身内に厳しいと言われるだけはある。
 今回ばかりは相手が悪かった。
「ありがとうございます」
「早速ですが質問です」
「ありがたく存じ上げます」
「うん、あれは……ひどかった」
 そしてその影響に対する責任をとれる者など、俺達の中には誰もいない。
「いや、そうでもないと思う…」

第17巻3章3節(お色気パート)

「お花、きれいだね」
 進行方向に光が見えて、それが大きくなると、一瞬視界が無くなり――。
「手、繋いでいいか?」
 なるほど、俺にはない発想だ。
「ですね」
 大きすぎず、小さすぎず。
「す、住むって、こんな狭いとこに?」
「すみません、付き合ってもらって……」
「強制的に酷いことをしてすまない……でも、こうするしかなかったんだ」
 バイゼルンまでの行程は今日を入れて二日。

第695巻4章4節(戦闘パート)

「こっこ」
「なぜそのことを」
「この角を曲がった先に!」
「どういうことよ?」
 リンはその場で大きく息を吐いて座り込み、俺は駆け出す準備をしていた足を弛緩させた。
 不意にヒースは風を感じる。
 ぎょっとなった。
「時間感覚が狂うな」
 そして見た。
「…………………」
 そう勘違いされているのかと無言で肯定してるように振る舞う。
 その隙にアシュレイは素早く刀を取り上げた。
 知らないはずがない。
 陽菜乃とはこの宿の裏庭で剣を合わせた時が最後に会った記憶だ。
「だが、まだ何とかなる範囲だな」
 症状が悪化するや否や素早く介抱を始める陽菜乃にヒースが苦笑する。
「オイ、アシュレイ!」
 その時、アシュレイが動いた!
「ううん、本当は俺が気付かなければならなかったんだよね」
「で、アシュレイ」
 お前を殺す。
 雄たけびを上げながら突進。

第10000巻4章4節(日常パート)

「だから、好きなのを必要なだけ選んで、くれます……か?」
「いったい同時にいくつの風を操っているのやら」
「お前っ……状況見えてんのか」
 瞳が小さく、妙に強面に見える。
「まぁ……みてて?」
「明日ですね?」
 陽菜乃も平気だとの事。
 アシュレイも初めてだ。
「……右がひどいな」
 黙っていたマルティナが、しばらくして呟いた。
「あいつらはどうした」
 結局彼女たちは浩介を見捨てなかった。
 ストレッチなんてする必要すらなくなったけど、これも習慣ってやつだ。
「何だい」
 手紙もこの教会を通してやり取りしていたらしい。
 何があったのかをまだ自分には知るすべはない。
 卒業式が終わった。

最終章節がエンディングっぽいのは、偶然です。本当に偶然です(笑)。


■物語自動生成プログラム『ジェネジェネちゃん』について

物語自動生成プログラムは、一般的な意味での人工知能プログラムに
該当します。

『ジェネジェネちゃん』は、インターネット上から小説テキストデータを
収集して学習し、それを元に小説を自動生成します。

『ジェネジェネちゃん』は、いわゆる人工無脳の域を出ていないものでは
ありますが、以下の法的な解釈に絡みますので、おこがましいですが
ひとまず人工知能(AI)とみなします。


■AIに関する法的解釈について

2017年現在、日本国内の法律においては「著作権法47条の7」により、
「データ収集」「学習データの公開」「生成物の公開」は
著作権法違反にはならないと考えられています。

参考:
『「日本は機械学習パラダイス」 その理由は著作権法にあり』
ITmedia
http://www.itmedia.co.jp/news/articles/1710/10/news040.html

『コラム:機械学習パラダイス(上野達弘)』
早稲田大学知的財産法制研究所[RCLIP]
https://rclip.jp/2017/09/09/201708column/

ただ、生成物に著作権が発生するかどうかについては、「人間がAIに
指示して生成された」とみなされた場合は著作権は発生せず、
「人間がAIを道具として利用して生成した」場合は発生すると
考えられています。

参考:
『AIによって生み出される創作物の取扱い(討議用)』(PDF)
内閣府知的財産戦略推進事務局 首相官邸ホームページ
http://www.kantei.go.jp/jp/singi/titeki2/tyousakai/kensho_hyoka_kikaku/2016/jisedai_tizai/dai4/siryou2.pdf

今回の生成物『ABC』は、「どういう作風」にしたいという「創作意図」を
私が決め、AIを利用して作成したと解釈され、著作権が発生してしまう
可能性があります。


■『ABC』の取り扱いについて

『ABC』は、私が人工知能分野における物語自動生成技術に関する
研究によって開発したプログラム『ジェネジェネちゃん』の
出力サンプルです。

あくまで研究用であり、この生成物『ABC』も学習データも
商用利用や販売をおこなう意図はありません。

仮に『ABC』が「自然人が関与しないAIによる創作」と判断され、
著作権が発生せず、誰のものでもないと判断された場合であっても、
学習データの元となる小説の文章は作家による創作物であることを
十分に配慮し、『ABC』の転載等はしないようお願い致します。


■物語自動生成技術の未来について

この『ジェネジェネちゃん』自体は人工無脳レベルで未熟なものですが、
物語自動生成技術は今後より進化していき、いずれは作家の方が
小説を執筆する際の補助ツールの一部となったり、オープンワールド
RPGなどでのサブシナリオ生成に利用されたりしていくのだと
思います。

まあ、個人的には故栗本薫氏の第130巻で止まってしまった
『グイン・サーガ』の続きが読みたい、というのが最大の動機では
あるのですが、僕が生きているうちにそのような人工知能が
実現するのは難しいでしょうね。



posted by 妹尾雄大 at 16:30| Comment(0) | 物語自動生成 | このブログの読者になる | 更新情報をチェックする