机器学习 (四) 基于Python实现的随机森林详解

Python机器学习笔记——随机森林算法 随机森林算法的理论知识   随机森林是一种有监督学习算法,是以决策树为基学习器的集成学习算法。随机森林非常简单,易于实现,计算开销也很小,但是它在分类和回归上表现出非常惊人的性能,因此,随机森林被誉为“代表集成学习技术水平的方法”。 一,随机森林的随机性体现在哪几个方面? 1,数据集的随机选取   从原始的数据集中采取有放回的抽样(bagging),构造子数据集,子数据集的数据量是和原始数... 阅读详情
1.概述

随机森林 Random Forest 是一种强大的机器学习模型,得益于各种强大的库,现在我们可以很轻松地调用它,但并不是每一个会使用该模型的人都理解它真正的实现方式,本文将用 Python 实现并解释了决策树和随机森林的工作过程。

比如Scikit-Learn,让我们现在可以非常轻松地使用 Python 实现任何机器学习算法。

2.随机森林简介

随机森林,是用随机的方式建立一个森林,森林里面有很多的决策树组成,随机森林的每一棵决策树之间是没有关联的,随机森林背后的思想,是与群体智慧,甚至“看不见的手”相互映照。

决策树(decision tree)是一个树形结构。其中每个非叶节点表示一个特征属性上的判断,每个分支代表这个特征属性在某个判断上的输出,而每个叶节点对应的是一个类别。使用决策树进行决策的过程就是从根节点开始,对待分类相应的特征属性进行判断,并按照其值选择输出分支,直到到达叶子节点,将叶子节点存放的类别作为最后的决策结果。

3.单个决策树

这里先从一个简单的二元分类任务开始:

我们的数据仅有两个特征(x1, x2),这里共有 6 个数据点,2 种不同的 lable标签。

可以看出我们不能在这些数据之间用一条直线将各个点划分到对应的类别,也就是说不是线性可分的。但是,我们可以画出一系列直线来分开这两个类别,这实际上就是在构建决策树的做法。

在这里,我们使用Scikit-Learn快速构建和训练数据的单个决策树:

from sklearn.tree import DecisionTreeClassifier
# Set random seed to ensure reproducible runs
RSEED = 50
# Make a decision tree and train
tree = DecisionTreeClassifier(random_state=RSEED)
tree.fit(X, y) #训练模型
#输出决策树的结构
print(f'Decision tree has {tree.tree_.node_count} nodes with maximum depth {tree.tree_.max_depth}.')
# Decision tree has 9 nodes with maximum depth 3.
#输出准确度
print(f'Model Accuracy: {tree.score(X, y)}')
#Model Accuracy: 1.0

这里的决策树使用 Scikit-Learn 默认的超参数,但是它也可以根据需要增加决策树的个数,以便完全分离类。这样会导致过度拟合,因为该模型过度耦合训练数据,一般在实践中,我们通常希望限制树的深度,以便模型有更好的扩展性。

在训练过程中,我们会向模型提供特征 X 和标签 y,使其能够学习基于这些特征对数据点进行分类。从输出结果看出,决策树形成了9个节点nodes ,最大深度depth 为3,它将在训练数据上达到100%的准确性,因为我们没有限制深度,因此可以完美地对每个训练点进行分类。

4.随机森林

从上面的决策树来看,这种分类器堪称完美,因为根本不会犯任何错误,但要记住一个重点:单个决策树只是不会在训练数据上犯错。而机器学习模型的关键在于能很好地泛化用于测试数据。不幸的是,当我们不限制决策树的深度时,它往往都会与训练数据过拟合。

随机森林是多个决策树的集合,想象一下,你要分析明天小米的股票是否上涨,然后你决定去询问几位股票分析师朋友A和B。任何一位股票分析师都可能有很大的差异,并且非常依赖他们各自能获取的数据——A可能仅仅看到了小米公司新产品大卖的新闻,因此认为价格会上涨,而B看到了最近报道小米手机质量问题的新闻,所以认为应当下跌。这些分析师个体之间有很高的方差,因为他们的答案严重依赖于他们见过的数据。我们不只是询问单个分析师,而是集各种专家的意见,是相当于群体智慧,并基于最常见的答案给出最终决策。

随机森林的本质:不是使用单个决策树,而是使用数百或数千个决策树来组成一个强大的模型,则该模型的最终预测结果即为集体中所有决策树的预测的平均。

随机森林是由许多决策树构成的模型。这不仅仅是森林,而且是随机的,这涉及到两个概念:

  • 随机采样

