0/前言
单棵决策树不是集成学习,多棵决策树共同起作用才是集成学习ensemble learning。
根据决策树之间是否有依赖,可以把集成学习分成bagging思想和boosting思想。
随机森林,各个决策树之间是独立的,互相没有依赖,所以说是bagging思想。
xgb,各个决策树之间是有依赖的,所以是boosting思想。
随机森林 = 集成学习 + bagging思想 + 决策树
所以,对随机森林调参数,可以从3个方面进行。
框架层面的调参 + 决策树本身层面的调参 + 任务执行性能
1/sklearn扩展包的ensemble的RandomForestClassifier类(分类任务)
本文以随机森林解决分类问题,来调整参数。
class sklearn.ensemble.RandomForestClassifier(
n_estimators=10,
criterion='gini',
max_depth=None,
min_samples_split=2,
min_samples_leaf=2,
min_weight_fraction_leaf=0.0,
max_features=’auto’,
max_leaf_nodes=None,
min_impurity_decrease=0.0,
min_impurity_split=None,
bootstrap=True,
oob_score=False,
n_jobs=1,
random_state=None,
verbose=0,
warm_start=False,
class_weight=None
)
2/参数介绍
<1>n_estimators
官方解释如下:
integer, optional (default=10) The number of trees in the forest.
整数,可选择(默认值为10),随机森林里决策树的数量。
简单来说:就是你打算用多少棵树来投票。
该参数大,会提升模型的性能,更佳稳定,方差减小了。因为决策树多了,相当于参与决策的‘专家’多了,这样出错的概率就会变小
但是如果决策树太多,也会增加计算量,模型的复杂度对增加。
有利有弊,但是相比来说,还是大一点好。
n_estimators是森林里树的数量,通常数量越大,效果越好,但是计算时间也会随之增加。
此外要注意,当树的数量超过一个临界值之后,算法的效果并不会很显著地变好
<2>criterion
string, optional (default=”gini”) 字符串,可选择
衡量特征分裂质量的性能。
受支持的标准是基尼不纯度的"gini"和信息增益的"entropy"(熵)。
注意:这个参数是特定树的。
<3>max_features
随机森林的特征随机选择指的是:每个节点在分裂的时候在所有特征中进行选择,而不是对于整棵决策树进行特征的随机选择。
int, float, string or None, optional (default=”auto”)
整数,浮点数,字符串或者无值,可选的(默认值为"auto")
寻找最佳分割时需要考虑的特征数目:
如果是int,就要考虑每一次分割处的max_feature特征
如果是float,那么max_features就是一个百分比,那么(max_feature*n_features)特征整数值是在每个分割处考虑的。
如果是auto,那么max_features=sqrt(n_features),即n_features的平方根值。
如果是log2,那么max_features=log2(n_features)
如果是None,那么max_features=n_features
注意:寻找分割点不会停止,直到找到最少一个有效的节点划分区,即使它需要有效检查超过max_features的特征。
max_features是分割节点时考虑的特征的随机子集的大小。 这个值越低,方差减小得越多,但是偏差的增大也越多
回归:max_features = n_features
分类:max_features = sqrt(n_features)
<4>max_depth
integer or None, optional (default=None) 整数或者无值,可选的(默认为None)
树的最大深度。如果值为None,那么会扩展节点,直到所有的叶子是纯净的,或者直到所有叶子包含少于min_sample_split的样本。
<5>min_sample_leaf
每个叶子节点中容纳的最小的样本数量。
如果您以前编写过一个决策树,你能体会到最小叶子节点样本数的重要性。
叶子节点是决策树的末端节点。
较小的叶子使模型更容易捕捉训练数据中的噪声。
一般来说,我更偏向于将最小叶子节点数目设置为大于50。
在你自己的情况中,你应该尽量尝试多种叶子大小种类,以找到最优的那个。
<6>min_sample_split
分割节点所需的最小样本数(该参数不是很重要)
如果我们设置了min_sample_split = 6,
这个时候,某个节点中有4个样本,则不会再对该节点进行划分。
min_sample_leaf基本上是叶节点所需的最小样本数
假设min_sample_leaf = 3,并且一个含有5个样本的节点可以分别分裂成2个和3个大小的叶子节点,那么这个分裂就不会发生,因为最小的叶子大小为3。
<7>min_sample_leaf和min_sample_split这2个参数,具有一定的联动性
<8>class_weight
如果我们给出的训练数据中,正负样本严重不均衡,则可以通过该参数调整正负样本的权重
权重大的样本,在进行随机子采样的时候,被选中的概率就大。
在随机森林(Random Forest)中,`class_weight` 参数用于处理数据集中类别不平衡的问题。
当某个类别的样本数量远多于其他类别时,模型可能会偏向于这个多数类别,导致对少数类别的预测性能不佳。
通过为不同的类别分配不同的权重,`class_weight` 参数可以帮助模型更公平地对待各个类别。
在 scikit-learn(Python 中最常用的机器学习库之一)中,
`RandomForestClassifier` 类提供了 `class_weight` 参数。
这个参数可以取几种不同的值:
1. `None`(默认值):不对类别进行加权,即所有类别的权重都是 1。
1. `'balanced'` :自动调整权重,使得每个类别的权重与其在数据集中出现的频率成反比。这通常用于解决类别不平衡问题。例如,如果一个类别的样本数量是另一个类别的两倍,那么该类别将具有 0.5 的权重,而另一个类别将具有 1.0 的权重。
1. 字典(dict):可以手动指定每个类别的权重。字典的键是类别的标签(整数或字符串),值是相应的权重(浮点数)。这允许用户根据具体需求自定义权重。
demo1:
假设你有一个二分类问题,类别 0 的样本数量远多于类别 1。你可以这样设置 `class_weight`:
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier(class_weight='balanced')
demo2:
手动指定权重
假设类别 0 的标签为 0,类别 1 的标签为 1,你可以这样设置:
class_weights = {0: 1.0, 1: 2.0}
clf = RandomForestClassifier(class_weight=class_weights)
注意,选择适当的权重取决于你的具体数据和需求。有时,使用 `'balanced'` 选项可能是一个好的起点,但根据问题的复杂性,手动调整权重可能会获得更好的结果。
此外,处理类别不平衡问题的另一种方法是使用数据重采样技术,如过采样(增加少数类别的样本数量)或欠采样(减少多数类别的样本数量),这些技术可以在训练模型之前应用于数据集。然而,`class_weight` 参数提供了一种无需修改数据本身的简单而强大的解决方案。
<9>n_jobs
这个参数告诉服务器用多少处理器cpu来训练模型。
因为随机森林中的决策树之间是独立的,各自训练自己的。
所以可以并行训练,可以多开几个进程。
“-1”意味着没有限制,
而“1”值意味着它只能使用一个处理器。
下面是一个用Python做的简单实验用来检查这个指标:
“%timeit”是一个非常好的功能,他能够运行函数多次并给出了最快循环的运行时间。
这出来非常方便,同时将一个特殊的函数从原型扩展到最终数据集中。
%timeit
model = RandomForestRegressor(n_estimator = 100, oob_score = TRUE,n_jobs = 1,random_state =1)
model.fit(X,y)
Output ———- 1 loop best of 3 : 1.7 sec per loop
%timeit
model = RandomForestRegressor(n_estimator = 100,oob_score = TRUE,n_jobs = -1,random_state =1)
model.fit(X,y)
Output ———- 1 loop best of 3 : 1.1 sec per loop
<10>random_state
该参数,确定一个数值,可以让每一次选择出来的数据都是一样的。
此参数让结果容易复现。
一个确定的随机值将会产生相同的结果,在参数和训练数据不变的情况下。
我曾亲自尝试过将不同的随机状态的最优参数模型集成,有时候这种方法比单独的随机状态更好。
确定该参数,则每棵决策树随机选择的样本数据和随机选择的特征数据都是固定的,
这样我们每次训练的时候去调整其他的参数就可以了。
<11>oob_score
out of bag, 袋外样本
out of bag score
这是一个随机森林交叉验证方法。
这种方法只是简单的标记在每棵子树中用的样本数据。
然后对每一个样本数据找出一个最大投票得分,是由那些没有使用该观察样本进行训练的决策树投票得到。
例子:
model = RandomForestRegressor(n_estimator=100,
oob_score=TRUE,
n_jobs=-1,
random_state=50,
max_features="auto",
min_samples_leaf=50)
model.fit(x,y)
在随机森林中,oob_score参数是用于评估模型的泛化能力。
oob是Out of Bag(袋外)的缩写,表示在随机森林训练过程中,未被选中的样本。
由于随机森林采用有放回的抽样方式构建每个决策树,因此会有部分样本未被选中,这部分样本被称为袋外样本。
oob_score参数利用袋外样本来评估随机森林的性能。
具体来说,对于每个决策树,使用袋外样本进行预测,并计算预测结果的准确率或误差。
然后将所有决策树的oob_score进行平均,得到整个随机森林的oob_score。这个指标可以用来评估模型的泛化能力,即模型在未见过的数据上的表现。
需要注意的是,oob_score是一个无偏估计,它不需要额外的验证数据集来评估模型性能,因此可以节省计算资源和时间。
同时,oob_score也可以作为模型选择的一个依据,帮助我们选择性能更好的模型。