决策树、随机森林、极端随机树(ERT)

声明:本文仅为个人学习记录所用,参考较多,如有侵权,联系删除

决策树

通俗来说,决策树分类的思想类似于找对象。现想象一个女孩的母亲要给这个女孩介绍男朋友,于是有了下面的对话:

  女儿:多大年纪了?

  母亲:26。

  女儿:长的帅不帅?

  母亲:挺帅的。

  女儿:收入高不?

  母亲:不算很高,中等情况。

  女儿:是公务员不?

  母亲:是,在税务局上班呢。

  女儿:那好,我去见见。

  这个女孩的决策过程就是典型的分类树决策。相当于通过年龄、长相、收入和是否公务员对将男人分为两个类别:见和不见。假设这个女孩对男人的要求是:30岁以下、长相中等以上并且是高收入者或中等以上收入的公务员,下图表示了女孩的决策逻辑。

在这里插入图片描述
如果你作为一个女生,你会优先考虑哪个条件:长相?收入?还是年龄。在考虑年龄条件时使用25岁为划分点,还是35岁为划分点。有这么多条件,用哪个条件特征先做if,哪个条件特征后做if比较优呢?还有怎么确定用特征中的哪个数值作为划分的标准。这就是决策树机器学习算法的关键了。

集成学习

假设我们现在提出了一个复杂的问题,并抛给几千个随机的人,然后汇总他们的回答。在很多情况下,我们可以看到这种汇总后的答案会比一个专家的答案要更好。这个称为“群众的智慧”。同理,如果我们汇总一组的预测器(例如分类器与回归器)的预测结果,我们可以经常获取到比最优的单个预测器要更好的预测结果。这一组预测器称为一个集成,所以这种技术称为集成学习,一个集成学习算法称为一个集成方法。

随机森林

假如训练一组决策树分类器,每个都在训练集的一组不同的随机子集上进行训练。在做决策时,我们可以获取所有单个决策树的预测结果,然后根据各个结果对每个类别的投票数,最多票的类别获胜。这种集成决策树称为随机森林。尽管它非常简单,不过它是当前最强大的机器学习算法之一。

一个树和1000个树

假如有一个弱学习者(weak learner,也就是说它的预测能力仅比随机猜稍微高一点),分类正确的概率是51%。本来不应该考虑这种弱分类器(分类能力强的还有很多种方法),但是,假如我们考虑把1000个这样的树放在一起(一个集合),预测结果如何呢?
·每个决策树都使用所有数据作为训练集
·节点的选择是通过在所有特征中进行搜索选出最好的划分方式得到的
·每个决策树的最大深度都是1

import pandas as pd
import numpy as np

# 导入鸢尾花数据集
from sklearn.datasets import load_iris

# 从样本中随机按比例选取训练集和测试集
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import BaggingClassifier
# To measure performance
from sklearn import metrics
# 该数据集一共包含4个特征变量,1个类别变量。共有150个样本。
iris = load_iris()
X = pd.DataFrame(iris.data[:, :], columns = iris.feature_names[:])
# print(X)
y = pd.DataFrame(iris.target, columns =["Species"])

# 划分数据集
# 随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。
# 随便填一个大于0的数据就能保证,其他参数一样的情况下得到的随机数组是一样的。但填0或不填,每次都会不一样。
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 20, random_state = 100)

# 定义决策树
stump = DecisionTreeClassifier(max_depth = 1)

# bagging集成方法
ensemble = BaggingClassifier(estimator = stump, n_estimators = 1000,
                             bootstrap = False)

# 训练分类器
stump.fit(X_train, np.ravel(y_train))
ensemble.fit(X_train, np.ravel(y_train))

# 预测
y_pred_stump = stump.predict(X_test)
y_pred_ensemble = ensemble.predict(X_test)

# 决策表现
stump_accuracy = metrics.accuracy_score(y_test, y_pred_stump)
ensemble_accuracy = metrics.accuracy_score(y_test, y_pred_ensemble)

print(f"The accuracy of the stump is {stump_accuracy*100:.1f} %")
print(f"The accuracy of the ensemble is {ensemble_accuracy*100:.1f} %")

在这里插入图片描述
可以看到无论是一棵树还是1000棵树,预测准确率都一样。

随机森林-RandomForest

上面1000棵树虽然构成了一片森林,但是每棵树都一样,相当于你问一只兔子爱吃青菜还是爱吃肉,问1000遍,结果都是一样的,这不叫群众的智慧!
如果我们:
·每个决策树都使用随机采样得到的子集作为训练集,采样方式为bootstrap(一种有放回抽样)
·节点的选择是通过在子集中随机选择特征(不是所有特征)中进行搜索选出最好的划分方式得到的
·每个决策树的最大深度都是1

