【投資・R】統計や機械学習使って"金持ち"になりたい~prophetでインスタント予測~【第5話】

さて、散々頑張ってきましたがどうやら予測は難しいようです。
データがノイズ多いのか
やり方にコツがあるのか
沖本先生に弟子入りしたい。。。

前から試してみたかったパッケージを使ってみたいと思います。
一応最終回です。

#でた、prophet

時系列の解析ライブラリとして2017年に現れたprophetですが、
簡単でそれっぽい予測ができると聞いて試してみたいと思いました。

時系列といえばよくお邪魔しているブログにも時系列の話が取り上げられていて、
「LSTMのようなディープラーニングよりも古典的な移動平均やARIMAモデルのようなものが時系列をうまく表現する傾向にある」
なんて記事を拝見しました。

ド素人の個人的な意見ですが、
ディープラーニングのように過去のデータの"パターン"から値を推定する手法と、
データの周期から将来も同じ周期で同じ形の波形が生成されるであろう、
と推定する手法を比べると、
後者のほうが時系列のパターンを表現できるので直観的にも当たりそうだと思っています。

機械学習全般に言えることですが、時系列の推定のようにデータの無い部分を推定するのは苦手な分野です。
特に株や需要のような突発的なノイズが複数絡んでいるものに関しては尚のことモデル化するのは難しいでしょう。

もしも丁寧にノイズを分析して、ノイズのパターンを見つけ出し、取り除いたとしても、
新しく現れるデータに"新しいノイズ"が入ってきたらモデルはパーです。

ならばある程度のざっくりとした"方向"だけを教えてくれるような分析をしたらいいのではないでしょうか？

そんなことを実現させてくれるのがprophetです。
・・・・ですよね？

トレンド成分は、時系列が上昇し続けるならば正の傾きを持つ直線にたとえてくれます。
もしもデータが今は上昇していても、いずれ限界で収束(飽和)するような場合にはシグモイドカーブを使って非線形を表現してくれます。
飽和の限界値は人間から指定してやることで、加味して調整してくれます。

周期は、どの期間で、どんな波形をしているのかをフーリエ変換して求めているようです。

原理とか設計思想とかは全くワカランなので公式の出しているpdfをこれから読みます。

#やってみる

prophetの一番良いところはdsとyの二つを突っ込んだら何も指定せず
"それっぽいこと"をしてくれる部分だと思っています。
データの質から分析方針など、時系列に完全を求めだすと時間や労力(私は追加で精神力と眼精疲労)を持っていかれますが、
「それっぽいデータをチャチャっと出してから考える」という事が出来るのが醍醐味かと。
まずは完全デフォルト。

```r
library(prophet)
library(ggplot2)


prophet_df<-data.frame(ds=fill_data$day, y=fill_data$move)
m <- prophet(prophet_df)
future_df <- make_future_dataframe(m, 365)
pred <- predict(m, future_df)
plot(m, pred) + ggtitle("Prophet Forecast Plot")
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/f9c27189-ceb9-1263-df1c-dc323468c3d7.png)


ネット上でstanのパッケージも必要とのコメントをみました。
もし動かなければ以下も試してみてください。

```r
install.packages("rstan", repos = "https://cloud.r-project.org/",dependencies=TRUE)
```



一年分予測させてみました。
予測できてそうに見えます。
一方で単純にトレンド成分から行先を予測しているだけにも見えます。

信頼区間のカタチを確すると2020年を超えたあたりで上がり気味の可能性も見えるようです。
信頼区間はあまりアテにはなりませんが、
大暴落した後などに「上がる可能性もある」、と分かっただけで少しは生きる希望が持てそうです。


```r
dyplot.prophet(m, pred)
```

こんな指定をしてやるとレポートがブラウザで起動してくれます。
カーソルを合わせるとデータも表示されるし、
拡大などもできるので便利です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/0f284e05-077a-bc0b-4933-0e046c469836.png)

```r
prophet_plot_components(m, pred)
```

prophetがデータからどんな特徴を掴んでplotしているのかを確認してみます。

トレンド成分
・上がり調子であったが、いくつかの変化点を経て、現在は下がりの一直線を予測している。

週次成分
・月曜から金曜までに上がり、土日で下がる。

月次成分
・6月と8月に上がり、7月に下がる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/af6ecfbc-e921-0c05-0948-5e4013edd86b.png)


これだけデフォルトで出るならもう難しいことを考える前にとりあえず実行も魅力的かもしれません。

#パラメータを変更してみる

prophetには

```
function (df = NULL, growth = "linear", changepoints = NULL, 
    n.changepoints = 25, changepoint.range = 0.8, yearly.seasonality = "auto", 
    weekly.seasonality = "auto", daily.seasonality = "auto", 
    holidays = NULL, seasonality.mode = "additive", seasonality.prior.scale = 10, 
    holidays.prior.scale = 10, changepoint.prior.scale = 0.05, 
    mcmc.samples = 0, interval.width = 0.8, uncertainty.samples = 1000, 
    fit = TRUE, ...) 
