本コンペティションでは、米国証券取引所の株価推移データを用いて、1週間後の株価を予測するアルゴリズム開発に挑戦いただきます。
この10年で証券会社にとって、株価動向を予測するテクニカル分析へ機械学習モデルを用いることは、当たり前とも言える時代となりました。
今ではWealthNavi・大和証券など、多くの証券会社で機械学習モデルを搭載したロボアドバイザーがサービス提供されており、機関投資家だけではなく多くの個人投資家にとっても身近なものとなりつつあります。
さてこうしたテクニカル分析ですが、"モデル精度の向上"や"話題作り" といった目的で、国内外問わず様々なイベントでコンペティションが開催されております。
しかしながら通常スポンサー付きのコンペティションにおいては、知的財産権の都合上アルゴリズムを公開したり、自己投資への流用が許されないケースがほとんどでした。
そこで今回は、Open Review CompetitionであるProbSpaceの強みを活かし、誰でも自由に優勝者アルゴリズムを使えるよう、あえて定番である株価予測コンペを開催することといたしました。
MITライセンス化を優勝条件と定めておりますため、コンペ終了後、モデルを自由にご活用いただいて問題ございません。(優勝された方は、当ルールについてご了承願います)
株式投資に興味を持っていただく機会となり、また既に投資を行われている皆様にとっても有益なコンペティションとなれば幸いです。
2011/11/13~2019/11/17週の計419週間にわたる米国株データをもとに、2019/11/24週の終値を予測いただきます。
今回のコンペにおいては、純粋な時系列データ解析スキルの競技を目的とし、株価・ファンダメンタル情報に関する外部データの使用は不可といたします。
(外部データの使用も含めたコンペティションについては、また別の機会での企画を考えております)
ぜひとも、ご参画ください。
ProbSpaceでは、 データ関連人材を対象とした求人紹介サービスを提供しております。
Open to Workリーダーボードに参加されている方々に対し、ProbSpaceより転職求人、副業/フリーランス案件についてのメールを登録アドレスにお送りいたします。
ご希望の方は、コンペ終了までに下記参加手順よりOpen to Work リーダーボードにご参加ください。
データサイエンティスト様に限らず、データ活用に関連したエンジニア・コンサル・事業/企画部門の皆さまを対象としております。どうぞよろしくお願いいたします。
(Open to Workリーダーボードへの参加手順)
① リーダーボード右上の"LBチーム"をクリックし、LB設定ページを開く
② リーダーボードチームリストよりOpen to Workリーダーボードへの"参加申請"をクリック
※ 完了後、リーダーボードにOpen to Workが追加されます
100,000円
データをダウンロードするにはログインまたはユーザー登録して下さい
当コンペティションでは、下記3種類のデータが提供されます。
訓練データには、3,278銘柄の米国株それぞれについて、2011/11/13~2019/11/17週の終値が計419期分含まれています。
提出ファイル例を参考に、に2019/11/24週の終値、つまり2019/11/29の終値を予測し、ご提出ください。
3-4文字のアルファベットは、ニューヨーク証券取引所、NASDAQ、アメリカン証券取引所の証券コードです。
Date | NNN | FHN | ..... |
---|---|---|---|
日付(YYYY-MM-DD) | 銘柄NNNの価格 | 銘柄FHNの価格 | ..... |
..... | ..... | ..... | ..... |
米国における、2020年4月時点での各証券取引所取り扱い企業一覧です。
訓練データに含まれていない企業も掲載されています。
id | Name | IPOyear | Sector | Industry | List |
---|---|---|---|---|---|
NNN | 会社名 | 上場年 | セクター | 業界 | 証券取引所名 |
提出用のテンプレートファイルです。
予測された2019/11/24週の終値を入力し、ご提出ください。
(RMSLEでの評価となるため、値がマイナスとなる場合は提出エラーとなります。ご注意ください)
id | y |
---|---|
NNN | 銘柄NNNの価格 |
FHN | 銘柄FHNの価格 |
..... | ..... |
2011/11/13~2019/11/17週に及ぶ計419期の学習データを用いて、420期(2019/11/24週)の終値yを小数で予測してくだい。
モデルの予測性能は評価関数RMSLE(Root Mean Squared Logarithmic Error)で評価されます。
$$
\sqrt{\frac{1}{n}{\sum_{i=1}^{n}{(\log (Pred_i+1)-\log (Act_i+1))^2}}}
$$
回答用のsubmission.csvをご使用しyの値を予測値に変換して提出ください(エントリーとヘッダー行を含む) 。
提出されたファイルに余分な行や列(idとy以外)が含まれていた場合はエラーとなります。
提出ファイルは以下の列のみを必ず含んでください:
id,y
FLIR, 4838.42
本コンペでは、開催期間終了後 賞金対象者のコードを公開し、ユーザーの皆様にチーティング有無をレビューしていただき順位確定させる、オープンレビュー方式のコンペティションを行います。
コード公開後1週間:
レビュアー(ユーザー)より、チーティングの疑いに関するコメントがある場合は、ご回答をお願いいたします。
※チーティングとは無関係のコメント(ノウハウに関する質疑 等)についてもご回答いただけると幸いですが、順位確定の判断材料とは致しません。
レビュアーからの質疑と、回答状況をふまえて、最終的に運営側で順位確定を判断します。
開始 2021/9/21 0:00 JST
提出締切 2021/12/12 22:00 JST
LB公開 2021/12/13 0:00 JST
エントリー締め切り なし
※コンペ期間中であっても、不正が疑われる場合は、運営より確認のためメール連絡させていただくことがございます。一週間以内にご回答いただけない場合も、不正と判断させていただきます。
公平性の担保、チーティング等の不正防止のため、予告なくルールの追加・変更を行う場合がございます。
ご不便をおかけすることもあるかと思いますが、サービス向上のためご了承ください。
可能です。チームページから作成いただけます。
こちらから作成いただけます。
コンペティション参加にはアカウント登録が必要となりますのでご注意ください。
Seed を固定することが推奨です。
ただし、Seed を固定しなくても提出用コードとしては認めています。
このチュートリアルでは、時系列の株価情報データに対して
を行います。
#環境確認
import pandas as pd
import numpy as np
import statsmodels
!python3 --version
print(pd.__version__)
print(np.__version__)
print(statsmodels.__version__)
import matplotlib
print(matplotlib.__version__)
Python 3.9.6
1.3.0
1.20.3
0.12.2
3.4.2
まずはデータを読み込んで見ましょう。csvデータの読み込みは複数のやり方がありえますが、pandas
のread_csv
関数はその中でも機能が豊富で、扱いやすいためこれを使います。
これを使うと、csvデータを読み込み、pandas.DataFrame
にして返してくれます。
#データの読み込みと前処理
import pandas as pd
train_data = pd.read_csv("train_data.csv", index_col='Date')
print(train_data.shape)
(419, 3278)
また、DataFrame
には.head()
というメソッドが定義されており、これを呼び出すとDataFrame
の先頭の数行を確認できます。
train_data.head()
VGSH | JEF | IVZ | KTCC | FBZ | PLOW | JBK | IAC | IVR | VSH | ... | ASFI | JTA | MNR | TFSL | GTN | TYG | VIRC | BIS | WOOD | MASI | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Date | |||||||||||||||||||||
2011-11-13 | 55.942184 | 17.649006 | 13.770864 | 4.77 | 13.818835 | 10.198389 | 12.440549 | 38.484608 | 4.836254 | 8.575465 | ... | 3.721562 | 4.747546 | 5.567790 | 7.262252 | 1.80 | 20.079035 | 1.504111 | 826.767029 | 30.918266 | 18.430309 |
2011-11-20 | 55.978844 | 16.270664 | 12.719761 | 4.94 | 12.744166 | 10.035272 | 12.065370 | 36.252533 | 4.658076 | 7.657301 | ... | 3.590744 | 4.549112 | 5.473421 | 7.125532 | 1.56 | 19.711763 | 1.474619 | 769.836304 | 29.410889 | 17.534525 |
2011-11-27 | 56.021038 | 18.813454 | 14.402946 | 4.82 | 13.918125 | 10.510439 | 12.285713 | 39.479744 | 4.966706 | 8.611118 | ... | 3.608788 | 4.851724 | 5.372760 | 7.616116 | 1.70 | 20.698137 | 1.572927 | 672.212830 | 31.723339 | 19.631044 |
2011-12-04 | 56.002697 | 18.425301 | 14.758045 | 4.73 | 13.994051 | 10.652282 | 12.148743 | 38.856613 | 4.680348 | 8.406092 | ... | 3.541123 | 4.931097 | 5.498586 | 7.350718 | 1.74 | 20.010817 | 1.779373 | 694.906921 | 31.577734 | 19.383274 |
2011-12-11 | 56.030224 | 17.676432 | 13.664331 | 4.55 | 13.445042 | 10.449807 | 12.053457 | 38.624111 | 4.772620 | 7.719699 | ... | 3.577211 | 4.734335 | 5.662159 | 6.956642 | 1.74 | 20.336115 | 1.297665 | 702.928040 | 30.412945 | 18.201599 |
5 rows × 3278 columns
いくつかのデータを可視化してみましょう。時系列データの可視化にはmatplotlib
を用います。
import matplotlib.pyplot as plt
%matplotlib inline
fig, ax = plt.subplots(8, 2, figsize=(12, 16))
for i in range(16):
ax[i//2, i%2].plot(train_data.iloc[:, i])
似たような推移をしている銘柄があるようです。似ている動きのの銘柄の情報をうまく扱えると精度を向上させることができるかもしれません。
続いて、下記のコードを使用して使用するデータ全体の概観を確認します。
train_data.dtypes
VGSH float64
JEF float64
IVZ float64
KTCC float64
FBZ float64
...
TYG float64
VIRC float64
BIS float64
WOOD float64
MASI float64
Length: 3278, dtype: object
データの形式を見ると、すべてのデータはfloat64
型になっているようです。
all(train_data.dropna() == train_data)
True
欠損値は存在しないようです。
モデルに投入する目的変数(y)、説明変数(X)を作成します
model.fit('説明変数','目的変数')
と記述することでモデルの学習が可能となります。目的変数を説明変数の組み合わせで説明可能な回帰モデルを作成できます。
from statsmodels.tsa.api import VAR
m=VAR(train_data.values[:-50])
r=m.fit(5)
p=r.forecast(train_data.values[:-50],50)
plt.plot(train_data.iloc[:,0])
plt.plot(range(len(train_data.values)-50,len(train_data.values)),p[:,0],c="tab:blue",linestyle="--")
[<matplotlib.lines.Line2D at 0x11ee25a60>]
破線が予測の値になります。直近のデータの変動に大きく影響を受けるようです
また、コンペの評価指標となるrmsle
についても計算できます。
正解データを用いてrmsle
を計算するために最終期のデータを除いて学習を行い、最終期のデータを予測したいと思います。
モデルを元にした予測値は、model.forecast('説明変数')
で表します。
from sklearn.metrics import mean_squared_log_error
eval_model = VAR(train_data.values[:-1])
eval_results = eval_model.fit(5)
eval_pred = eval_results.forecast(train_data.values[:-1], 1)
eval_pred[eval_pred < 0] = 0
print(np.sqrt(mean_squared_log_error(eval_pred.flatten(), train_data.values[-1])))
0.1314633377924251
今回作成したモデルのrmsle
は0.1314程度でした。
最後に、作成したモデルを使用して提出データを作成します。forecast
メソッドを用いて学習データの1期先のデータを予測します。
pred = eval_results.forecast(train_data.values, 1)
submit_df = pd.DataFrame(pred, columns=train_data.columns)
submit_df = submit_df.transpose()
submit_df.columns = ['y']
submit_df.index.name = 'id'
submit_df.where(submit_df['y'] > 0, 0)
submit_df.to_csv('submission.csv')
コンペティションへの参加に際しては、ProbSpace利用規約(以下、「利用規約」といいます。)に加え、本ProbSpace参加規約(以下「本規約」といいます。)に同意いただく必要があります。利用規約にて定義された用語は、本規約においても同様の意味で用いられるものとします。
第1条(適用)
第2条(定義)
本規約において次の各用語の定義は、それぞれ以下に定めるとおりとします。
第3条(権利の帰属)
第4条(入賞者の義務)
第5条(禁止事項)
第6条(本コンペの変更、中断、終了等)
第7条(損害賠償)
第8条(本規約の変更)
当社は、必要と判断した場合には、参加者に対して事前に通知する(本コンペにかかる当社ウェブサイト上での告知その他当社が適当と認める方法を含みます。)ことにより、いつでも本規約を変更することができるものとします。なお、変更内容の通知後、参加者が当社の定める期間内に本コンペへの参加を取り消す手続をとらなかった場合には、当該参加者は変更後の規約に同意したものとみなされます。当社は、本規約の変更により参加者に生じたすべての損害について一切の責任を負いません。
第9条(その他)
本契約の準拠法は日本法とし、本契約に起因し又は関連する一切の紛争については、当社の本店所在地を管轄する裁判所を第一審の専属的合意管轄裁判所とします。
(制定)2020年6月22日