使用RandomizedSearchCV在sklearn中进行超参数调优耗时过长

我正在处理一个包含13个特征和550068行的数据集。我进行了k折交叉验证,并选择了k值为10,然后选择了均方根误差最小的最佳模型,在我的案例中是梯度提升回归器。接下来我进行了超参数调优,以下是我的代码:

from sklearn.ensemble GradientBoostingRegressorgradientboost = GradientBoostingRegressor(n_estimators = 300)from sklearn.model_selection import RandomizedSearchCVloss = ['ls', 'lad', 'huber']n_estimators = [100, 500, 900, 1100, 1500]max_depth = [2, 3, 5, 10, 15]min_samples_leaf = [1, 2, 4, 6, 8] min_samples_split = [2, 4, 6, 10]max_features = ['auto', 'sqrt', 'log2', None]# Define the grid of hyperparameters to searchhyperparameter_grid = {'loss': loss,    'n_estimators': n_estimators,    'max_depth': max_depth,    'min_samples_leaf': min_samples_leaf,    'min_samples_split': min_samples_split,    'max_features': max_features}# Set up the random search with 4-fold cross validationrandom_cv = RandomizedSearchCV(estimator=gradientboost,            param_distributions=hyperparameter_grid,            cv=4, n_iter=50,            scoring = 'neg_mean_absolute_error',n_jobs = 4,            verbose = 5,             return_train_score = True,            random_state=42)random_cv.fit(features,target)

超参数调优花费了大量时间,几乎用了48小时但尚未完成。我尝试了不同的n_jobsn_iterscv值,但进程并未加速。enter image description here。我还将数据集分成了5个相等的部分,并尝试对单个部分进行参数调优

dataframe_splits = np.array_split(dataframe, 5)features = dataframe_splits[0].drop(columns= ['Purchase','User_ID', 'Product_ID'])target = dataframe_splits[0]['Purchase']

但这也不奏效。单个部分的调优也花费了大量时间。我使用的是Windows 10操作系统和英特尔i5第七代处理器。谁能帮我解决这个问题?提前感谢。


回答:

这是几个因素共同作用的结果:

  • 拥有五十万个样本,
  • 使用了大量集成的梯度提升,
  • 搜索网格通常较大,
  • 进行10折交叉验证。

在本地机器上训练这样的模型不会有太大进展。如果你不是在训练一个生产级别的模型(而是更像是一个副业或大学项目),可以尝试以下方法:

  • 将样本量大幅减少(例如10k样本),
  • 尝试深入了解每个超参数的作用以及梯度提升的工作原理。例如,在你的网格中使用的损失函数不会产生巨大的差异,而你却遗漏了一个非常重要的参数’learning_rate’。同样适用于’max_features’ – ‘auto’和’none’本质上是相同的,最好尝试一些浮点数进行实验。
  • 调整较少的参数。目前你是从3 * 5 * 5 * 5 * 4 * 4 = 6000种可能的组合中随机抽取50种。你可以从较小的网格开始(例如100/200种可能的组合),并抽取较少的组合,看看哪些参数变化最大,然后尝试一次调整几个参数,而不是所有参数。其中最耗费资源的参数是’n_estimators’,因为它将’n_estimators’棵树组合成一个集成来形成完整的模型。首先找到一个接近’偏差/方差’权衡边缘的估计器数量,然后将其放入网格中会是一个好的开始。
  • 将k的数量减少到8甚至5,这应该会立即大幅减少运行时间。

如果你是在进行生产规模的训练并希望使用整个数据集,你需要获取一些额外的强大计算资源,比如虚拟机和/或使用其他用于训练梯度提升树的包,例如xgboostLightGBM。这两个都支持GPU训练,所以如果你有CUDA GPU,你也可以使用它。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注