深層学習とマルコフ連鎖による短歌自動生成Ver.0.10

短歌自動生成だと[星野しずる](http://sasakiarara.com/sizzle/)が有名ですが、あれはランダムに単語をつなげてその面白さを味わうもの。ここでやろうとしているのはランダムではなく、既存の短歌を学習してそれっぽい短歌を出力するというもの。
結論、今のところ、星野しずるの足元にも及ばない。

# 学習データ

- http://www.twimemachine.com/
    - 短歌ボットを指定して、著名な短歌を取得
    - 日時やタグなどをテキストエディタで除去
    - tanka.txt として保存
    - 現在4,278首を取得　まだ全然足りないと思う

# 深層学習
## Chainer
- [Chainerで作るコンテンツ自動生成AIプログラミング入門](http://amzn.to/2nHjo6S)
    - <a href="https://www.amazon.co.jp/Chainer%E3%81%A7%E4%BD%9C%E3%82%8B%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84%E8%87%AA%E5%8B%95%E7%94%9F%E6%88%90AI%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E5%85%A5%E9%96%80-%E5%9D%82%E6%9C%AC-%E4%BF%8A%E4%B9%8B/dp/4863542348/ref=as_li_ss_il?ie=UTF8&qid=1517713179&sr=8-1&keywords=Chainer%E3%81%A7%E4%BD%9C%E3%82%8B%E3%82%B3%E3%83%B3%E3%83%86%E3%83%B3%E3%83%84&linkCode=li2&tag=aokikenichi-22&linkId=02905bbad325272f201089a58c21c0fe" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4863542348&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=aokikenichi-22" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=aokikenichi-22&l=li2&o=9&a=4863542348" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
    - プログラムは許可なく配布は不可とのことで本を買っていただくしかありませんが、本書を用いました。
    - 7章「意味のある文章の自動生成」の入力を tanka.txt として以下実行
        - chapt07-01.py
        - chapt07-02.py
        - chapt07-03.py
        - chapt07-04.py
    - ざっくりとした仕組み
        - 短歌を単語レベルに分ける
        - 単語に品詞をつける
        - 深層学習で品詞の並びを学習する
        - word2vecにて単語ベクトルを作成し疑似的に「意味」を把握する
        - 初期値として語を指定すると（ランダムに指定したもよいがここのプログラム例では初期値を指定する）品詞の並び順を生成し、意味が近い単語を並べていく
            - 理想的には「雨」と入力すると雨に意味が近いような短歌が出来る、、、出来てないけど
    - 長所　単語の意味も見ている
    - 短所　学習に時間が掛かる。
        -  [Windows10にCUDA9.0とPyCUDAをインストールしてテストが動きcupyインストールに苦労してChainerのMNISTチュートリアルでGPU使用で速度が約6倍となるのを確かめるまで](https://qiita.com/aokikenichi/items/dd6cb0d611784581c001) で作った環境にて2時間20分
        - かなり大量に文書を学習させないと意味のある文書とならない。
    - 以下現状のアウトプット例
        - 初期語「夏」に対して

```
夏の夏といふ答えので回る夏夏夏児
夏の夏といふ答えので回る夏夏ひかり
夏の夏といふ答えので回る夏夏夏夏夏
夏の夏といふ答えので回る夏の夏についてひらか夏
夏の夏といふ答えので回る夏夏夏夏ひかり
夏の夏といふ答えので回る夏の夏の夏ってひらか
夏といふ夏についてわから夏の夏って答えので切れ夏
夏の夏といふ答えので回る夏について運ぶけれどすぎ夏
夏といふ夏についてわから夏の夏って答え夏といふ書き
夏といふ夏についてわからけれどいけ夏にて変わるのでやら夏
夏の夏といふ答えので回る夏の夏について夏ってひらか
夏の夏といふ答えので回る夏夏夏について運ぶ
夏といふ夏についてわからけれどいけ夏の夏といふ答え夏
夏といふ夏についてわからごとき夏を答えのでやら夏
夏といふ夏についてわから夏にて運ぶ夏の夏について答え
夏の夏といふ答えので回る夏の夏についてひらかけれど終わら
夏といふ夏についてわから夏の夏って夏について答えので切れ
夏といふ生き夏の夏について答えので回る夏の夏
夏といふ生き夏の夏について答え夏の夏ってひらか
夏の夏といふ答えので回る夏について夏の夏ってひらか
```
確率が高い順に出るとのことだが、上位は意味をなしていない。下位になるとそれ風のが出るが、単に「夏」を繰り返しているだけ。学習する短歌数が足りないのだと思う。生成する文書の長さは指定していないが、学習させた短歌の長さとほぼ同等のものが生成された。品詞の並びを学習し、文書の最後となるパターンまで学習しているからと思われる。

- 「オレンジ」、「少女」、「雨」、「風」と4単語を指定すると

```
風の少女へ知っながらいくオレンジ少女風雨
風の少女へ知っながらいくオレンジ少女ふゆ
風の少女へ知っながらいくオレンジ少女風吾オレンジ
風の少女へ知っながらいくオレンジの少女よりさめ風
風の少女へ知っながらいくオレンジ少女風吾ふゆ
風の少女へ知っながらいくオレンジの少女の風よりなら
風として少女へしれオレンジの風について育てどもいく少女
風の少女へ知っながらいくオレンジについてさめちゃいっ風
風として少女へしれオレンジの風について育て少女という燃え
風として少女へしれながらいる風について育てどいくオレンジ
風の少女へ知っながらいくオレンジの少女より風についてさめ
風の少女へ知っながらいくオレンジ少女風よりさめ
風として少女へしれながらいる風のオレンジについて育て少女
風として少女へしれらしいオレンジを書いながらいける風
風として少女へしれオレンジを育て風の少女についてしい
風の少女へ知っながらいくオレンジの少女よりさめど出す
風として少女へしれオレンジの風について少女より知っちゃいく
風としてなれ少女のオレンジへ知っながらいく風の少女
風としてなれ少女のオレンジへ知っ風の少女より呼ん
風の少女へ知っながらいくオレンジについて風の少女よりさめ
```
……だめだめです

- 課題
    - 学習する短歌数を増やす
        - 単語の意味を見るword2vecだけは短歌で学習させるのではなく大量に取得しやすい別の文書で代用する　
    - 後述、マルコフ連鎖と組み合わせる

## TensorFlow

- [TensorFlow活用ガイド](http://amzn.to/2nGKRW3)
    - <a href="https://www.amazon.co.jp/TensorFlow%E6%B4%BB%E7%94%A8%E3%82%AC%E3%82%A4%E3%83%89-%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E4%B8%8B%E7%94%B0-%E5%80%AB%E5%A4%A7/dp/4774195049/ref=as_li_ss_il?ie=UTF8&qid=1517718338&sr=8-1-spell&keywords=TensofFlow%E6%B4%BB%E7%94%A8%E3%82%AC%E3%82%A4%E3%83%89&linkCode=li2&tag=aokikenichi-22&linkId=161be37850b4b98dc7f4f9bbd6b4c9e2" target="_blank"><img border="0" src="//ws-fe.amazon-adsystem.com/widgets/q?_encoding=UTF8&ASIN=4774195049&Format=_SL160_&ID=AsinImage&MarketPlace=JP&ServiceVersion=20070822&WS=1&tag=aokikenichi-22" ></a><img src="https://ir-jp.amazon-adsystem.com/e/ir?t=aokikenichi-22&l=li2&o=9&a=4774195049" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />
    - 未着手だが、文章生成の章があるのでChainerと同様に試してみるつもり

# マルコフ連鎖
- ざっくりとした仕組み
    - 短歌を単語レベルに分ける
    - 単語と単語のつながりを計算する
        - マルコフ連鎖とは、例えば過去2語のつながりで次の語が出るというようなルールとした場合、過去3語以上は一切関係ないですよというような考え方。
        - なので、A-Bの語の後にCが30%、Dが70%というような統計を取り、次にA-Bという語が出てきたら30%の確率でC、70%の確率でDを出すというようなもの。
    - 最初の語をランダムに選び、マルコフ連鎖により次の語をつなげていく
    - 長所　単語の前後のつながりは自然なものが出やすい
    - 短所　学習する文書（短歌）数が少ないと元の文書とほぼ同じようなものしか出ない。きっちり57577とはならない。
- 先行事例
    - [機械学習で石川啄木の未完の短歌を完成させる](https://sunpro.io/c89/pub/hakatashi/introduction)
        - マルコフ連鎖かつ他の文書処理手法をもちいてもっとがっつり短歌生成にトライした事例があります。石川啄木の短歌を再現しています。

## TextGenerator
- o-tomoxさんの記事[Pythonリハビリのために文章自動生成プログラムを作ってみた](http://o-tomox.hatenablog.com/entry/2014/11/14/190632)
    - https://github.com/o-tomox/TextGenerator
をもとに改良された版
- [マルコフ連鎖を使ってブログの記事を自動生成してみた](http://karaage.hatenadiary.jp/entry/2016/01/27/073000)
    - https://github.com/karaage0703/TextGenerator
を使用した


- 実行例

```
python PrepareChain.py tanka.txt    # で文書DB作成
python GenerateText.py 1            # で文書生成
```

- 出力例

```
スカートの人の汗滲むボール横抱きにしない死は寝室でもう遊んでいてつま先立ちのさよならが風である配管のうねりを闇に叫ぶわたしをだれか死ぬ。
暑い暑い夏の腕を垂らして触れるとき新たに満ちる見えるものみな視線を乞はず
永遠に存在を追い越すことができない人も物語を待っている四時に鳴り出すアラームを手の中は空白の街めざして偽者のサンタク ロースが溢れる街をゆく
ねんごろの少女とは遠い伝言ゲームのように
川べりに止めた
```
57577を学習しているわけではないので長さは適当だけどたまにいい感じ風なやつが出てくる

```
金曜の首泳ぎゆくあやつるごとく我は清くも醜くもなる
そうでなかった時間に淡くかかはりてゐる人の額に花をゆさぶる
産み終えて雪崩のあとのしずかさの妻の顔あおくあふれて
```

最後の一首字足らずだけどキターーーーーーと思ったが、元の歌の半分くらいをパクった感じで独立の一首とは言い難い……


- 課題
    - まともな短歌風の場合は、元の短歌とまったく同じか、2句まで一緒のようなのしか出ない。つまり学習する短歌数が全然足りない。


# 全体の課題と今後の展望
短歌はわざと単語と単語のつながりを飛躍させるところがあるので、単純に意味が似ているものを持ってきてはだめ。なのでランダムな星野しずるのほうが人間に出来ない意味の飛躍をするので趣深いのかも。
文書での例は見たことないのですが画像生成だと、

- 大量に作者名と絵画画像を学習させる
- 作者名を入れるとその作者風の新たな絵画画像を生成する
- 作者A80%、作者B20%などと指定すると作者Aよりだがと作者Bの画風が合わさったような絵画画像を生成する

というの（DCGAN）があるので、その短歌版を作りたい。穂村弘50%、東直子50%の短歌を生成するとか。