随机森林中的超参数调整

时间:2018-11-29 17:58:51

标签: python machine-learning scikit-learn random-forest grid-search

在sklearn的Boston的帮助下,我尝试对RandomForestRegressor数据集进行随机森林算法来预测房价medv。我总共尝试了3 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)

迭代1的结果

{'RMSE Test': 2.9850839211419435, 'RMSE Train': 1.2291604936401441}

迭代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)

所以我得到了 best 超参数如下

CV_rfc.best_params_
#{'min_samples_split': 0.1, 'max_features': 'auto', 'max_depth': 18}
CV_rfc.best_score_
#0.8021713812777814

所以我用下面的 best 超参数训练了一个新模型

#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)

迭代2的结果

{'RMSE Test': 3.2836794902147926, 'RMSE Train': 2.71230367772569}

迭代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)

所以我得到了 best 超参数如下

CV_rfc.best_params_
#{'max_depth': 12, 'max_features': 'auto', 'min_samples_split': 0.1}
CV_rfc.best_score_
#0.8021820114800677

迭代3的结果

{'RMSE Test': 3.283690568225705, 'RMSE Train': 2.712331014201783}

我评估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 

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

  1. 即使我使用RandomSearchCV和GridSearchCV,为什么 tuned 模型的结果比具有默认参数的模型还要差。理想情况下,在通过交叉验证进行调整时,该模型应能给出良好的结果
  2. 我知道交叉验证仅会针对param_grid中存在的值的组合进行。可能有些值 good 但未包含在我的param_grid中。那么我该如何处理这种情况
  3. 如何确定应该为max_featuresmin_samples_splitmax_depth或机器中任何超参数尝试的值的范围学习模型以提高其准确性。(这样,我可以获得比带有默认超参数的模型更好的调整模型)

1 个答案:

答案 0 :(得分:2)

  

为什么调整后的模型的结果比默认模型的结果差   参数,即使我使用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)}

大约200次运行结果如下所示, enter image description here 因此我将空间扩大到'min_samples_split', 0.01, 1,使{'test_rmse':3.278, 'train_rmse':1.716}的最佳结果是min_samples_split等于0.01。根据文档,min_samples_split的公式为ceil(min_samples_split * n_samples),在我们的情况下,得出的np.ceil(0.1 * len(x_train)) = 34对于像这样的小型数据集来说可能很大。

  

我知道交叉验证仅适用于组合   存在于param_grid中的值。   但未包含在我的param_grid中。那么我该如何处理   情况

     

如何确定应尝试的值范围   max_features,min_samples_split,max_depth或就此而言   机器学习模型中的超参数以增加其   准确度。(这样我可以得到比   具有默认超参数的模型)

您可能无法事先知道,所以您必须对每种算法进行研究,以了解通常会搜索哪种类型的参数空间(对此很好的来源是kaggle,例如google kaggle kernel random forest),将其合并,请考虑您的数据集特征并使用某种Bayesian Optimization算法(为此使用multiple existing libraries)对其进行优化,该算法会尝试最佳选择新的参数值来选择。