Pythonの世界に飛び込むことにしました
お久しぶりです、cedro です。
先回、リカレントニューラルネットワークを使って、過去の乗客数の流れから、その後の乗客数がどうなるかの予測をやりました。
そうすると今度は、過去の文章の流れから、その後の文章がどうなるかの予測をしてみたくなって来る。
しかし、Neural Network Consoleは、行列やベクトル、画像データは読めますが、単語は読めません。
まあ、1文字づつ数字に変換すれば読み込めないことはないですが、これでは後の処理が上手くできません。
そこで word2vec の登場となります。word2vec は、ある単語の周辺にどの様な単語が現れやすいかというルールに基づいて、単語をベクトル化してくれるものです。
しかし、これ Python を使わないと無理なんですよねー。
ただ、今まで、SONY Neural Network Console のマニュアルとWeb情報を元に、ここまでやって来ました。
Pythonについても、自分がやりたいことだけWebで調べて、写経すればいいんじゃない。と考えて、Pythonの世界に飛び込むことにしました。
ユーミンの歌詞生成をやってみる
いつもの様に「とりあえず一通りやって見る」の方針に従って、今回は松任谷由実の歌詞生成をやってみます。そのシナリオは、
1)Pythonの環境を作り、必要なライブラリーを整備する。
2)松任谷由実の歌詞データを収集し、gensim ( word2vec のライブラリーの1つ)で ユーミンモデルを作る。
3)松任谷由実のどれか1曲の歌詞を、ユーミンモデルを使ってベクトルデータに変換し、Neural Network Console が読める様にする。
4)Neural Network Console のLSTMで1曲の歌詞の前半3分の2を学習させ、後半3分の1を予測させる。
5)LSTMの予測したベクトルデータを単語に変換し、ユーミンの歌詞を生成する。
データはたった1曲という前代未聞の少なさ。一体、LSTMの学習は収束するんでしょうか。
まあ、なんとかなるでしょう。
1)Pythonの環境を作り、必要なライブラリーを整備する
これは、Webを見れば、山ほど情報があるので、割愛します。
私のマシン環境と導入したライブラリーだけ書いておきます。
マシン:MacBook Air 2017年モデル 256GB(bootcampで64GB分にWindows10を入れてます)
OS : Mac OS Sierra 10.12.6
ライブラリー:anacond5.0.1 (普通のアプリケーションと同様にインストールでき、後々欲しくないそうなライブラリーを一括で導入でき、一押しです)、gensim(word2Vecのライブラリー)、Mecab(分かち書きをする時に必要なライブラリー)、ipadic(Mecabで使う辞書です)。
2)松任谷由実の歌詞データを収集し、gensim で ユーミンモデルを作る。
歌詞データは、Uta-Net でダウンロードしたい曲を表示させ、HTMLのソース画面にすると170行目に歌詞がありますので、これをひたすらコピペします。
早くPythonでスクレイピングも出来る様にせねば(;汗)
全403曲を1つのtxtファイルにまとめます。
gesim は単語がスペースで区切られていないと読み込めないので、分かち書きをします。
Mecab ライブラリーを使って、分かち書きするプログラムです。 wakati.py として保存します。
プログラム wakati.pyを実行します。分かち書きする対象は yuming.txt で、分かち書き後のデータは yuming_wakati.txt に保存します。
分かち書き後のデータ yuming_wakati.txt の中身を見ると、こんな感じ。
「神様が いて」というところが「神様が いる て」となっていて、気にいらないのですが、一般化するとこうなるのかな。まあ、今回は良しとしましょう。
これが、gensim ライブラリーを使ってユーミンモデルを生成するプログラムです。ベクトル化の次元数は100、ウインドウは10(前後どこまでの単語を考慮するか)。train.py として保存します。
プログラム train.pyを実行します。yuming_wakati.txt を元にして、yuming.model というモデルが生成されます。
yuming.model の中には、yuming_wakati.txt の中に出てくる単語すべてについて辞書が出来ます。そして、それぞれの単語について、ある単語の周辺にどの様な単語が現れやすいかというルールに基づいて、ベクトルが設定されます。
ある単語の周辺に現れやすい単語は類似したベクトルが設定され、その逆は異なるベクトルが設定されることになります。
さて、yuming.model が上手く出来たのか、チェックして見ましょう。これは、指定した単語と類似度の高い単語の上位10個を出力するプログラムです。similars.py で保存します。
プログラム similars.py を実行し、yuming.model に「空」と類似度が高い単語を出力させてみます。
「空」と最も類似度が高い単語は「海」で、その確率は69.7%だと表示されました。
3位の「ひこうき雲」、4位の「憧れる」を見ると、ユーミンのことを学習していることが良く分かります。
3)「海を見ていた午後」をベクトル化し、Neural Network Console で読める様にする。
さて、いよいよ歌詞のベクトルデータ化です。曲は、荒井由実時代の名作「海を見ていた午後」を選びました。
歌詞は1行1単語です。注意すべきは、yuming.modelの辞書に登録されている単語の区分で書くことです。
こうしないとベクトル化の時にエラーになってしまいます。分かち書きの関係で不自然な表現になっている部分は、適当に端折ります。
全部で96行(96単語)になりました。これを umi_kashiw.csv で保存します。
umi_kashiw.csv から1行づつ単語を読み込んで、ベクトルに変換し、umi_kashiv.csv に1行づつベクトルを書き込むプログラムです。
vector = model.wv [word] のところがベクトル化している部分です。
encoder.py で保存します。
プログラム encoder.py を yuming.model に対して実行します。
ベクトルデータを書き込んだ umi_kashiv.csv の中身を見て見ましょう。
これが、海を見ていた午後」の歌詞の冒頭にある「あなた」をベクトル化した結果です。100次元ですので、この表示の全部で、「あなた」です。
umi_kashiv.csv はベクトルの先頭に [ が付き、ベクトルの最後に ] が付き、空白の区切り(タブ区切り)になっていますので、エディターを使って、[ と ] を削除し、空白を , (カンマ)に変更します。
さて、Neural Network Consoleのデータセットをどう作るかですが、100次元のベクトルが96行あるというのは、言い換えれば96行×100列の行列データがあることになります。
これを8行×100列の行列に分割します。そうすると、全部で12個の行列になります。
この12個のファイルに 0.csv~11.csv の名前を付けて、kashi フォルダーに格納します。
前半の8個を学習用、後半の4個を評価用に使うことにします。

