随机森林Random Forest & Extra Tree 及实例
本篇介绍机器学习中常用的随机森林算法还有其常用的延申算法Extra Tree以及实例
参考:
- https://zhuanlan.zhihu.com/p/380323376
- https://zhuanlan.zhihu.com/p/57965634
- https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html
- https://www.kaggle.com/prashant111/random-forest-classifier-tutorial/notebook
一:随机森林算法概述
集成学习
集成学习(ensemble learning)通过构建并结合多个学习器来完成学习任务,有时也被称为多分类器系统(multi-classifier system)、基于委员会的学习(committee-based learning)等。
集成学习的一般结构:先产生一组“个体学习器”(individual learner),再用某种策略将它们结合起来,个体学习器通常由一个现有的学习算法从训练数据产生,例如C4.5决策树算法、BP神经网络算法等,此时集成中只包含同种类型的个体学习器,例如“决策树集成”中全是决策树,“神经网络集成”中全是神经网络,这样的集成是“同质”的(homogeneous).同质集成中的个体学习器亦称“基学习器”(base learner),相应的学习算法称为“基学习算法”(base learning algorithm).集成也可包含不同类型的个体学习器,例如同时包含决策树和神经网络,这样的集成是“异质”的(heterogenous).异质集成中的个体学习器由不同的学习算法生成,这时就不再有基学习算法;相应的,个体学习器一般称为“组件学习器”(component learner)或弱学习器、或直接称为个体学习器.
Bagging 和 Boosting
根据个体学习器的生成方式,目前的集成学习方法大致可分为两大类。即个体学习器问存在强依赖关系、必须串行生成的序列化方法。以及个体学习器间不存在强依赖关系、可同时生成的并行化方法。前者的代表是 Boosting,后者的代表是 Bagging。
Boosting
Boosting方法训练基分类器时采用串行的方式,各个基分类器之间有依赖。它的基本思路是将基分类器层层叠加,每一层在训练的时候,对前一层基分类器分错的样本,给予更高的权重。测试时,根据各层分类器的结果的加权得到最终结果。
Boosting的过程类似上图,我们学习新知识的过程往往是迭代式的,第一遍学习的时候,我们会记住一部分知识, 但往往也会犯一些错误,对于这些错误, 我们的印象会很深。第二遍学习的时候,就会针对犯过错误的知识加强学习, 以减少类似的错误发生。 不断循环往复, 直到犯错误的次数减少到很低的程度。
Bagging
Bagging是并行式集成学习方法最著名的代表。它直接基于自助采样法(bootstrap sampling)。给定包含m个样本的数据集,我们先随机取出一个样本放入采样集中,再把该样本放回初始数据集,使得下次采样时该样本仍有可能被选中,这样,经过m轮随机采样,我们得到m个样本的采样集。照这样,我们可以采样出T个含m个训练样本的采样集,然后基于每个采样集训练出一个基学习器,然后将这些基学习器进行结合。在对预测输出进行结合时,Bagging通常对分类任务使用简单投票法,对回归任务使用简单平均法,这就是Bagging的基本流程。
随机森林
随机森林是一个Bagging的过程, 随机森林是一种有监督的学习算法。它有两种变体:一种用于分类问题,另一种用于回归问题。 它是目前最灵活易用的算法之一。 它在给定的数据样本上创建决策树,从每棵树中获得预测,并通过投票的方式选择最佳方案。 它也是特性重要性的一个很好的指示器。
随机森林算法将多棵决策树组合在一起,形成了一个树的森林,因此得名随机森林。 在随机森林分类器中,森林中的树越多,准确率越高。
随机森林的算法步骤
通常有以下两步:
在第一阶段,我们从m个特征中随机选择“k”个特征并构建随机森林。 在第一阶段,我们按如下步骤进行:
- 从m个特征中随机选取k个k < m的特征。
- 在k个特征中,使用最佳分割点计算节点d。
- 使用最佳拆分将节点拆分为子节点。
- 重复1到3步,直到达到l个节点。
- 通过重复步骤1到4 n次来创建森林,创建n棵树。
在第二阶段,我们使用训练好的随机森林算法进行预测。
- 我们采用测试特征,并使用随机创建的每个决策树的规则来预测结果,并存储预测结果。
- 然后,我们计算每个预测目标的选票。
- 最后,我们将高投票的预测目标作为随机森林算法的最终预测。
随机森林的特征选择
随机森林算法可以用于特征选择过程。 该算法可用于对回归或分类问题中变量的重要性进行排序。
我们通过将随机森林算法与数据拟合来度量数据集中变量的重要性。 在拟合过程中,记录每个数据点的自袋误差,并在森林中取平均值。
训练后测量第j个特征的重要性。 第j个特征的值在训练数据之间进行排列,并在这个扰动数据集上再次计算out- bag误差。 第j个特征的重要性分数是通过平均所有树的排列前后的out- bag误差的差来计算的。 分数由这些差异的标准差标准化。对于这个分数,产生大值的特征比产生小值的特征更重要。 根据这个分数,我们将选择最重要的特征,并删除最不重要的特征进行模型构建。
Extra Tree
extra trees是RF的一个变种, 原理几乎和RF一模一样,仅有区别有:
①对于每个决策树的训练集,RF采用的是随机采样bootstrap来选择采样集作为每个决策树的训练集,而extra trees一般不采用随机采样,即每个决策树采用原始训练集。
②在选定了划分特征后,RF的决策树会基于基尼系数,均方差之类的原则,选择一个最优的特征值划分点,这和传统的决策树相同。但是extra trees比较的激进,他会随机的选择一个特征值来划分决策树。
从第二点可以看出,由于随机选择了特征值的划分点位,而不是最优点位,这样会导致生成的决策树的规模一般会大于RF所生成的决策树。也就是说,模型的方差相对于RF进一步减少,但是偏倚相对于RF进一步增大。在某些时候,extra trees的泛化能力比RF更好。
二:实践
用随机森林实现分类
本文这里用例和上一篇博客中数据
根据车辆的其它特征来分类其acc的属性
导入相关库:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
预处理:
# 数据split:
X = df.drop(['class'], axis=1)
y = df['class']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42)
# 数据编码:
encoder = ce.OrdinalEncoder(cols=['buying', 'maint', 'doors', 'persons', 'lug_boot', 'safety'])
X_train = encoder.fit_transform(X_train)
X_test = encoder.transform(X_test)
滚动estimators值,预测:
其中,estimators的值就是树的个数
pipe = RandomForestClassifier(n_estimators=0, max_samples=0.1, n_jobs=-1, random_state=1, max_depth=3)
n_estimators = 1
initialized = False
while n_estimators < 256:
n_estimators *= 4
pipe.set_params(n_estimators=n_estimators, warm_start=initialized)
pipe.fit(X_train, y_train)
initialized = True
y_pre = pipe.predict(X_test)
score = accuracy_score(y_test, y_pre)
print(f'Estimators = {n_estimators}, score = {score * 100}%')
output:
Estimators = 4, score = 72.83236994219652%
Estimators = 16, score = 70.52023121387283%
Estimators = 64, score = 70.52023121387283%
Estimators = 256, score = 71.67630057803468%
一些优化:
随机森林模型可以查到特征的重要度,选择重要度最高的2个特征作输入重新训练
feature_scores = pd.Series(pipe.feature_importances_, index=X_train.columns).sort_values(ascending=False)
print(feature_scores)
sns.barplot(x=feature_scores, y=feature_scores.index)
plt.show()
X = df[['persons', 'safety']]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2, random_state = 42)
pipe = RandomForestClassifier(n_estimators=128, max_samples=0.1, n_jobs=-1, random_state=1, max_depth=3)
pipe.fit(X_train, y_train)
y_pre = pipe.predict(X_test)
score = accuracy_score(y_test, y_pre)
print(f'Estimators = {n_estimators}, score = {score * 100}%')
ExtraTreeClassifier
ExtraTree分类器代码上差不多,由于选择的是全部样本。没有max_samples
这个参数
pipe = ExtraTreesClassifier(n_estimators=0, n_jobs=-1, random_state=1, max_depth=3)
n_estimators = 1
initialized = False
while n_estimators < 256:
n_estimators *= 4
pipe.set_params(n_estimators=n_estimators, warm_start=initialized)
pipe.fit(X_train, y_train)
initialized = True
y_pre = pipe.predict(X_test)
score = accuracy_score(y_test, y_pre)
print(f'Estimators = {n_estimators}, score = {score * 100}%')
Output:
Estimators = 4, score = 71.38728323699422%
Estimators = 16, score = 67.91907514450867%
Estimators = 64, score = 67.91907514450867%
Estimators = 256, score = 67.91907514450867%
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?