iTransformerの学習に使用する教師データって期間が偏っても良いのでしょうか?

実現したいこと

githubにアップされている「iTransformer」というモデルでいろいろな時系列データを予測する実験におけるTrain用、Test用、Validaition用の時系列データの選定方法をちゃんと理解したいのですが、選定方法について疑問を持ったので質問させていただきました。

発生している問題・分からないこと

Githubにアップされているこちらの実験について調べています。
この実験は論文としても公開されています。
iTransformer_Github
iTransformer_論文要約記事

この中のデータローダー(.\data_provider\data_loaderのDataset_Customクラス)について疑問を持ちました。以下に示すDataset_Customクラスでは、2020年1月1日から2021年1月1日までで10分刻みの21種類(気温や相対湿度、風速など)のデータを取り込んだりするのですが、コードの通りに処理を進めれば、最初の7割までのデータしか学習できず、後の3割のデータについては学習できなくないですか?
具体的に言うと1月~8月中旬までのデータをTrain用データ、8月中旬~11月初旬までをTest用データ、残りをVali用データみたいに選んでいませんか?もしそのように選んでいたのなら、モデルは9月から12月にかけての気象情報を学習できませんし、1月から8月のデータで検証やテストが出来ないですよね?それでも良いのですか?

実際にDataLoaderから提供されるTest用のデータを確認したところ、似たような気象情報のみしか提供されていませんでした。

該当のソースコード

python3

1class Dataset_Custom(Dataset): 2 def __init__(self, root_path, flag='train', size=None, 3 features='S', data_path='ETTh1.csv', 4 target='OT', scale=True, timeenc=0, freq='h'): 5 # size [seq_len, label_len, pred_len] 6 # info 7 if size == None: 8 self.seq_len = 24 * 4 * 4 9 self.label_len = 24 * 4 10 self.pred_len = 24 * 4 11 else: 12 self.seq_len = size[0] 13 self.label_len = size[1] 14 self.pred_len = size[2] 15 # init 16 assert flag in ['train', 'test', 'val'] 17 type_map = {'train': 0, 'val': 1, 'test': 2} 18 self.set_type = type_map[flag] 19 20 self.features = features 21 self.target = target 22 self.scale = scale 23 self.timeenc = timeenc 24 self.freq = freq 25 26 self.root_path = root_path 27 self.data_path = data_path 28 self.__read_data__() 29 30 def __read_data__(self): 31 self.scaler = StandardScaler() 32 df_raw = pd.read_csv(os.path.join(self.root_path, 33 self.data_path)) 34 35 ''' 36 df_raw.columns: ['date', ...(other features), target feature] 37 ''' 38 cols = list(df_raw.columns) 39 cols.remove(self.target) 40 cols.remove('date') 41 df_raw = df_raw[['date'] + cols + [self.target]] 42 num_train = int(len(df_raw) * 0.7) 43 num_test = int(len(df_raw) * 0.2) 44 num_vali = len(df_raw) - num_train - num_test 45 border1s = [0, num_train - self.seq_len, len(df_raw) - num_test - self.seq_len] 46 border2s = [num_train, num_train + num_vali, len(df_raw)] 47 border1 = border1s[self.set_type] 48 border2 = border2s[self.set_type] 49 50 if self.features == 'M' or self.features == 'MS': 51 cols_data = df_raw.columns[1:] 52 df_data = df_raw[cols_data] 53 elif self.features == 'S': 54 df_data = df_raw[[self.target]] 55 56 if self.scale: 57 train_data = df_data[border1s[0]:border2s[0]] 58 self.scaler.fit(train_data.values) 59 data = self.scaler.transform(df_data.values) 60 else: 61 data = df_data.values 62 63 df_stamp = df_raw[['date']][border1:border2] 64 df_stamp['date'] = pd.to_datetime(df_stamp.date) 65 if self.timeenc == 0: 66 df_stamp['month'] = df_stamp.date.apply(lambda row: row.month, 1) 67 df_stamp['day'] = df_stamp.date.apply(lambda row: row.day, 1) 68 df_stamp['weekday'] = df_stamp.date.apply(lambda row: row.weekday(), 1) 69 df_stamp['hour'] = df_stamp.date.apply(lambda row: row.hour, 1) 70 data_stamp = df_stamp.drop(['date'], 1).values 71 elif self.timeenc == 1: 72 data_stamp = time_features(pd.to_datetime(df_stamp['date'].values), freq=self.freq) 73 data_stamp = data_stamp.transpose(1, 0) 74 75 self.data_x = data[border1:border2] 76 self.data_y = data[border1:border2] 77 self.data_stamp = data_stamp 78 79 def __getitem__(self, index): 80 s_begin = index 81 s_end = s_begin + self.seq_len 82 r_begin = s_end - self.label_len 83 r_end = r_begin + self.label_len + self.pred_len 84 85 seq_x = self.data_x[s_begin:s_end] 86 seq_y = self.data_y[r_begin:r_end] 87 seq_x_mark = self.data_stamp[s_begin:s_end] 88 seq_y_mark = self.data_stamp[r_begin:r_end] 89 90 return seq_x, seq_y, seq_x_mark, seq_y_mark 91 92 def __len__(self): 93 return len(self.data_x) - self.seq_len - self.pred_len + 1 94 95 def inverse_transform(self, data): 96 return self.scaler.inverse_transform(data)

試したこと・調べたこと

上記の詳細・結果

実際にDataLoaderから提供されるTest用のデータを確認したところ、似たような気象情報のみしか提供されていませんでした。

補足

PyTorch

コメントを投稿

0 コメント