XGBoost 和 scikit-optimize:BayesSearchCV 和 XGBRegressor 不兼容 - 为什么?

问题描述

我有一个非常大的数据集(700 万行,54 个特征),我想使用 XGBoost 拟合回归模型。为了训练最好的模型,我想使用 BayesSearchCV 中的 scikit-optimize 对不同的超参数组合重复运行拟合,直到找到性能最佳的集合。

对于给定的超参数集,XGBoost 需要很长时间来训练模型,因此为了找到最佳超参数,而无需花费数天时间处理训练折叠、超参数等的每个排列,我想要多线程 XGBoostBayesSearchCV。我的代码的相关部分如下所示:

xgb_pipe = Pipeline([('clf',XGBRegressor(random_state = 42,objective='reg:squarederror',n_jobs = 1))])

xgb_fit_params = {'clf__early_stopping_rounds': 5,'clf__eval_metric': 'mae','clf__eval_set': [[X_val.values,y_val.values]]}

xgb_kfold = KFold(n_splits = 5,random_state = 42)

xgb_unsm_cv = BayesSearchCV(xgb_pipe,xgb_params,cv = xgb_kfold,n_jobs = 2,n_points = 1,n_iter = 15,random_state = 42,verbose = 4,scoring = 'neg_mean_absolute_error',fit_params = xgb_fit_params)

xgb_unsm_cv.fit(X_train.values,y_train.values)

但是,我发现当 n_jobs > 1 调用中的 BayesSearchCV 时,拟合崩溃并出现以下错误

TerminatedWorkerError: A worker process managed by the executor was unexpectedly terminated. This Could be caused by a segmentation fault while calling the function or by an excessive memory usage causing the Operating System to kill the worker.

The exit codes of the workers are {SIGKILL(-9)}

每当我在 BayesSearchCV 调用中使用超过 1 个线程时,此错误仍然存​​在,并且与我提供的内存无关。

这是 XGBoostscikit-optimize间的某种根本不兼容,还是可以以某种方式强制两个包一起工作?如果没有某种多线程优化方法,我担心拟合我的模型需要数周时间才能执行。我该怎么做才能解决这个问题?

解决方法

我不认为该错误与库的不兼容有关。相反,由于您要求两个不同的多线程操作,因此您的内存正在耗尽,因为您的程序试图将完整数据集放入 RAM 中,而不是一次而是 两次 用于多个实例(取决于线程)。

TerminatedWorkerError: A worker process managed by the executor was unexpectedly terminated. This could be caused by a segmentation fault while calling the function or by an excessive memory usage causing the Operating System to kill the worker.

The exit codes of the workers are {SIGKILL(-9)}

分段错误是指系统可用内存不足的错误。

请注意,XGBoost 是一个 RAM 饥饿的野兽,将它与另一个多线程操作结合起来势必会造成损失(个人而言,不推荐与日常驱动程序机器一起使用。)

最可行的解决方案可能是使用 Google 的 TPU 或其他一些云服务(注意成本),或者使用一些技术来减少数据集的大小,以便使用一些统计技术进行处理,例如本文中提到的那些{ {3}} 和 kaggle notebook

这个想法是,要么升级硬件(金钱成本),要么直接使用单线程 BayesianCV(时间成本),要么使用最适合您的技术缩小数据。

最后,答案仍然是这些库可能是兼容的,只是数据对于可用 RAM 来说太大了。