```

このくらいの設定項目があるようです。
holidayにはトレンドが上昇するか下降するかなどを含めることが出来ます。
今回のデータには入れません。

#パラメータを明示

```r
m = prophet(prophet_df, 
    growth="linear", n.changepoints = 25, changepoint.range = 0.8,
    yearly.seasonality = "auto", weekly.seasonality = "auto",  daily.seasonality = "auto", 
    holidays = NULL, seasonality.mode = "additive", seasonality.prior.scale = 10,
    holidays.prior.scale = 10, changepoint.prior.scale = 0.05,
    mcmc.samples = 0, interval.width = 0.8, uncertainty.samples = 1000,fit=T
)

future_df <- make_future_dataframe(m, 600)
pred <- predict(m, future_df)
plot(m, pred)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/b915b232-7db7-9c0a-ac40-28e7c0960d1d.png)

#change pointの変更

n change pointsでは、トレンドの変化を一旦区切る点を等間隔に配置してくれるものです。

5の時

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/de00eb63-fa0f-f3ef-0f99-cc4ca318ddde.png)


1000の時
とても時間がかかります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/fbc5cf36-30bf-65b6-f35c-d5ef8fc2b4ad.png)



予測側のトレンドである青色の線が、黒色の実データに寄っているのがわかります。
変化点を増加させることで、実データを表しやすくなっています。
やりすぎるとオーバーフィットします。



#change point priorの変更　ncahageは25戻す

0.01のとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/5d71bf0b-59ca-ac52-8e65-be2ab2284287.png)



0.1のとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/abe50c11-41ac-c903-8540-27315a2c8fe0.png)


1のとき

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/2dc29acd-65a6-31a9-a14c-63baecce6e2c.png)



元データにフィットさせようと頑張ってくれます。

直近のデータには狭い範囲の信頼区間で予測していますが、
ちょっと先のデータでは突然確度が下がります。
元データに合わせすぎているので、汎化性能が下がっているということでしょうか。

これも挙動が確認できたので0.05に戻します。

#cange point range

1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/db0cf4f9-6d01-a1e2-e62a-1d3ac436bce1.png)



0.1

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e8175f69-8357-7cd5-97fc-2d9925369f19.png)


値が1に近いほどトレンドに対してfitさせようとして、
0に近いほどデータの傾向を無視して線形回帰のような結果になります。

0.8にもどします



#uncentainty

2000にする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/96480752-a6b8-f8fb-50d0-ad7759d5974f.png)

4000


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/841ec3ad-53d0-0ea5-0fdf-0c3513459cf9.png)


100

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/4fc375a2-115b-5d68-090c-0079843816c0.png)

100のときは信頼区間の刻みが細かくなっています。



