实战:用Python实现随机森林

摘要: 随机森林如何实现?为何要用随机森林?看这篇足够了!html

由于有Scikit-Learn这样的库,如今用Python实现任何机器学习算法都很是容易。实际上,咱们如今不须要任何潜在的知识来了解模型如何工做。虽然不须要了解全部细节,但了解模型如何训练和预测对工做仍有帮助。好比:若是性能不如预期,咱们能够诊断模型或当咱们想要说服其余人使用咱们的模型时,咱们能够向他们解释模型如何作出决策的。python

在本文中,咱们将介绍如何在Python中构建和使用Random Forest,而不是仅仅显示代码,我将尝试了解模型的工做原理。我将从一个简单的单一决策树开始,而后以解决现实世界数据科学问题的方式完成随机森林。本文的完整代码GitHubJupyter Notebook的形式提供git

理解决策

决策树是随机森林的构建块,它自己就是个直观的模型。咱们能够将决策树视为询问有关咱们数据问题的流程图。这是一个可解释的模型,由于它决定了咱们在现实生活中的作法:在最终得出决定以前,咱们会询问有关数据的一系列问题。github

决策树的主要技术细节是如何构建有关数据的问题,决策树是经过造成可以最大限度减小基尼系数的问题而创建的。稍后我会讨论Gini Impurity,但这意味着决策树试图造成尽量纯的节点,其中包含来自单个类的高比例样本(数据点)的节点。算法

Gini Impurity和构建树可能有点难以理解,因此首先让咱们构建一个决策树,以即可以更好的理解它。bootstrap

关于最简单问题的决策

咱们从一个很是简单的二进制分类问题开始,以下所示:app

咱们的数据只有两个特征(标签),且只有6个数据点。dom

虽然这个问题很简单,但它不是线性可分的,这意味着咱们不能经过数据绘制一条直线来对点进行分类。然而,咱们能够绘制一系列划分类的直线,这基本上是决策树在造成一系列问题时将要作的事情。机器学习

要建立决策树并在数据上训练,咱们可使用Scikit-Learn:性能

 from sklearn.tree import DecisionTreeClassifier # Make a decision tree and train tree = DecisionTreeClassifier(random_state=RSEED) tree.fit(X, y)

在训练过程当中,咱们为模型提供特征和标签,以便学习根据特征对点进行分类。咱们没有针对这个简单问题的测试集,可是在测试时,咱们只给模型提供功能并让它对标签作出预测。

咱们能够在训练数据上测试咱们模型的准确性:

print(f'Model Accuracy: {tree.score(X, y)}') Model Accuracy: 1.0

咱们看到它100%正确,这是咱们所指望的,由于咱们给了它训练的答案。

化决策

当咱们训练决策树时,实际上会发生什么?我发现了解决策树的最有用的方法是经过可视化,咱们可使用Scikit-Learn的功能(详细信息请查看笔记本本文)。

上图显示了决策树的整个结构,除叶节点(终端节点)外,全部节点都有5个部分:

  1. 问题基于特征值询问数据:每一个问题都有对或错的答案。根据问题的答案,数据点在树中移动。
  2. Gini:节点的Gini杂质。当咱们向下移动树时,平均加权基尼系数必须减小。
  3. samples:节点中的观察数。
  4. value:每一个类的样本数量。例如,顶部节点在类0中有2个样本,在类1中有4个样本。
  5. class:节点中点的多数分类。在叶节点的状况下,这是对节点中全部样本的预测。

叶节点没有问题,由于这些是最终预测的地方。要对新节点进行分类,只需向下移动树,使用点的特征来回答问题,直到到达class预测的叶节点。你可使用上面的点进行尝试,或者进行不一样的预测。

基尼系数

在这一点上,咱们应该尝试了解基尼系数。简而言之,Gini Impurity是随机选择的样本被节点中的样本分布标记错误的几率。例如,在顶部(根)节点中,有44.4%错误的可能性根据节点中样本标签的分布对随机选择的数据点进行分类。咱们可使用下面这个等式获得这个值:

节点的Gini系数n是1减去每一个J类的p_i平方的总和让咱们计算出根节点的基尼系数

在每一个节点处,决策树在要素中搜索要拆分的值,从而最大限度地减小基尼系数。(拆分节点替代方法是使用信息增益)。

而后,它以递归过程重复此拆分过程,直到达到最大深度,或者每一个节点仅包含来自一个类的样本。每层树的加权总基尼系数必须减小。在树的第二层,总加权基尼系数值为0.333:

最后一层的加权总Gini系数变为0意味着每一个节点都是纯粹的,而且从该节点随机选择的点不会被错误分类。虽然这彷佛是好结果,但这意味着模型可能过分拟合,由于节点仅使用是经过训练数据构建的

过分拟合:为何森林比一棵树更

你可能会想问为何不仅使用一个决策树?它彷佛是完美的分类器,由于它没有犯任何错误!记住这其中的关键点是树在训练数据上没有犯错。由于咱们给树提供了答案。机器学习模型的要点是很好地归纳测试数据。不幸的是,当咱们不限制决策树的深度时,它每每会过分拟合

当咱们的模型具备高方差而且基本上记忆训练数据时,必定会发生过分拟合。这意味着它能够很好地在训练数据上,但因为测试数据不一样,它将没法对测试数据作出准确的预测!咱们想要的是一个能很好地学习训练数据的模型,而且能够在其余数据集上发挥做用。当咱们不限制最大深度时,决策树容易过分拟合的缘由是由于它具备无限的复杂性,这意味着它能够保持增加,直到它为每一个单独的观察只有一个叶节点,完美地对全部这些进行分类。

要理解为何决策树具备高差别,咱们能够用一我的来考虑它。想象一下,你以为明天苹果股票会上涨,你会问一些分析师。每一位分析师均可能会有很大差别而且会严重依赖他们能够访问的数据。一位分析师可能只阅读亲苹果新闻,所以她认为价格会上涨,而另外一位分析师最近从她的朋友那里听到苹果产品的质量开始降低,她可能就认为价格会降低。这些个体分析师的差别很大,由于他们的答案极其依赖于他们所看到的数据。

由于每一个分析师均可以访问不一样的数据,因此预计个体差别会很大,但整个集合的整体方差应该减小。使用许多个体本质上是随机森林背后的想法:而不是一个决策树,使用数百或数千个树来造成一个强大的模型。(过分拟合的问题被称为误差-方差权衡,它是机器学习中的一个基本主题)。

随机森林

随机森林是许多决策树组成的模型。这个模型不只仅是一个森林,并且它仍是随机的,由于有两个概念:

  1. 随机抽样的数据点;
  2. 基于要素子集拆分的节点;

随机抽

随机森林背后的关键是每棵树在数据点的随机样本上训练。样本用替换(称为bootstrapping)绘制,这意味着一些样本将在一个树中屡次训练。这个想法是经过对不一样样本的每棵树进行训练,尽管每棵树相对于一组特定的训练数据可能有很大的差别,但整体而言,整个森林的方差都很小。每一个学习者在数据的不一样子集上学习,而后进行平均的过程被称为bagging,简称bootstrap aggregating

用于拆分节点的随机特征子集

随机森林背后的另外一个关键点是,只考虑全部特征的子集来分割每一个决策树中的每一个节点。一般,这被设置为sqrt(n_features)意味着在每一个节点处,决策树考虑在特征的样本上分割总计特征总数的平方根。考虑到每一个节点的全部特征,也能够训练随机森林。

若是你掌握单个决策树、bagging决策树和随机特征子集,那么你就能够很好地理解随机森林的工做原理。随机森林结合了数百或数千个决策树,在略微不一样的观察集上训练每一个决策树,而且仅考虑有限数量的特征来分割每一个树中的节点。随机森林作出的最终预测是经过平均每棵树的预测来作出的。

随机森林实践

与其余Scikit-Learn模型很是类似,在Python中使用随机森林只须要几行代码。咱们将构建一个随机森林,但不是针对上面提到的简单问题。为了将随机森林与单个决策树的能力进行对比,咱们将使用分为训练和测试的真实数据集。

数据集

咱们要解决的问题是二进制分类任务。这些特征是我的的社会经济和生活方式特征,标签是健康情况不佳为0和身体健康为1。此数据集是由中心疾病控制和预防收集,能够在这里找到。这是一个不平衡的分类问题,所以准确性不是一个合适的指标。相反,咱们将测量接收器工做特性区域曲线(ROC AUC),从0(最差)到1(最佳)的度量,随机猜想得分为0.5。咱们还能够绘制ROC曲线以评估模型性能。

笔记本包含了决策树和随机森林的实现,但在这里咱们只专一于随机森林。在读取数据后,咱们能够实现并训练随机森林以下:

from sklearn.ensemble import RandomForestClassifier # Create the model with 100 trees model = RandomForestClassifier(n_estimators=100, bootstrap = True, max_features = 'sqrt') # Fit on training data model.fit(train, train_labels)

