随机森林调参

随机搜索:
首先,为随机森林回归器定义超参数的随机网格。
然后,您可以使用基于指定的随机网格搜索最佳超参数。RandomizedSearchCV
从随机搜索中提取最佳估计量 ()。best_random

随机搜索模型的评估:
在测试集上评估基本随机森林回归器 () 的性能。base_model
接下来,通过测试集上的随机搜索 () 评估最佳估计器的性能。best_random
网格搜索(第一轮):

您可以定义一个新的、更具体的参数网格 () 以进行进一步的超参数优化。param_grid
用于对指定的参数网格执行详尽搜索。GridSearchCV
从此网格搜索中提取最佳估计器 ()。best_grid
第一网格搜索模型的评估:

从测试集上的第一个网格搜索 () 中评估最佳估计器的性能。best_grid
网格搜索(第二轮):

为第二轮超参数优化定义另一个参数网格 ()。param_grid
您可以再次使用,以根据新参数网格搜索最佳超参数。GridSearchCV
从第二个网格搜索中提取最佳估计器 ()。best_grid_2
第二网格搜索模型的评估:

您可以在测试集上通过第二个网格搜索() 评估最佳估计器的性能。best_grid_2

其他网格搜索:

最后,使用其他超参数执行另一个网格搜索 ()。grid_search_ad
从此附加网格搜索中提取最佳估计器 ()。best_grid_ad
您可以在测试集上通过此附加网格搜索来评估最佳估计器的性能。
打印最终模型参数:

使用 打印最佳模型 () 的最后一组超参数。

import pandas as pd
features= pd.read_csv('data/temps_extended.csv')

独热处理处理数据

features = pd.get_dummies(features)

labels = features['actual']
features = features.drop('actual', axis = 1)

feature_list = list(features.columns)

import numpy as np

features = np.array(features)
labels = np.array(labels)

from sklearn.model_selection import train_test_split

train_features, test_features, train_labels, test_labels = train_test_split(features, labels,
                                                                            test_size = 0.25, random_state = 42)
# print('Training Features Shape:', train_features.shape)
# print('Training Labels Shape:', train_labels.shape)
# print('Testing Features Shape:', test_features.shape)
# print('Testing Labels Shape:', test_labels.shape)
#
# print('{:0.1f} years of data in the training set'.format(train_features.shape[0] / 365.))
# print('{:0.1f} years of data in the test set'.format(test_features.shape[0] / 365.))

选择那6个重要性比较高的特征

important_feature_names = ['temp_1', 'average', 'ws_1', 'temp_2', 'friend', 'year']

important_indices = [feature_list.index(feature) for feature in important_feature_names]

important_train_features = train_features[:, important_indices]
important_test_features = test_features[:, important_indices]

# print('Important train features shape:', important_train_features.shape)
# print('Important test features shape:', important_test_features.shape)

train_features = important_train_features[:]
test_features = important_test_features[:]

feature_list = important_feature_names[:]

不对,开始调节新的参数

from sklearn.ensemble import RandomForestRegressor

rf = RandomForestRegressor(random_state = 42)

from pprint import pprint

# 打印所有参数
pprint(rf.get_params())

RandomizedSearchCV(),这个函数可以帮助我们在候选集组合中,

不断的随机选择一组合适的参数来建模,并且求其交叉验证后的评估结果。

为什么要不断随机的选择呢?

按顺序一个个来不是更靠谱嘛,假设咱们有5个参数待定,

每个参数都有10种候选值,那一共有多少种可能性呢?这个数字就很大了吧,

由于建立模型所花的时间并不少,当数据量大的时候,

几小时能完成一次建模就已经不错了,所以我们很难遍历到所有的可能,

随机变成了一种策略,让我们大致能得到比较合适的参数组合,

该函数所需的所有参数解释都在API文档中有详细说明

from sklearn.model_selection import RandomizedSearchCV

# 建立树的个数
n_estimators = [int(x) for x in np.linspace(start = 200, stop = 2000, num = 10)]
# 最大特征的选择方式
max_features = ['sqrt']
# 树的最大深度
max_depth = [int(x) for x in np.linspace(10, 20, num = 2)]
max_depth.append(None)
# 节点最小分裂所需样本个数
min_samples_split = [2, 5, 10]
# 叶子节点最小样本数,任何分裂不能让其子节点样本数少于此值
min_samples_leaf = [1, 2, 4]
# 样本采样方法
bootstrap = [True, False]

# Random grid随机网格
random_grid = {'n_estimators': n_estimators,
               'max_features': max_features,
               'max_depth': max_depth,
               'min_samples_split': min_samples_split,
               'min_samples_leaf': min_samples_leaf,
               'bootstrap': bootstrap}

这里可以参考一些经验值或者不断通过实验结果来改变参数空间,

这是一个反复的过程,并不是说我们机器学习建模任务就是从前往后的进行,

有了实验结果之后,都需要再回过头来反复来对比不同参数,不同预处理方案的。

随机选择最适合的参数组合

rf = RandomForestRegressor()

rf_random = RandomizedSearchCV(estimator=rf, param_distributions=random_grid,
                              n_iter = 10, scoring='neg_mean_absolute_error',
                              cv = 3, verbose=2, random_state=42, n_jobs=-1)

# 执行寻找操作
rf_random.fit(train_features, train_labels)

RandomizedSearchCV中常用的参数

Estimator:RandomizedSearchCV这个方法是一个通用的,并不是专为随机森林设计的,所以我们需要指定选择的算法模型是什么。

Distributions:参数的候选空间,我们之间已经用字典格式给出了所需的参数分布。

n_iter:随机寻找参数组合的个数,比如在这里我们赋值了100代表接下来要随机找100组参数的组合,在其中找到最好的一个。