1000にもどす


#周期
year T
week F
day  F

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d8575c6c-8669-4fe9-75f5-ce586667904e.png)


year T
week T
day  F



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/0a89641f-47ca-f554-0f09-ff5d96115a86.png)




year T
week T
day  T



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/776acfff-5754-61b1-7654-a3fef148ecea.png)



year F
week F
day  T




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/091a47f1-8c17-4b79-3e75-d4094fc6d26a.png)




year F
week T
day  F


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/100f5c51-526a-36c3-a923-16cb32812c66.png)


曜日と言えば、曜日をデータ中に明示することも可能です。

```r
Sys.setlocale("LC_TIME")
daily_data_weekday <- prophet_df
daily_data_weekday$weekdays <-  weekdays(as.POSIXct(prophet_df$ds))# 曜日で色分けしてプロット
p <- ggplot(daily_data_weekday, aes(as.POSIXct(ds),y, group=1))
p <- p + geom_point(aes(colour=weekdays))
p <- p + theme(axis.title.x = element_blank())
p
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/e84f3550-b057-55f0-390a-934144b0bb6c.png)

何年間というデータでなければ、曜日ごとの影響など見つけやすくなるので分析時にも使えます。

#cange pointの図示



```r
plot(m, pred)+ add_changepoints_to_plot(m)
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/ee319ed8-9cef-56c6-e7d6-dfceca5cb59f.png)



#seasonality mode 乗法的にする multiplicative


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/77ae9df8-b9c5-7d40-6e14-028e78199bc1.png)





#結果発表！！

分からない部分も多いですが、
こうして色々いじっているうちに使い方は理解できました。
おそらく。きっと。たぶん。

あとは色々なデータに対して試したり、
綺麗な周期をもつものに対して試すなど経験値を積んで、
もうちょっと本を読みたいと思います。

好きな銘柄を買って、それっぽい数字を見てニヤニヤできるのも楽しいのではないでしょうか。

#お金がたまったら実践

以上

#参考ページ
https://cran.r-project.org/web/packages/prophet/vignettes/quick_start.html
http://datalove.hatenadiary.jp/entry/python/prophet/getting-started-with-facebook-machine-learning-library-for-time-series-analysis
https://www.medi-08-data-06.work/entry/prophet_forecats
https://dev.classmethod.jp/statistics/basis-of-ts-data-analysis-reading-memo/
https://tjo.hatenablog.com/entry/2013/07/04/190139
https://www.procrasist.com/entry/13-prophet
https://logics-of-blue.com/time-series-regression/
https://haltaro.github.io/2018/07/22/summer-prophet
https://www1.doshisha.ac.jp/~mjin/R/Chap_33/33.html
https://www1.doshisha.ac.jp/~mjin/R/Chap_34/34.html
https://www1.doshisha.ac.jp/~mjin/R/Chap_35/35.html
https://qiita.com/japanesebonobo/items/96868e58d4da42d36807
http://funyakofunyao.click/2017/05/07/prophet%E3%83%88%E3%83%AC%E3%83%B3%E3%83%89%E5%88%86%E6%9E%90%EF%BC%88%E9%9D%9E%E7%B7%9A%E5%BD%A2%E6%88%90%E9%95%B7%E3%83%A2%E3%83%87%E3%83%AB%EF%BC%89/
https://cran.r-project.org/web/views/TimeSeries.html
https://tjo.hatenablog.com/entry/2013/10/30/190552
https://mode.com/example-gallery/forecasting_prophet_r_cookbook/
https://codeday.me/jp/qa/20190531/908538.html

http://ill-identified.hatenablog.com/entry/2018/05/28/020224
https://www.rdocumentation.org/packages/stats/versions/3.6.1/topics/stl

https://samurai-0517.hatenadiary.org/entry/20110118/1295349084
https://teramonagi.hatenablog.com/entry/20111201/1322686548