使用 RandomizedSearchCV 在 sklearn 中调整超参数需要花费大量时间

hyperparameter tuning in sklearn using RandomizedSearchCV taking lot of time

我正在处理一个包含 13 个特征和 550068 行的数据集。我做了 k-fold cross 验证并选择 k 值为 10,然后选择了具有最小均方根误差的最佳模型,在我的例子中模型是梯度 boos挺回归。然后我做了超参数调整这是我的代码:

from sklearn.ensemble GradientBoostingRegressor
gradientboost = GradientBoostingRegressor(n_estimators = 300)
from sklearn.model_selection import RandomizedSearchCV
loss = ['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 search
hyperparameter_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 validation
random_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)

它花了很多时间来调整超参数它 almost 花了 48 小时但还没有 completed.I 尝试了不同的 n_jobs 和 n_iters 和 cv 值但这个过程并没有加快。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']

但它不起作用。单个部分也需要很多时间。我正在使用 windows10 os 和处理器 intel i5 7th generation.can 任何人都可以帮助我解决这个问题。提前致谢。

这是几件事的结合:

  • 有一百万个样本,
  • 使用梯度提升和大量集成,
  • 通常有一个很大的搜索网格
  • 进行 10 次 k 验证。

在本地机器上训练这样的东西不会让你走得太远。如果您不是在训练生产级模型(更像是一个副业或大学项目),请尝试以下操作:

  • 使您的样本更小(比如 10k 个样本),
  • 尝试深入了解每个超参数的作用以及梯度提升的工作原理。例如,在您的网格中,您使用的损失函数不会产生如此巨大的差异,而您却遗漏了一个非常重要的参数 'learning_rate'。 'max_features' - 'auto' 和 'none' 本质上做同样的事情,尝试在那里试验一些浮点数是个好主意。
  • 调少参数。目前,您正在从 3 * 5 * 5 * 5 * 4 * 4 = 6000 种可能的组合中抽取 50 种。您可以从较小的网格(比如 100/200 种可能的组合)开始,对较少的组合进行采样,查看哪些参数产生最大变化,然后尝试微调它们,一次耦合,但不是一次全部。最昂贵的参数是 'n_estimators',因为它将 'n_estimators' 树放在一起形成一个完整的模型。首先找到大约数量的处于 'bias/variance' 权衡边缘的估计器,然后将其放入网格将是一个好的开始。
  • 将 k 的数量减少到 8 甚至 5,这应该会立即大大减少 运行 时间。

如果你正在为生产规模做这件事并且想使用整个数据集,你需要获得一些额外强大的计算资源,例如虚拟机and/or使用不同的包来训练梯度提升树,例如 xgboost or LightGBM。两者都应该支持 GPU 训练,所以如果你有 CUDA GPU,你也可以使用它。

查看您的参数网格,您可以更改一些内容,这些内容会立即减少 运行 时间,而不会牺牲太多:

  1. verbose =5。请删除它,因为这需要大量时间。它所做的只是打印每棵树的性能。你真的需要所有这些视觉干扰吗?
  2. return_train_score = True。你真的需要保留训练分数吗?可能不会。您可以将其删除以节省时间。
  3. huber loss 比 ls 花费的时间长很多,因为它是 lslad 的组合。如果您的数据没有不合理的异常值,请使用默认损失。如果一定要用huber loss,那就先在小样本上试试。

顺便说一句,在 sklearn GradientBoostingRegressor 中, max_features = 'auto'None 意思相同。