Scoring:评估方法,按照该方法去找到最好的参数组合

Cv:交叉验证,咱们之前已经唠过了。

Verbose:打印信息的数量,看自己的需求了。

random_state:随机种子,为了使得咱们的结果能够一致,排除掉随机成分的干扰,一般我们都会指定成一个值,用你自己的幸运数字就好。

n_jobs:多线程来跑这个程序,如果是-1就会用所有的,但是可能会有点卡。

即便我把n_jobs设置成了-1,

程序运行的还是很慢,因为我们建立100次模型来选择参数,

并且还是带有3折交叉验证的,那就相当于300个任务了

rf_random.best_params_

# 评估函数
def evaluate(model, test_features, test_labels):
    predictions = model.predict(test_features)
    errors = abs(predictions - test_labels)
    mape = 100 * np.mean(errors / test_labels)
    accuracy = 100 - mape

    print('平均气温误差.',np.mean(errors))
    print('Accuracy = {:0.2f}%.'.format(accuracy))

# 看看效果 与老模型对比
base_model=RandomForestRegressor(random_state=42)
base_model.fit(train_features,train_labels)
evaluate(base_model,test_features,test_labels)

# 新配方(最好的参数)
best_random=rf_random.best_estimator_
evaluate(best_random,test_features,test_labels)

GridSearchCV(),它的意思是进行网络搜索,说白了就是一个一个的遍历,

就像我们之前说的组合有多少种,就全部走一遍,其所需的参数都是类似的,

没记住的话赶紧先翻一遍API文档

#
from sklearn.model_selection import GridSearchCV

# 网络搜索
param_grid = {
    'bootstrap': [True],
    'max_depth': [8,10,12],
    'max_features': ['sqrt'],
    'min_samples_leaf': [2,3, 4, 5,6],
    'min_samples_split': [3, 5, 7],
    'n_estimators': [800, 900, 1000, 1200]
}

# 选择基本算法模型
rf = RandomForestRegressor()

# 网络搜索
grid_search = GridSearchCV(estimator = rf, param_grid = param_grid,
                           scoring = 'neg_mean_absolute_error', cv = 3,
                           n_jobs = -1, verbose = 2)


# 执行搜索
grid_search.fit(train_features,train_labels)


grid_search.best_params_
best_grid = grid_search.best_estimator_
evaluate(best_grid, test_features, test_labels)

另一组参赛选手 Grid Search

经过了再调整之后我们的算法模型效果又有了一点提升,

虽然只是一小点,但是把每一小步累计在一次就是一个大成绩了。

再用网络搜索的时候,遍历的次数太多,我们通常并不把所有的可能性都放进去,

而是分成不同的组来分别执行,下面我们再来看看另外一组网络搜索的参赛选手

param_grid = {
    'bootstrap': [True],
    'max_depth': [12, 15, None],
    'max_features': [3, 4],
    'min_samples_leaf': [5, 6, 7],
    'min_samples_split': [7,10,13],
    'n_estimators': [900, 1000, 1200]
}

# 选择算法模型
rf = RandomForestRegressor()

# 继续寻找
grid_search_ad = GridSearchCV(estimator = rf, param_grid = param_grid,
                           scoring = 'neg_mean_absolute_error', cv = 3,
                           n_jobs = -1, verbose = 2)

grid_search_ad.fit(train_features, train_labels)
grid_search_ad.best_params_
best_grid_ad = grid_search_ad.best_estimator_
evaluate(best_grid_ad, test_features, test_labels)

## 最终模型
print('最终模型参数:\n')
pprint(best_grid_ad.get_params())
最终模型参数:

{'bootstrap': True,
 'ccp_alpha': 0.0,
 'criterion': 'squared_error',
 'max_depth': None,
 'max_features': 4,
 'max_leaf_nodes': None,
 'max_samples': None,
 'min_impurity_decrease': 0.0,
 'min_samples_leaf': 7,
 'min_samples_split': 13,
 'min_weight_fraction_leaf': 0.0,
 'n_estimators': 900,
 'n_jobs': None,
 'oob_score': False,
 'random_state': None,
 'verbose': 0,
 'warm_start': False}

**# bootstrap:此参数确定在构建树时是否使用 bootstrap 示例。设置为True 时,它将启用引导。

ccp_alpha:最小成本复杂度修剪的非负浮点参数。它表示用于最小成本复杂度修剪的复杂性参数。

criterion:用于衡量拆分质量的函数。对于回归问题,通常使用“squared_error”。

max_depth:树的最大深度。如果设置为 ,则节点将展开,直到所有叶子都是纯的,或者直到所有叶子都包含少于样本。Nonemin_samples_split

max_features:寻找最佳拆分时要考虑的特征数量。在本例中,它设置为 4,表示在每次拆分时,算法都会考虑 4 个要素。

max_leaf_nodes:树中叶节点的最大数量。如果设置为None ,则没有最大限制。

max_samples:每个估计器中要引导的最大样本数。如果None ,则使用所有样本。

min_impurity_decrease:如果分裂导致杂质减少大于或等于该值,则节点将被分裂。

min_samples_leaf:叶节点上所需的最小样本数。

min_samples_split:拆分内部节点所需的最小样本数。

min_weight_fraction_leaf:位于叶节点所需的权重总和的最小加权分数。

n_estimators:森林中的树木数量。

n_jobs:要并行运行的作业数 fitpredict和 。如果设置为-1 ,它将使用所有处理器。

oob_score:是否使用袋外样本来估计看不见的数据的 R^2。

random_state:控制估计器的随机性。

verbose:控制拟合和预测时的详细程度。

warm_start:当设置为 时,它会重用上一次调用的解决方案来拟合,并向集成添加更多估计器。**

你可能感兴趣的:(随机森林,算法,机器学习)