在训练几分后,准对测试数据行以下预测

# Actual class predictions rf_predictions = model.predict(test) # Probabilities for each class rf_probs = model.predict_proba(test)[:, 1]

咱们进类预测(predict)以及predict_proba计算ROC AUC所需的预测几率()。一旦我们进行了预测测试,我就能够将它测试标签进行比较,以计算出ROC AUC

from sklearn.metrics import roc_auc_score # Calculate roc auc roc_value = roc_auc_score(test_labels, rf_probs)

结果

最终的ROC AUC是随机森林为0.87而单一决策树是0.67。若是咱们查看训练分数,咱们注意到两个模型都达到了1.0 ROC AUC,由于咱们给这些模型提供了训练答案,并无限制最大深度。然而,尽管随机森林过分拟合,但它可以比单一决策树更好地推广测试数据。

若是咱们检查模型,咱们会看到单个决策树达到最大深度55,总共12327个节点。随机森林中的平均决策树的深度为46和13396个节点。即便平均节点数较多,随机森林也能更好地推广!

咱们还能够绘制单个决策树(顶部)和随机森林(底部)的ROC曲线。顶部和左侧的曲线是更好的模型:

咱们看到随机森林明显优于单一决策树。咱们能够采用模型的另外一个诊断措施是绘制测试预测的混淆矩阵:

特征重要性(Feature Importances)

随机森林中的特征重要性表示在该特征上拆分的全部节点上Gini系数减小总和。咱们可使用这些来尝试找出随机森林最重要的预测变量,同时也能够从训练有素的随机森林中提取特征重要性,并将其放入Pandas数据框中,以下所示:

import pandas as pd # Extract feature importances fi = pd.DataFrame({'feature': list(train.columns), 'importance': model.feature_importances_}).\ sort_values('importance', ascending = False) # Display fi.head() feature importance DIFFWALK 0.036200 QLACTLM2 0.030694 EMPLOY1 0.024156 DIFFALON 0.022699 USEEQUIP 0.016922

咱们还能够经过删除具备0或低重要性的特征来使用特征重要性来选择特征

在森林中可

最后,咱们能够在森林中可视化单个决策树。此次,咱们必须限制树的深度,不然它将太大而没法转换为图像。为了制做我将最大深度限制为6,这仍然致使咱们没法彻底解析的大树!

优化决策树

下一步多是经过随机搜索和Scikit-LearnRandomizedSearchCV来优化随机森林。

优化是指在给定数据集上找到模型的最佳超参数。最佳超参数将在数据集之间变化,所以咱们必须在每一个数据集上单独执行优化(也称为模型调整)。我喜欢将模型调整视为寻找机器学习算法的最佳设置。有关随机森林模型优化的随机搜索的实现,请参阅Jupyter Notebook

结论

在本文中,咱们不只在Python中构建和使用了随机森林,并且还对模型的进行了分析。

咱们首先查看了一个单独的决策树,一个随机森林的基本构建块,而后咱们看到了如何在一个集合模型中组合数百个决策树。当与bagging特征一块儿使用和随机抽样时,该集合模型被称为随机森林。从这篇文章中理解的关键概念是:

  1. 决策:直观模型,根据询问有关特征值的问题流程图作出决策,经过过分拟合训练数据表示方差高。
  2. Gini Impurity:衡量决策树在拆分每一个节点时尝试最小化的度量。表示根据节点中样本的分布对来自节点的随机选择的样本进行分类的几率。
  3. Bootstrapping:用替换的方式随机观察组进行采样。随机森林用于训练每一个决策树的方法。
  4. 随机的特征子集:在考虑如何在决策树中分割每一个节点时选择一组随机特征。
  5. 随机森林:由数百或数千个决策树组成的集合模型,使用自举,随机特征子集和平均投票来进行预测。这是一个bagging总体的例子。
  6. 误差-方差:机器学习中的基本问题,描述了高复杂度模型之间的权衡,以采用最好的方式学习训练数据,代价是没法推广到测试数据以及简单的模型(高偏见)甚至没法学习训练数据。随机森林减小了单个决策树的方差,同时还准确地学习了训练数据,从而更好地预测了测试数据。

但愿本文为你提供了开始在项目中使用随机森林所需的信心和理解。随机森林是一种强大的机器学习模型,但这不该该阻止咱们知道它是如何工做的!

原文连接

相关文章
相关标签/搜索