随机森林中的超参数调整

Roo*_*123 5 python machine-learning random-forest scikit-learn grid-search

我在sklearn 的帮助下尝试在波士顿数据集上使用随机森林算法来预测房价。我尝试如下medvRandomForestRegressor3 iterations

迭代 1:使用具有默认超参数的模型

#1. import the class/model
from sklearn.ensemble import RandomForestRegressor
#2. Instantiate the estimator
RFReg = RandomForestRegressor(random_state = 1, n_jobs = -1) 
#3. Fit the model with data aka model training
RFReg.fit(X_train, y_train)

#4. Predict the response for a new observation
y_pred = RFReg.predict(X_test)


y_pred_train = RFReg.predict(X_train)
Run Code Online (Sandbox Code Playgroud)

迭代 1 的结果

{'RMSE Test': 2.9850839211419435, 'RMSE Train': 1.2291604936401441}
Run Code Online (Sandbox Code Playgroud)

迭代 2:我使用RandomizedSearchCV来获得超参数的最佳值

from sklearn.ensemble import RandomForestRegressor
RFReg = RandomForestRegressor(n_estimators = 500, random_state = 1, n_jobs = -1) 

param_grid = { 
    'max_features' : ["auto", "sqrt", "log2"],
    'min_samples_split' : np.linspace(0.1, 1.0, 10),
     'max_depth' : [x for x in range(1,20)]


from sklearn.model_selection import RandomizedSearchCV
CV_rfc = RandomizedSearchCV(estimator=RFReg, param_distributions =param_grid, n_jobs = -1, cv= 10, n_iter = 50)
CV_rfc.fit(X_train, y_train)
Run Code Online (Sandbox Code Playgroud)

所以我得到了最好的超参数如下

CV_rfc.best_params_
#{'min_samples_split': 0.1, 'max_features': 'auto', 'max_depth': 18}
CV_rfc.best_score_
#0.8021713812777814
Run Code Online (Sandbox Code Playgroud)

所以我训练了一个具有最佳超参数的新模型,如下所示

#1. import the class/model
from sklearn.ensemble import RandomForestRegressor
#2. Instantiate the estimator
RFReg = RandomForestRegressor(n_estimators = 500, random_state = 1, n_jobs = -1, min_samples_split = 0.1, max_features = 'auto', max_depth = 18) 
#3. Fit the model with data aka model training
RFReg.fit(X_train, y_train)

#4. Predict the response for a new observation
y_pred = RFReg.predict(X_test)


y_pred_train = RFReg.predict(X_train)
Run Code Online (Sandbox Code Playgroud)

迭代 2 的结果

{'RMSE Test': 3.2836794902147926, 'RMSE Train': 2.71230367772569}
Run Code Online (Sandbox Code Playgroud)

迭代 3:我使用GridSearchCV来获得超参数的最佳值

from sklearn.ensemble import RandomForestRegressor
RFReg = RandomForestRegressor(n_estimators = 500, random_state = 1, n_jobs = -1) 

param_grid = { 
    'max_features' : ["auto", "sqrt", "log2"],
    'min_samples_split' : np.linspace(0.1, 1.0, 10),
     'max_depth' : [x for x in range(1,20)]

}

from sklearn.model_selection import GridSearchCV
CV_rfc = GridSearchCV(estimator=RFReg, param_grid=param_grid, cv= 10, n_jobs = -1)
CV_rfc.fit(X_train, y_train)
Run Code Online (Sandbox Code Playgroud)

所以我得到了最好的超参数如下

CV_rfc.best_params_
#{'max_depth': 12, 'max_features': 'auto', 'min_samples_split': 0.1}
CV_rfc.best_score_
#0.8021820114800677
Run Code Online (Sandbox Code Playgroud)

迭代 3 的结果

{'RMSE Test': 3.283690568225705, 'RMSE Train': 2.712331014201783}
Run Code Online (Sandbox Code Playgroud)

我要评估的功能RMSE

def model_evaluate(y_train, y_test, y_pred, y_pred_train):
    metrics = {}
    #RMSE Test
    rmse_test = np.sqrt(mean_squared_error(y_test, y_pred))
    #RMSE Train
    rmse_train = np.sqrt(mean_squared_error(y_train, y_pred_train))

    metrics = {
              'RMSE Test': rmse_test,
              'RMSE Train': rmse_train}

    return metrics 
Run Code Online (Sandbox Code Playgroud)

所以在 3 次迭代后我有以下问题

  1. 为什么即使我使用和 ,调整模型的结果也比使用默认参数的模型最差。理想情况下,模型在通过交叉验证进行调整时应该给出良好的结果RandomSearchCVGridSearchCV
  2. 我知道交叉验证只会针对 中存在的值的组合进行param_grid。可能有一些值很好不包含在我的 中param_grid。那么遇到这种情况我该如何处理
  3. 我如何决定应该尝试什么范围max_features的值,min_samples_split或者max_depth机器学习模型中的任何超参数以提高其准确性。(这样我至少可以获得比默认超参数模型更好的调整模型) -参数)

hel*_*err 3

为什么即使我使用 RandomSearchCV 和 GridSearchCV,调整模型的结果也比默认参数的模型最差。理想情况下,模型在通过交叉验证进行调整时应该给出良好的结果

您的第二个问题有点回答您的第一个问题,但我尝试在波士顿数据集上重现您的结果,我使用{'test_rmse':3.987, 'train_rmse':1.442}默认参数获得了{'test_rmse':3.98, 'train_rmse':3.426}随机搜索和{'test_rmse':3.993, 'train_rmse':3.481}网格搜索的“调整”参数。然后我使用hyperopt以下参数空间

 {'max_depth': hp.choice('max_depth', range(1, 100)),
    'max_features': hp.choice('max_features', range(1, x_train.shape[1])),
    'min_samples_split': hp.uniform('min_samples_split', 0.1, 1)}
Run Code Online (Sandbox Code Playgroud)

大约 200 次运行后,结果如下所示: 在此输入图像描述'min_samples_split', 0.01, 1所以我扩大了获得最佳结果的 空间,{'test_rmse':3.278, 'train_rmse':1.716}使其min_samples_split等于 0.01。根据文档,在我们的例子中,公式为min_samples_split= 34,对于像这样的小数据集来说,这可能有点大。ceil(min_samples_split * n_samples)np.ceil(0.1 * len(x_train))

我知道交叉验证只会针对 param_grid 中存在的值的组合进行。可能有一些值很好,但未包含在我的 param_grid 中。那么遇到这种情况我该如何处理

我如何决定应该尝试 max_features、min_samples_split、max_depth 或机器学习模型中的任何超参数的值范围以提高其准确性。(这样我至少可以获得比模型更好的调整模型)默认超参数)

你无法提前知道这一点,所以你必须对每种算法进行研究,看看通常搜索什么样的参数空间(这方面的好来源是kaggle,例如google kaggle kernel random forest),合并它们,考虑你的数据集特征并优化使用某种贝叶斯优化算法(有多个现有的库)对它们进行优化,该算法尝试最佳地选择新的参数值。