1枚目画像のメモリの大きさを持った訓練データに対してlightgbmを使用して
時系列クロスバリデーションをしたところ、
下記画像のように、メモリエラーが発生しました。たった19.40MBもの訓練データから32.3Gibもの膨大なメモリ消費をする原因がわかっていません。
その時の学習実行コードは以下の通りです。(学習実行コードは下のほうへ移動しました。)
この大量のメモリ消費の原因と、解決策をご教授いただけませんか。
追記事項
バージョン
Python 3.8.10 pandas 1.2.5 lightgbm 3.1.1 notebook 6.4.0 py38haa95532_0 numba 0.53.1 py38hf11a4ad_0 numpy 1.20.2 py38ha4e8547_0 numpy-base 1.20.2 py38hc2deb75_0
それぞれva_period = 1で実行時の
訓練データ、検証データ
訓練データのy、検証データのyの大きさ
(254302, 10) (254302, 10)
(254302, 1) (254302, 1)
全コード # main module import matplotlib.pyplot as plt import seaborn as sns import pandas as pd import pandas_profiling as pdp import numpy as np import lightgbm as lgb from sklearn.metrics import log_loss import datetime import logging import sys, os sys.path.append('../src/') import eda import maprepro as mpre # import config # from utils import setup_logger, ModelFactory path = '../../input' sample = pd.read_csv(f'{path}/sample_submission.csv') store = pd.read_csv(f'{path}/store.csv') test = pd.read_csv(f'{path}/test.csv') train = pd.read_csv(f'{path}/train.csv') def mk_ymd(df): df['year'] = df.Date.apply(lambda x: x.split('-')[0]).astype(np.int16) df['month'] = df.Date.apply(lambda x: x.split('-')[1]).astype(np.int16) df['day'] = df.Date.apply(lambda x: x.split('-')[2]).astype(np.int16) df = df.sort_values('Date') return df train = mk_ymd(train) test = mk_ymd(test) # 時系列データであり、時間に沿って変数periodを設定したとする train['period'] = np.arange(0, len(train)) // (len(train) // 4) train['period'] = np.clip(train['period'], 0, 3) test['period'] = 4 train['StateHoliday'] = train.StateHoliday.astype('category') target = ['Sales'] notuse = ['Id','Date','Open'] use = ['Store','DayOfWeek','Open','Promo','StateHoliday','SchoolHoliday','year','month','day','period'] train_y = train[target] train_x = train[use] test_x = test[use] import warnings warnings.simplefilter('ignore') train_x = eda.reduce_mem_usage(train_x) >>>start size(BEFORE): 57.24 Mb >>>Mem. usage decreased to 19.40 Mb (AFTER:66.1% reduction) import gc gc.collect() va_period_list = [1, 2, 3] for va_period in va_period_list: is_tr = train_x['period'] < va_period is_va = train_x['period'] == va_period tr_x, va_x = train_x[is_tr], train_x[is_va] tr_y, va_y = train_y[is_tr], train_y[is_va] print(tr_x.shape, va_x.shape) print(tr_y.shape, va_y.shape) lgb_train = lgb.Dataset(tr_x, tr_y) lgb_eval = lgb.Dataset(va_x, va_y) # ハイパーパラメータの設定 params = {'objective': 'binary', 'seed': 71, 'verbose': 1, 'metrics': 'binary_logloss', 'force_col_wise':'true' # メモリが足りないから } num_round = 10 # 学習の実行 # カテゴリ変数をパラメータで指定している # バリデーションデータもモデルに渡し、学習の進行とともにスコアがどう変わるかモニタリングする categorical_features = ['StateHoliday'] model = lgb.train(params, lgb_train, num_boost_round=num_round, categorical_feature=categorical_features, valid_names=['train', 'valid'], valid_sets=[lgb_train, lgb_eval], ) # バリデーションデータでのスコアの確認 va_pred = model.predict(va_x) score = log_loss(va_y, va_pred) print(f'logloss: {score:.4f}') # 予測 pred = model.predict(test_x)
回答1件
あなたの回答
tips
プレビュー