"BOKU"のITな日常

62歳・文系システムエンジニアの”BOKU”は日々勉強を楽しんでます

LSTMで売上の予測っぽいことを試みる時の失敗例。(;^_^A。/Neural Network Consoleの使い方

最初にお断りしておきますが、今回の記事は「うまくいかなかった例」です。 

恥ずかしながら、うまくいくと思ってやってみたけど、勘違いしていてダメだった)というのも情報だという開き直りで書いています(笑)。

f:id:arakan_no_boku:20190326212937j:plain

2017/12/02追記

>以降の説明の画面はVersion1.00のものを使ってます。

>Version1.10から一部アイコンのデザインが変わってます

>ただ、見たらわかる程度だと思ってますので貼り替えてません。


何をしようとしたか?

 

前回、SINカーブのトレースをやってみて、あることを思いついたわけです。

すなわち。

入力(X)に対して、Auto_Encoder的に出力(X')を比較的正確にトレースできた。

それを時系列データとして扱っているから、ある時点の入力(X)の次の状態(未来)を出力(X')は表している・・ということではないのか?です。

だとすれば、そのアウトプットを継ぎ足していけば、少しずつの未来になるから、未来の状態の予測にもなったりするんじゃないだろうか?と考えました。

で・・。

売り上げデータで試してみることにしました。

最初にも書いたとおり、今回は・・それがダメダメだったんですけどね。 

ちなみに、同じような売り上げデータを使って、もう少し、ましな予測っぽいことをやってみた記事はこちらです。

arakan-pgm-ai.hatenablog.com

 

さて、始めます

 

前回の続きです。

ネットワーク自体は、前回組んだものを、ほぼ、そのまま使います。

arakan-pgm-ai.hatenablog.com

  

売上データの用意

 

まず、元データとして11週間分の日別売上データを用意しました。 

だいたい3%から10%の範囲で凸凹しながら、トレンドとしては上昇傾向にあるデータにしてみました。

f:id:arakan_no_boku:20171024225404j:plain

グラフにすると、こんな感じです。

f:id:arakan_no_boku:20171024225540j:plain

このデータを7日間ずつの「7行1列」データにして、LSTMに学習させてみて、最終週のみの7日間で評価を行えば、0_0000フォルダに出力される出力(X')は、その近未来の数値なんじゃないか・・と考えたわけです。 

だったら、その売上予測のアウトプットを、インプットに追加して再学習させて、また最終週のみで評価することを繰り返せば、未来の「売上予測(みたいなもの)」になるかもしれないな・・・。

そういうことを考えたわけですね。  

 

売り上げデータの正規化

 

売上データを「-1.0 ~ 1.0」の数値に変換します。 

ここは単純に100000で割って、小数点以下四捨五入にいいでしょう。

f:id:arakan_no_boku:20171024230736j:plain

 

このC列に作ったデータだけを、7行ずつ11個のCSVファイルに分割します。

 

7行ずつ11個のファイルにわけるVBAソース

 

今回はシート名「forward01」に上記データを作成し、例によって以下のような使い捨てのEXCELマクロで作成しましたが、EXCELCSVファイルで保存して、手で加工してもできます。

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ファイルすべて。

f:id:arakan_no_boku:20171024232225j:plain

 

バリデーション用には、最後の10.csvファイルだけで作ります。

f:id:arakan_no_boku:20171024232408j:plain

 

これでデータの準備はできました。 

テキストデータのデータ・セット用CSVについては、以下の記事でも解説しています。

arakan-pgm-ai.hatenablog.com

 

LSTMのプロジェクトを開く

 

以下の記事で組んだLSTMのネットワークをそのまま使います。

arakan-pgm-ai.hatenablog.com

 

ニューラルネットワークコンソールを立ち上げて、上記の記事で保存したプロジェクトを開き、名前をつけて保存で、適当なプロジェクト名で保存します。

f:id:arakan_no_boku:20171025002950j:plain 

DATASETタブ

 

DATASETタブを開き、trainingとvalidationに、前に作成したトレーニング用データ・セットCSVとバリデーション用CSVを関連づけます。 

赤丸のOpenDatasetで、データ・セット一覧にして、赤四角のOpen Dataset で、フォルダを開き、各データセットCSVを選択すればOKです。

f:id:arakan_no_boku:20171025003431j:plain

 

各レイヤーのパラメータを設定する

 

以下の記事と手順は同じなので、繰り返し説明はしません。

arakan-pgm-ai.hatenablog.com

 

上記の記事を参照してください。 

違いは、上記の記事のデータが「25行1列」で、今回が「7行1列」という点だけなので、上記記事の「25」の部分を「7」に読み替えればいいだけです。

 

学習の実行

 

学習ボタンを押して、学習します。 

結果はこんな感じです。

f:id:arakan_no_boku:20171025003922j:plain

 

きれいに収束してますね。 

 

評価の実行

 

続けて評価を行います。

f:id:arakan_no_boku:20171025004201j:plain

 

1ファイルだけなので、あっさりしたものですね。

 

評価結果をインプットファイルに回す

 

ここからが、今回試してみたいことの肝です。 

この評価によって出力されたX'のファイルをインプットに追加して、さらに、その先を予測してみる・・というのを試みます。 

プロジェクトを保存したところにある files(プロジェクト名がmy_lstm.sdcprjなら、my_lstm.files)フォルダの下で、例によって、学習・評価の識別番号と同じフォルダの下の「0_0000」フォルダの下にいきます。 

そこにある「0.csv」ファイルを、エディタ等で開くとこんな感じに、1行7列のデータになっています。

f:id:arakan_no_boku:20171025005136j:plain

 それを改行させて、7行1列のデータにして、「11.csv」等に名前を変更して保存します。

f:id:arakan_no_boku:20171025005237j:plain

 

こいつを、データフォルダに移動させます。 

そして、データ・セット用CSVのトレーニング用に、11.csvの行を追加して、バリデーション用のデータ・セット用CSVのファイル名も、11.csvに修正するんですね。 

そうして、DATASETタブでもう一度、ファイルを読み込み直します。 

そうして、trainingの件数が12になって、validationのファイル名が11.csvになってればOKです。 

再度、学習させます。 

このデータを追加してから、再度学習させるってのが、今回のアイディアの肝だと思ってました。 

そうしないと、前のパラメータだと、何回評価だけを繰り返しても一番最初に評価したときと同じような結果しか出力されないはずだということですね。

 

再度評価して結果を確認する

 

 ここで再度評価すると、新しいフォルダの0_0000フォルダの下に、0.csvができるんですね。 

そうして、一つ前の評価結果の0.csvをコピーして、もとデータを作ったEXCELのデータ最後尾の次から「行列を入れ替えて値のみ貼り付け」をして、そして、その次に評価した結果の0.csvの内容もコピーして同じように後ろにくっつけます。 

そうして、その結果に✕100000をして、もとの金額にもどしてやります。

f:id:arakan_no_boku:20171025220923j:plain

 

上の黄色い網掛けの部分が、評価で出力された0.csvの中身を貼り付けたものです。 

そして、その結果をグラフにしてやります。 

赤枠で囲った部分が、評価によって出力されたX'の値です。

f:id:arakan_no_boku:20171025221256j:plain

 

おお! 

なんとなく、予測っぽく見えます。 

ちゃんと、上昇トレンドはとれているし、日別の凸凹もトレースできてます。 

なんて・・一瞬、思ってたんですけどね。

 

テンションあがってたのはここまで(笑)

 

しかし・・。

実際には、そんなわけありませんでした。

Ver1.00でやった時には、なんとなくいけてるように思えてたのですが、Ver1.10にバージョンアップしてやると数値が変わって、まんま、前の数値をなぞって生成しているという感じになってしまいました。

予測でもなんでもありません。

よいアイディアだと思ってみたんですけどね・・、そう甘くはありません。

ちょっとトホホでした。

 

今回のアプローチの反省点

 

RNN(リカレントニューラルネットワーク)での予測はしっかり結果(y)を推論するようにしないとダメなんだという、基本的な点が抜け落ちていたことですね。

Googleグループでも同じ話題がコメントされてました。

groups.google.com

とにかく適切な学習データを多数用意できないと、ニューラルネットワークではろくなことにはならない・・ということです。

やれやれです。

 

2017/12/02追記

Version1.10では以下の部分のアイコンデザインが変更になってます。

f:id:arakan_no_boku:20171130202351j:plain