とりあえず AI を試してみたい(だけどどこから手をつけてよいか分からなくて困っている)人にはよさそう……?
でも具体的になにができるんだろ。
今日のテーマ
Amazon Forecast でスクウェア・エニックスの今後1ヶ月分の株価を予測してみよう。
※ この記事の内容によって生じたいかなる損失についても、筆者は責任を負いかねます。
ちょっと最初にやる気を出すために、完成品イメージを先に貼っておこう。
今年1月のスクエニの株価を Forecast で予測してみたよ。
これが僕にも作れるようになるのか……
実習の流れ
今回の手順は以下の 6手です。 ですが、そのうち 5つは超簡単で失敗のしようがないので*1、実質的な関門は CSV ファイルを用意するところだけとなります。
しかも、今回はその CSV データも本記事の最後の方に添付していますので、実質手間ゼロで手軽に Forecast を試すことができます。
❶ CSV を作る
まずは、未来予測に必要な情報として、過去の実績データを CSV 形式で整形します。
Amazon Forecast には、さまざまな用途の時系列データを予測するためのデータセットドメインが用意されており、どれを選ぶかによって必要となる CSV 項目が少しずつ異なります。
参考: 事前定義済みのデータセットドメインとデータセットタイプ - Amazon Forecast
データセットドメイン | 目的 |
---|---|
RETAIL ドメイン | 小売の需要予測 |
INVENTORY_PLANNING ドメイン | サプライチェーンとインベントリの計画 |
EC2 CAPACITY ドメイン | Amazon EC2 キャパシティの予測 |
WORK_FORCE ドメイン | 従業員の計画 |
WEB_TRAFFIC ドメイン | 今後のウェブトラフィックの見積もり |
METRICS ドメイン | 収益およびキャッシュフローなどの予測メトリクス |
CUSTOM ドメイン | その他すべての時系列予測のタイプ |
CUSTOM ドメインの場合、CSV には item_id
、datetime
、target_value
という 3つの項目が必要です。
参考: CUSTOM ドメイン - Amazon Forecast
また、予測したい評価項目が1つだけの場合、各行の item_id
にはすべて同じ値を設定します。 あとで何を意味するデータだったのかが分かりやすいように、好きな文字列を設定しておきましょう(手順❻ で利用します)。
target_value
には、各日の終値を入れます。 すると、このような CSV が出来上がります(この記事の最後に、CSV データの完全版を掲載しています)。
取引のない土日祝日のデータが欠損しているけど(ピンクの矢印部分)、これはいいの?
大丈夫。
あとで予測子を作る際に補間するから問題ないよ。
ひとまずこれを 9684_2020.csv
という名前で保存しました。
❷ S3 バケットを作る
続いて、Forecast が参照できるファイル置き場を用意する必要があります。
おなじみ Amazon Simple Storage Service(通称 S3)というサービスに「バケット」と呼ばれるファイル置き場を作ります。
AWS マネジメントコンソールにログインし、S3 のダッシュボードから「バケットを作成」をクリックします。
続いて、バケット名に一意の名前をつけて、「バケットを作成」をクリックします。
❸ S3 バケットに CSV をアップロードする
先ほど作成した S3 バケットに、ローカルの CSV ファイルをアップロードします。
「アップロード」ボタン、もしくはファイルを直接ドラッグアンドドロップでアップロードが可能です。
アップロードが完了したら、CSV ファイル名のリンクをクリックして、「S3 URI」を確認しておきましょう。
❹ CSV を Forecast にインポートする
AWS マネジメントコンソールから、Forecast のダッシュボードを開き、「Create dataset group」をクリックします。
Dataset group name に任意の名前(ただし「-(ハイフン)」は使用不可)を、Forecasting Domain に Custom
をそれぞれ設定し、「Next」をクリックします。
さらに、Dataset name にも任意の名前を設定します。 ひとまず、スクエニの2020年の株価の推移データを取り込むので、square_enix_stock_2020
を指定しました。
Frequency of your data には、CSV の時系列データがどのくらいの間隔で記録されているかを指定します。 今回は、毎日の終値を記録したデータを用いますので、デフォルトの 1 day
になります。
少しスクロールすると、データセットのスキーマの設定を行うところがあります。 Timestamp format を、CSV に合わせて yyyy-MM-dd
に変更しましょう。
さらにスクロールすると、Dataset import name と Data locations を設定するところがあります。
Dataset import name には任意の名前を、Data locations には、手順❸ の最後で確認した「S3 URI」をそれぞれ設定します。
なお、タイムゾーンは利用しませんので、Select time zone はデフォルトの Do not use timezone
のままとします。
IAM ロールの作成
さらに、Forecast から S3 へのアクセス権(IAM ロール)を設定します。
IAM ロールは、新規に作成することも、既存のものを利用することもできます。 今回は新規に作成しましょう。
IAM role のドロップダウンから Create a new role
を選択します。
ここで、AWS アカウント内の全ての S3 バケットに対してアクセス権を付与するか、特定のバケットに対してのみアクセス権を付与するかどちらかを選ぶことができます。
今回は、手順❷ で作成したバケットに対するアクセス権のみを与えることにしました。
Create an IAM roleというモーダルダイアログボックスが起動しますので、ラジオボタンの Specific S3 buckets
を選択し、テキストボックスに S3 のバケット名( tercel-square-enix-stock
)を入力し、「Create role」ボタンを押してダイアログを閉じます。
すると、元の画面に IAM role が自動的に反映されますので、このまま「Start import」をクリックしましょう。 データのインポートが始まりますので、このまましばらく待ちましょう。
❺ 予測子を作る
データセットのインポートが終わると、ダッシュボードの Import your data - Target time series data のステータスが「 Active」に変わります。
さらに、Training a predictor - Predictor training にオレンジ色の「Start」ボタンが出現しますので、クリックします。
ここから、予測子の作成に必要な設定をしていきます。 まず、Predictor name には好きな名前を入れてください。
次に、予測の周期 (Forecast frequency) と期間 (Forecast horizon) を設定します。
たとえば、Forecast frequency が 1 day
の場合は、1日単位で予測が行われます。
Forecast horizon には、その周期を何回くりかえすかを設定します。
よって、もしForecast frequency に 1 day
、Forecast horizon に 30
と設定した場合は、おおよそ1ヵ月分、毎日の株価予想が得られることになります。
予測アルゴリズムの選択
少しスクロールすると、詳細の設定項目が現れます。
Algorithm selection では、Automatic (AutoML)
か Manual
のいずれかを選べます。 Manual
を選択した場合、さらに具体的な予測アルゴリズムを選択することになります。
デフォルト値である Automatic (AutoML)
は、Forecast が各アルゴリズムを評価した上で最適なものを自動選択してくれますので、通常はこちらを選んでおけばまず問題はないでしょう。
欠損データの補間設定
さらに、折り畳まれている Advanced configurations を展開します。
ここで、元の CSV データには土日祝や年末年始など、取引が行われなかった日のデータが欠損していたことを思い出してください。
これらの欠損データは、デフォルトでは「0」として扱われてしまいます。
とはいえ取引が行われないからといって、実際に株価が暴落しているわけではないため、欠損データをその前後の実績で適当に均してやる必要があります。
今回は、JSON の middlefill
, backfill
いずれにも、mean
を設定しました。
より詳細な解説は、以下の公式記事を参照してください。
参考: Amazon Forecast がサポートする自動補完機能による、ターゲットおよび関連データセット内での欠落した値の管理 | Amazon Web Services ブログ
一番下までスクロールして「Train predictor」をクリックしましょう。 予測子の作成が始まります。
ちなみに、予測子の作成には数十分〜数時間かかることもあるよ。
おぉぅ……
なので、CSV データは随時更新するけど、予測子は一度運用が始まったら、そうそう作り直したりはしない。
作り直すのはどんなとき?
予測に使えるパラメータが増えたり減ったりしたときとか、実際運用してみたらあまりにも予測精度が悪すぎて使い物にならなかったりしたときは見直すかもね。
なるほど。
❻ 予測を行う
予測子の作成が完了すると、データセットのインポートが終わると、ダッシュボードの Train a predictor - Predict training のステータスが「 Active」に変わります。
さらに、Generate forecasts - Forecast generation にオレンジ色の「Start」ボタンが出現しますので、クリックします。
Create a forecast 画面が表示されますので、Forecast name に適当な予測の名前(square_enix_stock_forecast
)、Predictor には使用する予測子として先ほど作成した square_enix_stock_predictor
をそれぞれ設定します。
Forecast typesは任意項目で、分位点回帰を指定します。 株価は突然高騰したり暴落したりしますので、おおよそ「このくらいの範囲で変動するだろう」という予測範囲の両裾を指定できるのです。
Forecast はデフォルトで 0.5(中央)および 0.1, 0.9 が指定されており、下振れした値から上振れした値まであたりをつけることができます。 今回はデフォルトのまま(何も入力せず)「Create new forecast」をクリックし、しばらく待ちます。
すると画面が切り替わり、ダッシュボードに「Lookup forecast」ボタンが出現しますのでクリックします。
Forecast に、先ほど作成した予測の名前(square_enix_stock_forecast
)、Start date と End date に表示期間の範囲、そして Choose the keys you want to use to filter your forecasts. - Value に、手順❶ の CSV で item_id
に設定した値を入力し、「Get Forecast」をクリックします。
ちなみに、Start date と End date に指定できる日付は、予測子を作成するときに指定した周期と期間によって決まります。
今回は 2020-12-30
までのデータを使い、周期を 1日、期間を 30に設定しましたので、 2021-01-29
まで予測できることになります。
万事うまくいくと、株価の予測グラフが表示されます。おめでとうございます。
はい、おしまい。
すごい、プログラムを1行も書かずに機械学習を試食できた……
これ、センサーから収集した時系列データとかを食わせたら楽しそうだよね。
I2Cで通信できる温湿度センサーを買って、ラズパイでグラフ化📈したいなあ。
— 紅茶 (@afternoonteeee) January 9, 2021
現状をグラフ化するだけじゃなくて、未来予知までできたら次のアクションも自動化できそう。
夢が広がるね。
おまけ
昨年1年間のスクウェア・エニックス(銘柄コード: 9684)の株価(終値)CSVデータ
item_value,datetime,target_value square_enix,2020-01-06,5270 square_enix,2020-01-07,5440 square_enix,2020-01-08,5370 square_enix,2020-01-09,5500 square_enix,2020-01-10,5670 square_enix,2020-01-14,5680 square_enix,2020-01-15,5430 square_enix,2020-01-16,5460 square_enix,2020-01-17,5480 square_enix,2020-01-20,5560 square_enix,2020-01-21,5520 square_enix,2020-01-22,5550 square_enix,2020-01-23,5540 square_enix,2020-01-24,5570 square_enix,2020-01-27,5520 square_enix,2020-01-28,5400 square_enix,2020-01-29,5420 square_enix,2020-01-30,5280 square_enix,2020-01-31,5380 square_enix,2020-02-03,5410 square_enix,2020-02-04,5490 square_enix,2020-02-05,5610 square_enix,2020-02-06,5200 square_enix,2020-02-07,5160 square_enix,2020-02-10,5200 square_enix,2020-02-12,5000 square_enix,2020-02-13,5040 square_enix,2020-02-14,5030 square_enix,2020-02-17,5010 square_enix,2020-02-18,4910 square_enix,2020-02-19,4975 square_enix,2020-02-20,4960 square_enix,2020-02-21,4945 square_enix,2020-02-25,4725 square_enix,2020-02-26,4660 square_enix,2020-02-27,4490 square_enix,2020-02-28,4350 square_enix,2020-03-02,4505 square_enix,2020-03-03,4530 square_enix,2020-03-04,4685 square_enix,2020-03-05,4680 square_enix,2020-03-06,4665 square_enix,2020-03-09,4395 square_enix,2020-03-10,4465 square_enix,2020-03-11,4260 square_enix,2020-03-12,4130 square_enix,2020-03-13,3920 square_enix,2020-03-16,3935 square_enix,2020-03-17,4225 square_enix,2020-03-18,4475 square_enix,2020-03-19,4760 square_enix,2020-03-23,4260 square_enix,2020-03-24,4680 square_enix,2020-03-25,4570 square_enix,2020-03-26,4570 square_enix,2020-03-27,4600 square_enix,2020-03-30,4845 square_enix,2020-03-31,4825 square_enix,2020-04-01,4800 square_enix,2020-04-02,4955 square_enix,2020-04-03,4965 square_enix,2020-04-06,5060 square_enix,2020-04-07,5000 square_enix,2020-04-08,4945 square_enix,2020-04-09,4930 square_enix,2020-04-10,4895 square_enix,2020-04-13,4950 square_enix,2020-04-14,4970 square_enix,2020-04-15,5130 square_enix,2020-04-16,5130 square_enix,2020-04-17,4995 square_enix,2020-04-20,4815 square_enix,2020-04-21,4695 square_enix,2020-04-22,4425 square_enix,2020-04-23,4525 square_enix,2020-04-24,4490 square_enix,2020-04-27,4530 square_enix,2020-04-28,4625 square_enix,2020-04-30,4405 square_enix,2020-05-01,4420 square_enix,2020-05-07,4535 square_enix,2020-05-08,4545 square_enix,2020-05-11,4675 square_enix,2020-05-12,4835 square_enix,2020-05-13,4950 square_enix,2020-05-14,4720 square_enix,2020-05-15,4770 square_enix,2020-05-18,4705 square_enix,2020-05-19,4740 square_enix,2020-05-20,4820 square_enix,2020-05-21,4875 square_enix,2020-05-22,4955 square_enix,2020-05-25,5060 square_enix,2020-05-26,5000 square_enix,2020-05-27,5140 square_enix,2020-05-28,5230 square_enix,2020-05-29,5230 square_enix,2020-06-01,5240 square_enix,2020-06-02,5300 square_enix,2020-06-03,5270 square_enix,2020-06-04,5270 square_enix,2020-06-05,5300 square_enix,2020-06-08,5310 square_enix,2020-06-09,5270 square_enix,2020-06-10,5460 square_enix,2020-06-11,5590 square_enix,2020-06-12,5450 square_enix,2020-06-15,5440 square_enix,2020-06-16,5530 square_enix,2020-06-17,5580 square_enix,2020-06-18,5640 square_enix,2020-06-19,5610 square_enix,2020-06-22,5610 square_enix,2020-06-23,5530 square_enix,2020-06-24,5500 square_enix,2020-06-25,5450 square_enix,2020-06-26,5510 square_enix,2020-06-29,5450 square_enix,2020-06-30,5440 square_enix,2020-07-01,5400 square_enix,2020-07-02,5450 square_enix,2020-07-03,5490 square_enix,2020-07-06,5500 square_enix,2020-07-07,5570 square_enix,2020-07-08,5490 square_enix,2020-07-09,5810 square_enix,2020-07-10,5520 square_enix,2020-07-13,5550 square_enix,2020-07-14,5450 square_enix,2020-07-15,5640 square_enix,2020-07-16,5450 square_enix,2020-07-17,5540 square_enix,2020-07-20,5760 square_enix,2020-07-21,5880 square_enix,2020-07-22,5870 square_enix,2020-07-27,5820 square_enix,2020-07-28,5780 square_enix,2020-07-29,5740 square_enix,2020-07-30,5670 square_enix,2020-07-31,5640 square_enix,2020-08-03,5700 square_enix,2020-08-04,5990 square_enix,2020-08-05,6050 square_enix,2020-08-06,6130 square_enix,2020-08-07,6890 square_enix,2020-08-11,6450 square_enix,2020-08-12,6430 square_enix,2020-08-13,6530 square_enix,2020-08-14,6740 square_enix,2020-08-17,6750 square_enix,2020-08-18,6920 square_enix,2020-08-19,6940 square_enix,2020-08-20,6940 square_enix,2020-08-21,6940 square_enix,2020-08-24,7150 square_enix,2020-08-25,7030 square_enix,2020-08-26,6980 square_enix,2020-08-27,7060 square_enix,2020-08-28,6850 square_enix,2020-08-31,6990 square_enix,2020-09-01,7120 square_enix,2020-09-02,7210 square_enix,2020-09-03,7320 square_enix,2020-09-04,7240 square_enix,2020-09-07,6900 square_enix,2020-09-08,6690 square_enix,2020-09-09,6710 square_enix,2020-09-10,6770 square_enix,2020-09-11,6670 square_enix,2020-09-14,6670 square_enix,2020-09-15,6750 square_enix,2020-09-16,6990 square_enix,2020-09-17,6860 square_enix,2020-09-18,6840 square_enix,2020-09-23,6910 square_enix,2020-09-24,6810 square_enix,2020-09-25,6990 square_enix,2020-09-28,6930 square_enix,2020-09-29,7010 square_enix,2020-09-30,6960 square_enix,2020-10-02,6890 square_enix,2020-10-19,6620 square_enix,2020-10-20,6470 square_enix,2020-10-21,6280 square_enix,2020-10-22,6440 square_enix,2020-10-23,6190 square_enix,2020-10-26,6080 square_enix,2020-10-27,6210 square_enix,2020-10-28,6230 square_enix,2020-10-29,6470 square_enix,2020-10-30,6120 square_enix,2020-11-02,6120 square_enix,2020-11-04,6200 square_enix,2020-11-05,6470 square_enix,2020-11-06,6470 square_enix,2020-11-09,5560 square_enix,2020-11-10,5150 square_enix,2020-11-11,5270 square_enix,2020-11-12,5520 square_enix,2020-11-13,5610 square_enix,2020-11-16,5490 square_enix,2020-11-17,5350 square_enix,2020-11-18,5340 square_enix,2020-11-20,5360 square_enix,2020-11-24,5630 square_enix,2020-11-25,5790 square_enix,2020-11-26,6020 square_enix,2020-11-27,6160 square_enix,2020-11-30,6410 square_enix,2020-12-01,6350 square_enix,2020-12-02,6300 square_enix,2020-12-03,6170 square_enix,2020-12-04,6350 square_enix,2020-12-07,6270 square_enix,2020-12-08,6460 square_enix,2020-12-09,6430 square_enix,2020-12-10,6330 square_enix,2020-12-11,6490 square_enix,2020-12-14,6440 square_enix,2020-12-15,6420 square_enix,2020-12-16,6450 square_enix,2020-12-17,6650 square_enix,2020-12-18,6590 square_enix,2020-12-21,6470 square_enix,2020-12-22,6060 square_enix,2020-12-24,6220 square_enix,2020-12-25,6150 square_enix,2020-12-28,6160 square_enix,2020-12-30,6260
*1:その代わり、待ち時間がめちゃくちゃ長い。