最初にお断りしておきますが、今回の記事は「うまくいかなかった例」です。
恥ずかしながら、うまくいくと思ってやってみたけど、勘違いしていてダメだった)というのも情報だという開き直りで書いています(笑)。
2017/12/02追記
>以降の説明の画面はVersion1.00のものを使ってます。
>Version1.10から一部アイコンのデザインが変わってます
>ただ、見たらわかる程度だと思ってますので貼り替えてません。
何をしようとしたか?
前回、SINカーブのトレースをやってみて、あることを思いついたわけです。
すなわち。
入力(X)に対して、Auto_Encoder的に出力(X')を比較的正確にトレースできた。
それを時系列データとして扱っているから、ある時点の入力(X)の次の状態(未来)を出力(X')は表している・・ということではないのか?です。
だとすれば、そのアウトプットを継ぎ足していけば、少しずつの未来になるから、未来の状態の予測にもなったりするんじゃないだろうか?と考えました。
で・・。
売り上げデータで試してみることにしました。
最初にも書いたとおり、今回は・・それがダメダメだったんですけどね。
ちなみに、同じような売り上げデータを使って、もう少し、ましな予測っぽいことをやってみた記事はこちらです。
さて、始めます
前回の続きです。
ネットワーク自体は、前回組んだものを、ほぼ、そのまま使います。
売上データの用意
まず、元データとして11週間分の日別売上データを用意しました。
だいたい3%から10%の範囲で凸凹しながら、トレンドとしては上昇傾向にあるデータにしてみました。
グラフにすると、こんな感じです。
このデータを7日間ずつの「7行1列」データにして、LSTMに学習させてみて、最終週のみの7日間で評価を行えば、0_0000フォルダに出力される出力(X')は、その近未来の数値なんじゃないか・・と考えたわけです。
だったら、その売上予測のアウトプットを、インプットに追加して再学習させて、また最終週のみで評価することを繰り返せば、未来の「売上予測(みたいなもの)」になるかもしれないな・・・。
そういうことを考えたわけですね。
売り上げデータの正規化
売上データを「-1.0 ~ 1.0」の数値に変換します。
ここは単純に100000で割って、小数点以下四捨五入にいいでしょう。
このC列に作ったデータだけを、7行ずつ11個のCSVファイルに分割します。
7行ずつ11個のファイルにわけるVBAソース
今回はシート名「forward01」に上記データを作成し、例によって以下のような使い捨てのEXCELマクロで作成しましたが、EXCELでCSVファイルで保存して、手で加工してもできます。
Sub dataCreate()
Dim wkst
Dim obj As Object
Dim buf As Variant
wkst = "forward01"
bottom = Range("C2").End(xlDown).Row
ts = 7
fn = 0
For r = 1 To bottom - 1
If (r Mod ts) > 0 Then
out = out & Worksheets(wkst).Cells(r + 1, 3).Value & vbNewLine
Else
out = out & Worksheets(wkst).Cells(r + 1, 3).Value & vbNewLine
datFile = ActiveWorkbook.Path & "\" & fn & ".csv"
Set obj = CreateObject("ADODB.Stream")
obj.Charset = "UTF-8"
obj.Open
obj.WriteText (out)
obj.Position = 0
obj.Type = adTypeBinary
obj.Position = 3
buf = obj.read
obj.Position = 0
obj.write buf
obj.SetEOS
out = ""
obj.SaveToFile datFile, 2
obj.Close
fn = fn + 1
End If
Next
End Sub
データセットCSV
それぞれに、0.csv から 10.csv のファイル名をわりふりました。
これを、ニューラルネットワークコンソールのインストールフォルダの下の「sample_dataset」以下に適当なフォルダをつくってコピーしておきます。
そしてそのフォルダのパスとファイル名を記述したデータ・セット用CSVを作ります。
トレーニング用には11ファイルすべて。
バリデーション用には、最後の10.csvファイルだけで作ります。
これでデータの準備はできました。
テキストデータのデータ・セット用CSVについては、以下の記事でも解説しています。
LSTMのプロジェクトを開く
以下の記事で組んだLSTMのネットワークをそのまま使います。
ニューラルネットワークコンソールを立ち上げて、上記の記事で保存したプロジェクトを開き、名前をつけて保存で、適当なプロジェクト名で保存します。
DATASETタブ
DATASETタブを開き、trainingとvalidationに、前に作成したトレーニング用データ・セットCSVとバリデーション用CSVを関連づけます。
赤丸のOpenDatasetで、データ・セット一覧にして、赤四角のOpen Dataset で、フォルダを開き、各データセット用CSVを選択すればOKです。
各レイヤーのパラメータを設定する
以下の記事と手順は同じなので、繰り返し説明はしません。
上記の記事を参照してください。
違いは、上記の記事のデータが「25行1列」で、今回が「7行1列」という点だけなので、上記記事の「25」の部分を「7」に読み替えればいいだけです。
学習の実行
学習ボタンを押して、学習します。
結果はこんな感じです。
きれいに収束してますね。
評価の実行
続けて評価を行います。
1ファイルだけなので、あっさりしたものですね。
評価結果をインプットファイルに回す
ここからが、今回試してみたいことの肝です。
この評価によって出力されたX'のファイルをインプットに追加して、さらに、その先を予測してみる・・というのを試みます。
プロジェクトを保存したところにある files(プロジェクト名がmy_lstm.sdcprjなら、my_lstm.files)フォルダの下で、例によって、学習・評価の識別番号と同じフォルダの下の「0_0000」フォルダの下にいきます。
そこにある「0.csv」ファイルを、エディタ等で開くとこんな感じに、1行7列のデータになっています。
それを改行させて、7行1列のデータにして、「11.csv」等に名前を変更して保存します。
こいつを、データフォルダに移動させます。
そして、データ・セット用CSVのトレーニング用に、11.csvの行を追加して、バリデーション用のデータ・セット用CSVのファイル名も、11.csvに修正するんですね。
そうして、DATASETタブでもう一度、ファイルを読み込み直します。
そうして、trainingの件数が12になって、validationのファイル名が11.csvになってればOKです。
再度、学習させます。
このデータを追加してから、再度学習させるってのが、今回のアイディアの肝だと思ってました。
そうしないと、前のパラメータだと、何回評価だけを繰り返しても一番最初に評価したときと同じような結果しか出力されないはずだということですね。
再度評価して結果を確認する
ここで再度評価すると、新しいフォルダの0_0000フォルダの下に、0.csvができるんですね。
そうして、一つ前の評価結果の0.csvをコピーして、もとデータを作ったEXCELのデータ最後尾の次から「行列を入れ替えて値のみ貼り付け」をして、そして、その次に評価した結果の0.csvの内容もコピーして同じように後ろにくっつけます。
そうして、その結果に✕100000をして、もとの金額にもどしてやります。
上の黄色い網掛けの部分が、評価で出力された0.csvの中身を貼り付けたものです。
そして、その結果をグラフにしてやります。
赤枠で囲った部分が、評価によって出力されたX'の値です。
おお!
なんとなく、予測っぽく見えます。
ちゃんと、上昇トレンドはとれているし、日別の凸凹もトレースできてます。
なんて・・一瞬、思ってたんですけどね。
テンションあがってたのはここまで(笑)
しかし・・。
実際には、そんなわけありませんでした。
Ver1.00でやった時には、なんとなくいけてるように思えてたのですが、Ver1.10にバージョンアップしてやると数値が変わって、まんま、前の数値をなぞって生成しているという感じになってしまいました。
予測でもなんでもありません。
よいアイディアだと思ってみたんですけどね・・、そう甘くはありません。
ちょっとトホホでした。
今回のアプローチの反省点
RNN(リカレントニューラルネットワーク)での予測はしっかり結果(y)を推論するようにしないとダメなんだという、基本的な点が抜け落ちていたことですね。
Googleグループでも同じ話題がコメントされてました。
とにかく適切な学習データを多数用意できないと、ニューラルネットワークではろくなことにはならない・・ということです。
やれやれです。
2017/12/02追記
Version1.10では以下の部分のアイコンデザインが変更になってます。