時系列データにCross validationするときの注意点
はじめに
論文ではなく、以下の記事から。
- splitting a time series without causing data leakage
- using nested cross-validation to obtain an unbiased estimate of error on an independent test set
- cross-validation with datasets that contain mltiple time series
とのこと。時系列データからleakさせずにtest set, validation setをどう取れば良いか悩んでいて発見。 わかりやすくまとまっていてありがたい。
通常のnested cross validationについては以下を。
要約
・時間依存性があるので、out-of-sampleへのaccuracyを予測するためには、K-Fold CVではなく、純粋に時間軸に沿って一番古いデータをtraining set, 次に新しいグループをvalidation set, 一番新しいグループをtest setにするとよい
・ただ、それではtest setは限定されるので、out-of-sampleのデータに対するaccuracyの予測としてはブレるかもしれない。accuracyを予測するouter loopとしてある特定の時刻までのデータセットを作り、その中でinner loopとして時間軸に沿ってtrain set, validation set, test setを作る(nested cross-validation)。
・Day-forward-Chainingと呼ぶ。Rolling-originとも呼ばれる方法の一種。
・多系統時系列(医療系データを想定していて、patientあたりの系列となっている)に対するnested cross-valiadtion:
Regular:すべての系統に対して、時期で区切った分割を行う
Population-Informed:ある一系統の中で時期を区切り、それ以外の系統のデータはすべてtrain setとしたものをひとつのtrain/validation/testとして、それをcrossさせる。
感想
postの最後でも触れられていたけど、population-informed approachでnested cross-validationにするのは、データセットによっては試行回数が増えすぎて大変そう。leave-one-outっぽいイメージ。系列数が十分多ければ、純粋にpopulation-based cross validationとするだけでも良さそうな気がする。
時系列データを使って未来の時系列を予測するなら、このpostで触れられていたような方法が良いし、時系列データからなにか別のfeatureを予測したい、というのであれば、純粋にpopulationだけで分離するのが良いか。
いずれにせよ、時系列データではデータやモデル(何を使って何を予測するか)に応じて、leakageに十分注意してvalidation/testしないといけない。
p.s.
参考文献で触れられているけど、こちらの論文を参考にしたとのこと。"Rolling Origin"で検索しても似たようなpostがちらほら見つかる。
追記
'Day-forward-Chaining'については、scikit-learnでも実装されていた!
sklearn.model_selection.TimeSeriesSplit — scikit-learn 0.21.2 documentation