学習用ファイルは、前回と同様です。名前は、yuming_train.csv としました。

評価用ファイルも前回と同様です。名前は、yuming_test.csv としました。
C:直下にSNNC90フォルダーを作り、そこへ yuming_train.csv とyuming_test.csvとkashiフォルダーを格納すれば準備完了です。
SONY Neural Network Console を起動して、DATASET画面で、yuming_train.csv とyuming_test.csv を登録しておいて下さい。
4)LSTMで学習・予測させる。

ニューラルネットワークは、先回の航空会社の乗客数予測に使ったものと同じく、LSTM unit を使用したものです。入・出力は8行×100列の行列ですので、8,100 とします。

学習ファイルをセットします。

評価ファイルをセットします。

評価ファイルのデータが4個しかないので、Batch Size は4、Max Epoch 500 で学習を実行します。

ちゃんと収束してくれて、過学習もないようです。

さて、評価(予測)結果です。評価データxに対してx’を予測しています。
なんか評価データはダイナミックレンジが広いのですが、予測データはダイナミックレンジが狭く、結構似ているような気がします。
さて、目的の予測データが何処にあるかと言うと

SNNC90フォルダーの中の yuming_LSTM_unit.files をクリックして

自分のみたい時刻のフォルダーをクリックして

その中の0_0000 フォルダーをクリックすると

この0~3のcsvファイルに予測したベクトルデータが入っています。
5)LSTMの予測したベクトルデータを単語に変換し、ユーミンの歌詞を生成する。
csvファイルからベクトルを1つづつ読み込んで、単語に変換し、ファイルに書き出そうとしたのですが、どうしても上手く行きません。
なので、とりあえず、力技で赤字の部分にベクトルを1つづつコピペして動かす仕様にしました。
word = model.most_similar ( [ vector ], [ ] ,1 )という部分でベクトルに最も類似する単語を抜きだしています。
これを power.py で保存します。
プログラム power.py を実行します。
出力がこれ。単語の後の数字は、類似度の確率です。
power.py のベクトルのところをコピペしては、プログラム power.py 実行するというのを32回繰り返します。
さて、32個の出力をまとめたものがこれです。
1曲分の歌詞だけでLSTMをやった割には、様式的にも揃っていて、何やら意味らしきものも分かる様な気がします。
この方法を追及して行くやり方は、ありじゃないでしょうか。
では、また。
コメントを残す