はじめに
UKIです。
久しぶりのQiita投稿ですが、今回はデータやコードの記載のない個人的な雑感手記となります。いわゆるポエムでありテクニカルな記事ではないので限定記事に設定しています。
Kaggleへ初参戦
私がKaggleアカを作成したのは2017年のことでしたが、これまではTwo SigmaやJane Streetなど株価予測関連のコンペ概要やデータをチラ見するだけで、実際にサブミッションすることはありませんでした。
遡ること6月末、ツイッタのTLでKaggleで株価ボラティリティ予測コンペ(Optiver Realized Volatility Prediction)が開催されるという情報が流れてきました。ボラティリティの予測と言えば、今年の1月からSignateにてJQuantsが開催されましたね。このコンペは株価の高値安値レンジを予測するコンペでしたが(ボラティリティ予測とほぼ同じ課題です)、こちらでは幸運の加護もあり好成績を収めることができました(入賞者プレゼン)。従ってイキリ気味に「まあこっちも行けるやろ」と、8月中旬なってからようやく重い腰を上げKaggle初参戦を決意しました(6月末から参加しとけよと)。
さていざ参戦したところ、その参加者の多さに驚きました。おいおい、株価予測ってマイナーなジャンルやんけ…こんなに参加者おるの??「Kaggle新コンペ出たけど株価予測か…」というディスを見掛けるなど明らかな不人気感がある中でこれほどの参加者が集まるとは…Kaggle恐るべし。
んん、データ形式のparquetって何や??
なんやこれ他人のnotebookコピペできるんかい。
おおLBスコアめっちゃ優秀やん。
当然ですが、傍から見ているのと実際に参加するのでは大違いです。見るもの全てが新しい、こうして私の初めてのKaggleライフが始まったのでした。
ボラティリティの分布は美しい
ここからポエムが始まりますが、ボラティリティの分布は美しいですね。普段はリターン予測ばかりしており歪んだ分布に目が慣れてしまっているせいか、ボラティリティの分布はことさら美しいと感じてしまいます。しかもコイツらはきちんと自己相関してくれる。それだけで触っているだけで楽しかった。
二次元(112銘柄×3830時刻)で与えられたデータは縦軸、横軸どちらでカットしてもキレイな分布が得られます。分布のパラメータはまちまちで、ボラの大きい銘柄もあれば動きの落ち着いた時刻もある。これらの事象を全て1つのモデルで記述することが今回のコンペの目的です(1つじゃなくてもいいけど)。完全にチ。の主人公のような感覚に浸ってしまった私は、まずは手当たり次第にこれらの分布を確認していったのでした。
んん?ちょっと待て、なんだこの銘柄?
stock_id=31だけ明らかに挙動がおかしいですね。調べてみるとバーコード銘柄(板が厚いいわゆる1カイ2ヤリ銘柄)です。ははあ、バーコード銘柄が低ボラ領域で予測がブレるのか。仕方ない、コイツは汚いから別物として扱おう。
ということで訓練ではデータからstock_id=31は除外して学習させ、stock_id=31には個別で予測モデルを作ってやることにしました(この時点で早々に1モデルでの市場表現から外れてしまいました。二重の周転円的になっちゃったよ。この表現わかるかな)。
絶対値の予測は難しい
さて実際にデータをイジってみて気が付いたのですが、JQuantsだとCV等の訓練方法をあまり考えずとも性能の良いモデルができたのですが、こちらでは全く良いスコアが得られません。参加した当初、fitさせればよいというツイートをしましたがこれは間違いでした。
そもそもの原因を考えてみると、JQuantsとOptiverではデータの構造が違います。Optiverのデータは二次元(銘柄×時刻)ですが、JQuantsは一次元のデータ(銘柄のみ)です。各計算期間の日付にズレがあるものの、限定された一四半期における高値安値レンジの相対順位予測であり、このように期間を限定したランク予測が如何にロバストな問題設定かということを再認識しました。
少し話が逸れますが、株価の予測モデル(実際に運用するもの)を作るのであればやはり相対予測でなければなりませんね。問題設定でロバストネスを向上させることが何よりも重要です。この点から株式投資の手法としてロングショートを採用するだけで他者よりも十分有利な選択ができたと言えるでしょう。
ここでいう相対予測とは、単純に1対1でどちらが高くなるかを予測するというものではなく、100個くらいの予測対象があってそれらの順位を予測する。そうすると、例えばその予測結果を10分位したときに、TOP1とWORST1のQuantileを平均で見てみると、単純な予測よりもかなり確度を上げることができるということです(つまり株式予測の勘所を知らなくても適当にワークするモデルが作れる)。実際に利益の出る株式運用モデルが作れないという方は、ぜひとも検討してみてはいかがでしょうか。
マッチしないCV(Out of Fold)スコアとPublicスコア
さて、このコンペですがディスカッションでも度々「CVとPublicがマッチしない」という話を見掛けました。本コンペでは訓練データとPublic LBデータの日時は伏せられていましたが(ただし訓練データに対してPublicデータは未来の期間であり重複していない旨説明があった)、訓練データは2016年頃~2020年、Public LBデータは2021年1月~5月、Private LBデータは2021年10月~12月あたりだろうと勝手に想像していました。これらの期間は時系列に重なりがありませんし、ボラティリティにはそもそも定常性がないため、それぞれのデータにおいてボラティリティの分布はかなり異なると考えるのが普通です。よって、CVスコアとPublicとPrivateは同じスコア水準にはならないのはある意味当然の話です。
しかし、そこには違和感が存在しました。「CVに比べてPublic LBのスコアめちゃくちゃ高くね??」
普通に自分で検証を進めると、CVスコアは0.21程度でPublicに提出してもその程度となります。しかし公開されているハイスコアNotebookではCVに比べてPublicがやたらと良くなっているのです。一方でTOP勢はそれらの公開Notebookと比べてもさらに頭一つ抜け出していました。
よって公開NotebookにおけるCVとPublicの乖離を認識すると同時に、LB上位勢には2通りのパターンがあるのだなと感じました。1つは公開Notebookのコピペ&改良を繰り返して徐々にPublicスコアを底上げしてきた勢、そしてもう1つは公開されていない何らかのTipsに気付きブレイクスルーを達成した勢です。このうち後者がTOP勢となります。
フィッティングの可能性
「ああこれはアカンかも」
これまでに株価分析してきた経験上、すぐに思いました。アカンというのはつまり、株価は時系列で振る舞いが変わるため特定の期間のスコアを向上させることに意味がない、ということです。
特にLB勢の前者(公開Notebookをベースとしてスコアを底上げしている勢)は、この罠に陥る可能性が高くなってくると思いました。少しずつコードをイジりながら、少し改善すればそちらにベースを移す。ロバストな問題では良いと思いますが、非定常なデータでこれをやると完全なフィッティング作業になるのではないか?バックテストでパラメータ調整して良い成績を作り上げる、あの作業と酷似している印象です。
一方でLB勢の後者(頭一つ抜けた勢)のほうのトリックはよく分かりませんでした。Publicのスコアを向上するためにはValidationの方法に一工夫いれてValidationとPublicの相関を取らなければならないはずです。つまりPublicデータを模倣したvalidationサンプルを訓練データから生成する必要があったはずで(さらに言い換えると、2016~2020年のデータから2021年前半を模倣したValidationサンプルを作って)、これにはPublicデータの特徴量分布から訓練データを逆にリサンプルしたり、訓練データをボラティリティでクラスタリングしてvalidationしたり、色々と試しましたが私には再現できませんでした。これができたユーザーはガンガンPublicスコアを下げることができたのではないかと思います。
どちらにせよ上記のいずれにもフィッティングの懸念が付きまといます。よってPublicでハイスコアを狙うのではなくPrivateで好スコアを出せる方法はないか、CVスコアとPublicスコアを両睨みで向上させるよう検証を進めていくことにしたのでした(Publicスコアを伸ばせない負け惜しみじゃないよ)。
コンペの行方
正直、コンペの結果がどうなるのかよく分かりません。評価期間は21年10月~12月の3ヶ月間であり、この間にショックが起こってボラティリティが急上昇する可能性もあります。市況に伴ってPublicとPrivateの乖離具合も変わってくると思います。
現在のところLB順位は大きくシェイクされると考えていますが、一方で現在のLB TOP勢にはPrivateでも極端なハイスコアを叩き出してぶっちぎりで入賞してほしいとも思うのです。そうすれば私自身これまでの投資経験からは思いもよらないTipsを彼らのSolutionから得られるでしょう。
いずれにせよ、今年はコンペ2つ(JQuantsを2つとしてカウントすると3つ)に参加して非常に有益だったと思います。次はJQuantsの続編を心よりお待ちしております。