随机森林的其中一个特点是:每个树都在训练集上随机的采样,这些样本是可重复地抽取出来的(叫 bootstrapping),也就是说某些样本会多次用于单个树的训练(当然也可以控制不重复)。这种在数据的不同子集上训练每个单个学习器然后再求预测结果的平均的流程被称为 bagging,这是 bootstrap aggregating 的缩写。

  • 基于特征属性的子集进行分类

随机森林的另一个特点是:在每个决策树中,分割每个节点时都只会考虑所有特征属性中的一个子集。通常设定为 sqrt(n_features),意思是在每个节点,决策树会基于一部分特征来考虑分割,这部分特征的数量为总特征数量的平方根。(在 Scikit-Learn 随机森林实现中,这些参数是可以调的。)

5.随机森林实践

我们将会使用一个真实数据集构建一个随机森林,非常类似于上面简单的二元分类模型,通过 Scikit-Learn 使用随机森林仅需要几行代码。

数据集

以下数据集来美国疾病预防控制中心,包括数十万人的社会经济和生活方式指标。目标是预测个体的整体健康状况:健康状况不佳0,健康状况良好1。

数据集这里可以获取:
https://www.kaggle.com/cdc/behavioral-risk-factor-surveillance-system

这是一个不平衡分类问题,因此准确度并不是合适的度量标准。我们将使用AUC(Area under Curve)来衡量,该度量的取值范围为 0(最差)到 1(最好),随机猜测的分数为 0.5。此外,我们还可以绘制 ROC 曲线来评估模型的表现。

AUC(Area under Curve):Roc曲线下的面积,介于0.1和1之间。Auc作为数值可以直观的评价分类器的好坏,值越大越好。

构建模型

这里我们省略了对数据的预处理,包括处理缺省值、去掉部分特征属性、分割训练测试集等,在读取了数据之后,我们可以用以下代码先实例化并训练一个决策树:

from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import precision_score, recall_score, roc_auc_score, roc_curve
# 单个决策树
tree.fit(train, train_labels)
print(f'Decision tree has {tree.tree_.node_count} nodes with maximum depth {tree.tree_.max_depth}.')
# Decision tree has 12327 nodes with maximum depth 55.
#评价性能
train_probs = tree.predict_proba(train)[:, 1]
probs = tree.predict_proba(test)[:, 1]

train_predictions = tree.predict(train)
predictions = tree.predict(test)
print(f'Train ROC AUC Score: {roc_auc_score(train_labels, train_probs)}')
print(f'Test ROC AUC  Score: {roc_auc_score(test_labels, probs)}')
#Train ROC AUC Score: 1.0
#Test ROC AUC  Score: 0.6639844451938421

以上是单个决策树的在训练集和测试集上的 ROC AUC 评价指标,可以看出单个决策树在训练集上AUC 值是1 ,但是在测试集上是0.66,AUC 大大降低了。

接下来我们可以实例化并训练一个随机森林:

from sklearn.ensemble import RandomForestClassifier
# Create the model with 100 trees
model = RandomForestClassifier(n_estimators=100, 
                               random_state=RSEED, 
                               max_features = 'sqrt',
                               n_jobs=-1, verbose = 1)
# Fit on training data
model.fit(train, train_labels)
#随机森林中决策树的平均深度以及节点数
n_nodes = []
max_depths = []
for ind_tree in model.estimators_:
    n_nodes.append(ind_tree.tree_.node_count)
    max_depths.append(ind_tree.tree_.max_depth)
print(f'Average number of nodes {int(np.mean(n_nodes))}')
print(f'Average maximum depth {int(np.mean(max_depths))}')
#Average number of nodes 13396
#Average maximum depth 46
....
....
#预测结果
rf_predictions = model.predict(test)
rf_probs = model.predict_proba(test)[:, 1]
# Calculate roc auc
print(f'Train ROC AUC Score: {roc_auc_score(train_labels, train_probs)}')
print(f'Test ROC AUC  Score: {roc_auc_score(test_labels, probs)}')
#Train: 1.0  Test: 0.87 

可以看出随机森林的在测试集上ROC AUC 结果是 0.87,而单个决策树的结果是 0.67。如果我们看看训练分数,可以看到这两个模型都得到了 1.0 的 ROC AUC,很明显这是过拟合了,因为我们已经为这些模型提供过训练数据的答案并且没有限制数的最大深度。尽管随机森林过拟合了,但是与单个决策树相比,它仍有更好的泛化能力。

构建调参

为了最大化随机森林的性能,我们可以使用随机搜索以获得更好的超参数。从网格中随机选择超参数的组合,使用对训练数据的交叉验证来评估它们,并返回执行最佳的值。

