hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。
09/14/2004 うー
■ [日記] むー
ちょっと前から鼻やられて調子悪くてしょうがない.更に今日はジャパネットたかた並にグレードアップして熱っぽくなってきた.んで寝てたんだけど蚊が襲いかかってきて眠れやしねぇ.
血を持ってくのは構わんけど,かゆくするのは頂けねーな,蚊のねーちゃんよ.5,6 発持ってってまだご入り用ですか.
■ [ソフト] Media Metadata for Python
メディアファイルの情報を取得するためのフレームワークらしい.対象は mp3,ogg,avi,jpg,tiff などなどだそうで.
■ [小ネタ] 「どの辺が未踏ですか?」に対する大人の対応
何も未踏に限った話じゃないよな…….
■ [小ネタ] 死に様占い
これも 安部さんとこ から.何か昔やったことあるような?
- 死亡した状況
-
ユーモアがあって人気者のあなたに、ある日、テレビ局から出演依頼がきます。それは某大喜利番組への一般人ゲスト出演の依頼でした。
撮影当日、レギュラー陣がかすむほどの抜群のネタで、あなたは次々とザブトンを頂戴していきます。そして積みあがること30メートル。ついに最後のお題を披露するところで、あなたはバランスを崩し転落してしまいます。30メートルの高さから落ちて無事なはずがありません。あなたはそのまま息をひきとりました。
しかし、あなたの最後の言葉はいまだに番組の伝説となっています。「これがホントのオチだ……」
おあとがよろしいようで。
- 死因
- 全身打撲
- 死因の種類
- 不慮の外因死
- 死亡した場所
- 某大喜利番組収録会場
- あなたの死に様は
- 文句ナシのAランク
……えーっと.
09/14/2014 うむ
■ [Py][小ネタ] 人工無脳 amazonas 実践編
さて昨日 この人工無脳の構造やアルゴリズム的なところを書いた わけだけれど,実際に,どんな文章を学習するとどんな文章を吐き出すのか,それを簡単に書いてみようと思う.
昨日,最後に「試したいことがあった」と書いたけれど,それは「歌詞の自動生成」. これは「歌詞とか詩的なものって文章の繋がりとか多少変でも気にならないというかむしろ多少変な方がそれっぽいんじゃね?」という変な思いつきから生まれたもの. よく Web 上では「J-POP の歌詞はワンパターンだ」と揶揄されているようだけれど,ワンパターンなら,文章の自動生成にはうってつけの題材でもあるはずだ.
ただし何か特定の用途向けにコードをチューニングするのはつまらないので,パラメタはチューニングするとしても,アルゴリズム自体を歌詞向けに特化させるようなことはしない. あくまでただのマルコフ連鎖型文章生成器で,どのような歌詞を吐き出せるのかを見てみたい.
なおテーマ自体は「歌詞 自動生成」とかでぐぐれば大量に出てくることなので,さして新しいことというわけではない.
動作環境を整える
インストールとかその辺は pip とか ebuild 書くとか setup.py 叩くとかで適当に. インストールすると amzweb (人工無脳 API サーバ),amzcons (簡易コンソール),amzirc (IRC Bot) という実行ファイルが作られるので,設定ファイルと共に起動してやる. サーバの設定は下記としてみた.
[web] instances = second host = 127.0.0.1 port = 8349 daemon = false debug = true [module] parsers = juman databases = dictdb [textgen:second] score_threshold = 0.0 nr_retry = 50 nr_history = 0 nr_wordclass = 100 nr_entrypoint = 0 [markov:second] level = 2 maxchain = 350 [parser:morph:second] type = Juman path = /usr/bin/juman encode = utf-8 [db:markov:second] type = Dict path = markov.json [db:entrypoint:second] type = Dict path = entrypoint.json
形態素解析器に juman を,データストアに dict/json を使い,2階マルコフ連鎖で最大 350 回まで連鎖させる. ただし連鎖数は初期値.連鎖数は学習する文章の単語数から勝手に調整されていく. スコアの初期値も 0 としておいて,閾値は学習から適当に調整させる. 歌詞生成において「最近の話題を」とか「繰り返しは禁止」というようなことは不要なので,ヒストリ等は 0 にしてある.
$ amzweb amzweb.ini * Running on http://127.0.0.1:8349/
設定した "second" という名前の人工無脳インスタンスを起動したので, コンソールから "second" インスタンスを操作する.
$ amzcons second amzcons>
コンソールから learn というコマンドを使って,ファイルから文章を学習することができる.
一行文生成
手始めに西野カナの歌詞 109 個を一行ずつ学習させた. その結果,下記のような状態となった.
amzcons> stat score threshold: 0.164676 markov maxchain: 6 markov keys: 8942 entrypoints: 1340
実際に文章を生成してみる.
amzcons> print 近すぎると怖くなって [0.167785]
ふむ何やらそれっぽい.最後の数値はこの文章のスコアを示す.
一行文の連結による歌詞の生成
一行ずつ学習させた結果だから一行ずつしか出てこないので,print コマンドを何度か叩いて結果だけを集めた結果がこちら. なお空行は適当に手で入れた.
近すぎると怖くなって リピートできないくらい泣いて 嫌いだった鏡に問いかける 久々のオフ 天気も最高 ふたりで過ごしたこと 顔くっつけ合って 恋が凍えてる 先週もまた怒られて ここに戻ってる 側にいたいよ 最後の恋に恋して 顔くっつけ合って アイライナー濃いめで 苦いコーヒー流しこみ この世を去った
何だかよく分からないうちに何かが死んでしまった...
「混ぜる」
意味は分からないが何かちょっと面白いので,悪ノリして Luna Sea の歌詞を 106 個ほど追加学習させてみる. 交わりそうにない西野カナ分と Luna Sea 分を混ぜてみるのだ. 結果は下記の通り.
amzcons> stat score threshold: 0.150078 markov maxchain: 7 markov keys: 14704 entrypoints: 1875
では文章の生成を行ってみる.
amzcons> print 冷たく透き通る瞳の 恋の色☆ [0.155039]
テンションが低いのか高いのかよく分からない. まあ面白いのでこのままいくつか文章を生成させていく.
冷たく透き通る瞳の 恋の色☆ ナビに怒ってる君を愛してる 伝説の夜に 僕が消えて行く リミットに気持ちが揺れてる 夢から覚めてすべての事があった 先週もまた怒られて ローマ風の中でずっと叫んでる せつなくて ずっと昔から知ってるみたいだね 次の日の未来が違っていたんだ 楽園に刻まれた こんな自分を好きに 伝説の夜 抱きしめた… 淋しげな歌を聴いて 雨音を夜まで数え 夢の中 鍵を探している 窓に映った 自分見つめて 思い通りにはいかないかもしれないけど叫ぶ 限り無く 今はほどいて 頼むからどいて コノ胸ノ アリフレタ 夢に見る
最初と最後,このテンションの差である.
複数行文生成
一行一行生成して,それっぽいところで手動で空行を挿入するというのもまあ良いのだけれど,そうすると人間の脳と手が介在することになってめんどくさい. この人工無脳エンジンは複数行から成る文章の学習と生成にも対応させてあるので,一発で一気に歌詞を生成できるように,一行一行ではなく歌詞全体を一発で学習させてみる.
AKB48 の歌詞 164 個を行毎ではなく作品毎に学習させてみた結果がこちら.
amzcons> stat score threshold: 0.267828 markov maxchain: 306 markov keys: 18086 entrypoints: 129
複数行から成る文章の場合,文章中に含まれる単語の品詞の羅列をそのままスコアリングに使ってしまうと,恐ろしく低い値となってしまう (長文同士の比較となり全く似ない). そのため複数行の場合でもスコアリングは行毎に行って,その平均値を使う形にしてある.
さてこの状態で print コマンドを打ってみた結果が以下.
amzcons> print 目の前にそびえる 悩みながら あの日の栞 輝いた青春の熱は ヘビーローテーション 時は静かに 広がってく波紋 その瞬間 自分のMINDで動けよ 熱く 燃え尽きるまで 別の力 生まれた場所 やさしさを心の道で 見つけた どこへ行けばいいのか? 喧嘩して 泣いたこと あきらめかけても 木っ端なんか ここで死ぬのだろう [0.273942]
...また死んだ.なぜだ.
複数行文も「混ぜる」
では AKB48 分と THE BLUE HEARTS 分を混ぜてみよう. THE BLUE HEARTS の歌詞 93 個を追加学習させた結果がこちら.
amzcons> stat score threshold: 0.169714 markov maxchain: 160 markov keys: 23498 entrypoints: 199
どうやら歌詞の構成の傾向が違うようで,スコア閾値や最大連鎖数がだいぶ下がっているのが見て取れる.
では歌詞を生成してみよう.
amzcons> print レストラン レストラン レストランに行きたい 遠くに見えても 何か別の答えを探す 愛し合おうぜ 裸になっていたんだ M・O・N・K・E・Y 燃えている 校庭は一面 鈍い銀の世界を 忘れられない 楽しい事をたくさんしたい 喚きたい ミサイルほどのペンを片手に 僕たちの隠した牙 恋は ずっと手を取り 連れ出したい 妄想だけじゃ はかれない 目の前のマネキンたち 何かキレる音がした アイスのときめき ハートに火を吹くぜ 明日は明日のために おもしろい事をたくさん見たよ 何よりも しょうがないから オレの心が騒ぐよ しまっておけない [0.174378]
何言ってんだこいつ.
3階マルコフ連鎖
ここまで 2階マルコフ連鎖で文章を生成してきたけれど,3階マルコフ連鎖としてみよう. 設定ファイルを下記のように書き換えて学習し直せば,3階マルコフ連鎖で文章生成を行える.
[markov:second] level = 3
この状態で Luna Sea の歌詞 106 個を学習させて歌詞を生成.
amzcons> print この詩 今夜おくろう君に かけがえない君に 変わることない風に 失いかけていたんだ この想いさえ 記憶の扉 鍵を壊して uh 二人の隙間で 育ってゆく物は 消えた 記憶のトビラ 開くカギか Break your mind, going back the dream I can't live without you このまま 君だけは ぬれないで ずっと さよなら 君だけは 微笑んで ずっと さよなら 揺れていた せつなくて ずっと さよなら 揺れていた せつなくて ずっと このまま 君だけは 大切な事 抱きしめていて 嘘の世界であなたと二人 愛し合ってみたい キミが欲しい キミの匂いと あどけない 微笑みが 塞がれた こんな夜には ROSIER 近づけない ROSIER 抱き締められない 貴方が与えて呉れた一生をばらばらに壊したい 瞳を閉じて フラッシュの中 散り咲こう 無情な夜 今誓う空虚の中 散り咲こう [0.132440]
やはり学習したフレーズがそのまま出てきてしまう率が上がるように見える. 過去の履歴を加味して次の状態を決める場合,次の状態への分岐が少なくなってしまうため,数値を大きくすると「そのまま感」が出てきてしまう.
ただ学習数を増やせば分岐も増えるはずではあるので,このまま AKB48,THE BLUE HEARTS,西野カナを全て混ぜてみて,文章を生成してみよう.
amzcons> print 夢まで寝静まる街 ベッドから抜け出して 大人を起こさないように パンパンパン パンパンパン パーンと弾けて 飛んで行け 前を邪魔する奴は 喧嘩上等 明け暮れて 無意味なことだとわかった 生意気な奴をボコボコにしても 僕はぼんやりと 眺めていた 苦しめたくない でも忘れられない 何故? 涙 拭いて 歩き出そうよ そこに 岸はあるんだ やわらかい君の声を聞かせて 涙を止めて Dancing on me life is cool. ありふれた毎日が Baby I like candy candy oh そうテレビをつけたって 話題のパンケーキ特集だって 妄想限界 Help me life is "LOVE IS OVER I tell you just wait for beauty… 貴方のため 生まれ変わる [0.167322]
やっぱ混ざらんわ.無理.
まとめ
おそらく,似たテイストを持つアーティストに絞ったりして学習を進めていけば,それっぽいものを吐き出せるようにはなるんじゃないかと思う. ただ,歌詞というものには主題となるものがあって,ある種の一貫性を文章全体として求めてくる. マルコフ連鎖で文章を生成する以上,どこまでも確率によって内容が展開されていくので,主題の違う文章を学習させてしまうと,生成された文章の中で矛盾を生んだりすることになる. 「このインスタンスはこういう文章の生成用」等といったように主題別に学習を進めて行けば,もしかしたらそれっぽいものを吐き出せるようになるかも知れない.
あと複数行から成る文章の学習と生成は昨日ざくっと適当に作ったものなので,まだまだコードとしてのチューニングの余地があるのではと思っている. 特に,スコアリングを一行一行に対して行うようにしたのは悪手だったかも知れないと思っている.全体の構造が無視されてしまうからだ. まあ,この辺はまたおいおいと詰めて行こうと思う.
この世を去った