# max_features:寻找最佳切分时考虑的最大特征数,默认是所有特征都用
# splitter:用于在每个节点上选择拆分的策略。可选“best”, “random”,默认“best”。
stump = DecisionTreeClassifier(max_depth = 1, splitter = "best", max_features = "sqrt")

# 随机森林
# n_estimators基分类器的个数
ensemble = BaggingClassifier(estimator = stump, n_estimators = 1000,
                             bootstrap = True)
stump.fit(X_train, np.ravel(y_train))
ensemble.fit(X_train, np.ravel(y_train))

y_pred_tree = stump.predict(X_test)
y_pred_ensemble = ensemble.predict(X_test)

stump_accuracy = metrics.accuracy_score(y_test, y_pred_stump)
ensemble_accuracy = metrics.accuracy_score(y_test, y_pred_ensemble)

print(f"The accuracy of the stump is {stump_accuracy*100:.1f} %")
print(f"The accuracy of the Random Forest is {ensemble_accuracy*100:.1f} %")

![在这里插入图片描述](https://img-blog.csdnimg.cn/9bb47d0e22304e53ab852cbacdeecc3d.png
群众的智慧这不就体现出来了吗!
在不同的训练集随机子集上进行训练(也就是将训练集上的数据随机抽样为若干个子集,然后用这些不同子集在同一种模型上训练,这样就形成了不一样的预测器)

极度随机树-Extremely randomized trees,Extra tree

在选定了划分特征后,RF的决策树会基于信息增益,基尼系数,均方差之类的原则,选择一个最优的特征值划分点,这和传统的决策树相同。但是Extra tree比较的激进,会随机的选择一个特征值来划分决策树。
由于随机选择了特征值的划分点位,而不是最优点位,这样会导致生成的决策树的规模一般会大于RF所生成的决策树。也就是说,模型的方差相对于RF进一步减少,但是bias相对于RF进一步增大。在某些时候,Extra tree的泛化能力比RF更好.
在这里插入图片描述

stump = DecisionTreeClassifier(max_depth=1, splitter="random", max_features="sqrt")
ensemble = BaggingClassifier(estimator=stump, n_estimators=1000, bootstrap=False)

stump.fit(X_train, np.ravel(y_train))
ensemble.fit(X_train, np.ravel(y_train))

y_pred_tree = stump.predict(X_test)
y_pred_ensemble = ensemble.predict(X_test)

stump_accuracy = metrics.accuracy_score(y_test, y_pred_stump)
ensemble_accuracy = metrics.accuracy_score(y_test, y_pred_ensemble)

print(f"The accuracy of the stump is {stump_accuracy * 100:.1f} %")
print(f"The accuracy of the Extra Trees is {ensemble_accuracy * 100:.1f} %")

在这里插入图片描述

补充 hard voting soft voting

在这里插入图片描述

补充 Bootstrap

Bootstrap又称自展法、自举法、自助法、靴带法 , 是统计学习中一种重采样(Resampling)技术,用来估计标准误差、置信区间和偏差
子样本之于样本,可以类比样本之于总体
举例
栗子:我要统计鱼塘里面的鱼的条数,怎么统计呢?
假设鱼塘总共有鱼N,不知道N是多少条
步骤:
承包鱼塘,不让别人捞鱼(规定总体分布不变)。
自己捞鱼,捞100条,都打上标签(构造样本)
把鱼放回鱼塘,休息一晚(使之混入整个鱼群,确保之后抽样随机)
开始捞鱼,每次捞100条,数一下,自己昨天标记的鱼有多少条,占比多少(一次重采样取分布)。
然后把这100条又放回去
重复3,4步骤n次。建立分布。
(原理是中心极限定理)

假设一下,第一次重新捕鱼100条,发现里面有标记的鱼12条,记下为12%,
放回去,再捕鱼100条,发现标记的为9条,记下9%,
重复重复好多次之后,假设取置信区间95%,
你会发现,每次捕鱼平均在10条左右有标记,

它怎么来的呢?
10/N=10%

所以,我们可以大致推测出鱼塘有1000条左右。

其实是一个很简单的类似于一个比例问题。这也是因为提出者Efron给统计学顶级期刊投稿的时候被拒绝的理由–“太简单”。这也就解释了,为什么在小样本的时候,bootstrap效果较好,

你这样想,如果我想统计大海里有多少鱼,你标记100000条也没用啊,因为实际数量太过庞大,
你取的样本相比于太过渺小,最实际的就是,你下次再捕100000的时候,发现一条都没有标记,就尴尬了。。。

参考文献

[1] 决策树(Decision Tree)
[2] 集成学习与随机森林(一)投票分类器
[3] Hard Voting 与 Soft Voting 的对比
[4] 统计学中的Bootstrap方法(Bootstrap抽样)用来训练bagging算法,如果随机森林Random Forests
[5] An Intuitive Explanation of Random Forest and Extra Trees Classifiers

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 随机搜索(Random Tree Search)是一种用于搜索问题的算法。在MATLAB中,可以使用以下代码实现随机搜索: ```MATLAB function [path, cost] = randomTreeSearch(startNode, goalNode, nodes, edges) % 初始化根节点 rootNode = startNode; % 初始化路径和代价 path = [rootNode]; cost = 0; while true % 随机选择一个节点作为当前节点 currentNode = nodes(randi(length(nodes))); % 生成当前节点到目标节点的路径 [currentPath, currentCost] = dijkstraSearch(currentNode, goalNode, nodes, edges); % 如果找到了一条更短的路径,则更新路径和代价 if currentCost < cost path = currentPath; cost = currentCost; end % 如果当前节点是目标节点,跳出循环 if currentNode == goalNode break; end end end function [path, cost] = dijkstraSearch(startNode, goalNode, nodes, edges) % 初始化优先队列和访问数组 priorityQueue = PriorityQueue(); visited = false(size(nodes)); % 将起始节点加入优先队列 priorityQueue.push(startNode, 0); % 初始化路径和代价 path = []; cost = Inf; while ~priorityQueue.isEmpty() % 从优先队列中取出一个节点 [currentNode, currentCost] = priorityQueue.pop(); % 如果当前节点已被访问过,则继续下一次循环 if visited(currentNode) continue; end % 更新当前节点的路径和代价信息 path(currentNode) = currentNode; cost(currentNode) = currentCost; % 如果当前节点是目标节点,跳出循环 if currentNode == goalNode break; end % 标记当前节点为已访问 visited(currentNode) = true; % 获取当前节点的邻居节点 neighbors = edges(currentNode, :); % 遍历邻居节点 for i = 1:length(neighbors) neighbor = neighbors(i); % 如果邻居节点未访问,则加入优先队列 if ~visited(neighbor) priorityQueue.push(neighbor, currentCost + edges(currentNode, neighbor)); end end end % 根据路径信息生成最短路径 if isinf(cost) path = []; else path = getPath(startNode, goalNode); end end ``` 这段代码实现了一个简单的随机搜索算法。它通过不断随机选择一个节点,然后使用Dijkstra算法找到当前随机节点到目标节点的最短路径。如果找到了一条更短的路径,则更新路径和代价。一直重复这个过程,直到当前节点为目标节点时停止搜索。最后,返回找到的最短路径和代价。 ### 回答2: 随机搜索是一种用于求解最优路径问题的算法,其基本思想是通过建立一棵随机来代表可能的路径集合,并在搜索过程中动态地扩展的分支,直到找到最优路径。下面是一个基于Matlab的随机搜索代码示例: 1. 初始化工作: - 定义搜索区域:确定地图的边界、障碍物等; - 定义起始点和终点; - 定义的根节点,将起始点作为根节点。 2. 迭代搜索过程: - while循环直到找到最优路径或达到最大迭代次数: - 生成一个随机点(随机采样); - 在中搜索与该点最近的节点; - 以该点为终点,绘制从最近的节点到该点的一条路径; - 判断该路径是否与障碍物相交; - 若路径合法,将该点作为新节点插入中,并更新路径的代价; - 判断新节点是否接近目标点,若是则停止搜索。 3. 输出结果: - 若在最大迭代次数内找到最优路径,则输出最优路径; - 若超过最大迭代次数仍未找到最优路径,则输出近似最优路径。 随机搜索算法能够在高维空间中搜索和规划最优路径,并且适用于不规则的地形或含有障碍物的环境。通过随机搜索算法,可以实现机器人的路径规划、无人机的航迹规划等应用。 ### 回答3: 随机搜索(Random Tree Search)是一种基于随机抽样的搜索方法,通常应用于解决优化问题。下面是一个使用Matlab编写的随机搜索代码的简要描述。 首先,我们需要定义问题的目标函数。假设我们要优化的问题是求解函数f(x),其中x是优化变量。我们需要将目标函数f(x)定义为一个Matlab函数。 接下来,我们需要确定搜索的范围。假设x的取值范围是[low, high],并且我们要进行N次搜索。 然后,我们开始进行随机搜索。我们首先初始化一个空的搜索结果集合,用来存储每次搜索的结果。然后,我们进行N次的搜索迭代。 在每次搜索迭代中,我们需要进行以下步骤: 1. 随机生成一个新的搜索点x_new,其中x_new的取值范围是[low, high]。 2. 计算目标函数f(x_new)的值。 3. 将搜索点x_new和其对应的目标函数值保存到搜索结果集合中。 4. 如果已经达到了指定的搜索迭代次数N,则停止搜索。 5. 否则,继续进行下一次搜索迭代。 搜索完成后,我们可以从搜索结果集合中选择具有最小目标函数值的搜索点作为最优解。 通过上述步骤,我们可以实现一个简单的随机搜索算法的Matlab代码。注意,这只是随机搜索的一个简单实现,实际应用中可能需要根据具体问题进行一些调整和改进。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值