from sklearn.model_selection import RandomizedSearchCV
# Hyperparameter grid
param_grid = {
    'n_estimators': np.linspace(10, 200).astype(int),
    'max_depth': [None] + list(np.linspace(3, 20).astype(int)),
    'max_features': ['auto', 'sqrt', None] + list(np.arange(0.5, 1, 0.1)),
    'max_leaf_nodes': [None] + list(np.linspace(10, 50, 500).astype(int)),
    'min_samples_split': [2, 5, 10],
    'bootstrap': [True, False]
}
# Estimator for use in random search
estimator = RandomForestClassifier(random_state = RSEED)
# Create the random search model
rs = RandomizedSearchCV(estimator, param_grid, n_jobs = -1, 
                        scoring = 'roc_auc', cv = 3, 
                        n_iter = 10, verbose = 1, random_state=RSEED)
# Fit 
rs.fit(train, train_labels)
print(rs.best_params_ )
{'n_estimators': 29,
 'min_samples_split': 5,
 'max_leaf_nodes': 43,
 'max_features': 'auto',
 'max_depth': 16,
 'bootstrap': True}

我们可以看到最好的超参数值不是 Scikit-Learn 的默认值,这显示了为特定数据集调整模型的重要性。

...
best_model = rs.best_estimator_
train_rf_predictions = best_model.predict(train)
train_rf_probs = best_model.predict_proba(train)[:, 1]

rf_predictions = best_model.predict(test)
rf_probs = best_model.predict_proba(test)[:, 1]

n_nodes = []
max_depths = []

for ind_tree in best_model.estimators_:
    n_nodes.append(ind_tree.tree_.node_count)
    max_depths.append(ind_tree.tree_.max_depth)
    
print(f'Average number of nodes {int(np.mean(n_nodes))}')
print(f'Average maximum depth {int(np.mean(max_depths))}')
#Average number of nodes 85
#Average maximum depth 10

#预测结果
rf_predictions = model.predict(test)
rf_probs = model.predict_proba(test)[:, 1]
# Calculate roc auc
print(f'Train ROC AUC Score: {roc_auc_score(train_labels, train_probs)}')
print(f'Test ROC AUC  Score: {roc_auc_score(test_labels, probs)}')
#Train: 0.88  Test: 0.87 

如上所述,最佳模型的最大深度大大减少!这表明限制单个决策树的最大深度可以提高随机森林的交叉验证性能,此外,最优随机森林也减少了在训练集上的拟合度,优化模型实现与默认模型大致相同的性能。

6.总结

虽然我们可能不需要理解机器学习模型内部原理也能构建出强大的机器学习模型,但了解一些模型工作方式的还是很有必要的,对你理解模型的各个超参数有很大帮助。

7.参考资料

1.https://enlight.nyc/projects/random-forest
2.https://scikit-learn.org/

python实现随机森林 阅读详情

相关推荐

Python随机森林模型的基本原理和代码实现【附代码】

集成学习模型是机器学习非常重要的一部分。集成学习是使用一系列的弱学习器(或称之为基础模型)进行学习,并将各个弱学习器的结果进行整合从而获得比单个学习器更好的学习效果的一种机器学习方法。集成学习模型有两种常见的算法:•。

weixin_60476982的博客 7126

随机森林算法(Random Forest)Python实现

目录 前言 一、什么是Random Forest ? 1.1什么是监督式机器学习? 1.2 什么是回归和分类? 1.3 什么是决策树? 1.4 什么是随机森林? 二、Random Forest 的构造过程 2.1 算法实现 2.2数据的随机选取 2.3待选特征的随机选取 2.4 相关概念解释 三、 Random Forest 优缺点 3.1 优点 3.2 缺点 、Extra-Trees(极端随机树) 五、Random Forest 的Python实现 5.1 R.....

Python,数据分析,机器学习,深度学习 6万+

随机森林算法(Random Forest)原理分析及Python实现

随机森林算法(Random Forest)原理分析及Python实现

weixin_45075135的博客 2万+

Python机器学习09——随机森林

bagging,决策树,随机森林,变量重要性,偏依赖图

weixin_46277779的博客 1万+

机器学习python实现随机森林

本文使用mnist数据集,进行随机森林算法。

mzy20010420的博客 5366

随机森林模型Python代码——用随机森林模型实现机器学习

随机森林模型Python代码——用随机森林模型实现机器学习随机森林模型是一种流行且功能强大的机器学习算法,用于分类和回归任务。它属于集成学习方法,主要通过构建多个决策树并综合它们的预测结果来工作。

qq_41698317的博客 9560

随机森林算法详解

