時系列のスプリットを作成する
動画では、時系列データを無作為に分割すると、未来のデータが混入してモデルが過学習する危険があることを学びました。時系列では、新しいデータが入手できるたびに蓄積され、最新データでモデルを再学習したくなることがよくあります。動画では学習用・テスト用に百分率で分割する方法を紹介しましたが、ここでは「直近45日分をテスト用にし、それ以外のすべてを学習用にする」ケースを考えます。
この演習では、テスト用に直近45日分を使い、残りを学習用にするための分割日を求める関数を作成します。timedelta() は標準の python ライブラリ datetime から既にインポート済みです。
この演習はコースの一部です
PySparkで学ぶ特徴量エンジニアリング
演習の手順
- データフレーム
df、分割に使う日付列split_col、テスト用日数test_days(デフォルトは45)を受け取る関数train_test_split_date()を作成します。 ,()を使ってsplit_colのmin日付とmax日付を求めます。max_dateからtimedelta()(days引数にこの場合はtest_daysを渡します)でtest_daysを引いて、学習用とテスト用を分ける分割日を求めます。OFFMKTDATEをsplit_colにしてsplit_dateを求め、その日付でデータフレームをtrain_dfとtest_dfの2つにフィルタします。test_dfはデータの直近45日分のみとし、さらにdf['LISTDATE']がsplit_date以下の住戸(分割日時点で掲載されている住戸)のみを含むようにフィルタします。
実践的なインタラクティブ演習
このサンプルコードを完成させて、この演習に挑戦してみましょう。
def train_test_split_date(df, split_col, test_days=____):
"""Calculate the date to split test and training sets"""
# Find how many days our data spans
max_date = df.____({____: ____}).collect()[0][0]
min_date = df.____({____: ____}).collect()[0][0]
# Subtract an integer number of days from the last date in dataset
split_date = ____ - timedelta(days=____)
return split_date
# Find the date to use in spitting test and train
split_date = train_test_split_date(df, ____)
# Create Sequential Test and Training Sets
____ = df.where(df[____] < split_date)
____ = df.where(df[____] >= split_date).where(df[____] <= split_date)