<div id="post_detail"> [Machine Learning & Algorithm] 随机森林(Random Forest) 阅读目录1 什么是随机森林?2 随机森林的特点3 随机森林的相关基础知识4 随机森林的生成5 袋外错误率(oob error)6 随机森林工作原理解释的一个简单例子7 随机森林...

阿斯达克 3万+

随机森林算法python实现

随机森林算法python实现瞎BB代码导入数据切分训练集测试集找到最有用的几个属性根据上面的代码更改属性参数组合遍历找最优随机森林样本数据 瞎BB 实现根据样本数据(用眼距离distance、最长持续用眼时长duration、总用眼时长total_time、户外运动时长outdoor、用眼角度angle、健康环境光照用眼比例proportion)判别是否需要近视预警 样本实在太少 代码 导入数据 ...

CK1201的博客 5966

机器学习——随机森林原理及Python实现

从直观角度来解释,每棵决策树都是一个分类器(假设现在针对的是分类问题),那么对于一个输入样本,N棵树会有N个分类结果。而随机森林集成了所有的分类投票结果,将投票次数最多的类别指定为最终的输出,这就是一种最简单的 Bagging 思想。...

qq_27758151的博客 3360

python实现随机森林_Python中的随机森林

python实现随机森林Random forest is a highly versatile machine learning method with numerous applications ranging from marketing to healthcare and insurance. It can be used to model the impact of marketing ...

cumei1658的博客 5048

随机森林回归算法的Python实现与应用

本文对随机森林回归算法对原理说明、算法的Python实现及算法应用进行了简要的说明,文中给出了一个拟合效果不佳的模型进行示例。

m0_61399808的博客 2万+

机器学习随机森林

简单介绍了集成学习定义,典型的集成算法随机森林的过程,及利用sklearn实现随机森林及可视化。

m0_69435474的博客 7211

机器学习④【算法详解:从决策树到随机森林

今天,我们将深入探讨两种强大且广泛应用的算法——决策树(Decision Tree)和随机森林(Random Forest)。

m0_74027965的博客 1304

随机森林算法的总结和基于python的简单实现

第一次写博客,水平有限,恳请指正交流. 接触机器学习也有一段时间了,以前只是看看理论,调调sklearn的包,感觉并没有真正的明白算法的具体细节。 现在开始利用空闲时间,把自己学过的算法用python实现一下,代码学习时间很短,所以代码结构不是很好,也没优化,以后我会努力写出优秀的代码的。 一 前言:随机森林(Random Forests)真正被系统性的提出是 BREIMAN  20

zwzen1的博客 1万+

Python随机森林实现与解释

作者:chen_h 微信号 & QQ:862251340 微信公众号:coderpai (一)机器学习中的集成学习入门 (二)bagging 方法 (三)使用Python进行交易的随机森林算法 (Python随机森林实现与解释 通过从单个决策树构建来使用和理解随机森林 幸运的是,对于像Scikit-Learn这样的库,现在很容易在Python实现数百种机器学习算法。这很容...

CoderPai的博客 8357

机器学习强基计划10-3:详解Bagging随机森林算法(Python实现)

并行集成学习通过并行地训练多个基础模型,并将它们的预测结果进行集成,以提高整体的学习性能和泛化能力。本文介绍Bagging框架与随机森林算法,并提供python实现加深理解

FRIGIDWINTER的博客 2925

【ML】机器学习中的随机森林算法

在数据分析领域,每种算法都有其价格。但如果我们考虑整体场景,那么业务问题最多有一个分类任务。考虑到数据的性质,直观地知道要采用什么变得相当困难。随机森林在金融、医疗保健、营销等领域具有多种应用。它们广泛用于欺诈检测、客户流失预测、图像分类和股票市场预测等任务。但今天我们将讨论最受数据专家信赖的顶级分类器技术之一,那就是随机森林分类器。随机森林还有一种回归算法技术,将在此处介绍。术语中的“森林”一词表明它将包含很多树木。

sikh_0529的博客 1080

随机森林python_实战:用Python实现随机森林

摘要: 随机森林如何实现?为什么要用随机森林?看这篇足够了!因为有Scikit-Learn这样的库,现在用Python实现任何机器学习算法都非常容易。实际上,我们现在不需要任何潜在的知识来了解模型如何工作。虽然不需要了解所有细节,但了解模型如何训练和预测对工作仍有帮助。比如:如果性能不如预期,我们可以诊断模型或当我们想要说服其他人使用我们的模型时,我们可以向他们解释模型如何做出决策的。在本文中,我...

weixin_42452328的博客 4547
上一篇: kaggle实战之房价预测,了解一下?
下一篇: Python | Pandas Series.nunique() 用法
grantpole
博客等级 码龄14年 39粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值