欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

决策树的集成 —随机森林

程序员文章站 2024-03-19 21:27:46
...

决策树的缺点在于,即使做了预剪枝,也会经常的过拟合,泛化能力很差,所以在大多数应用中。往往使用下面的的集成方法来代替蛋单棵决策树。

决策树的一个主要缺点在于经常对训练的数据过拟合。随机森林是解决这个问题的一种方法。随机森林的本质上是很多决策树的集合,其中那个每棵树都和其他树略有不同。随机森林背后砈思想史是,每棵树的预测都可能相对较好,但可能对部分书聚过拟合,如果我们构建很多树,并且每棵树都可以预测的很好,但都已不同的方式过拟合,那么我们可以对这些树的结果取平均值来降低过拟合。既能减少过拟合又能保持树的预测能力。

为了实现这一策略,我们需要构建很多树。每棵树都应该对目标值做出可以接受的预测,还应该与其他的树不同。随机森林的名字来源于 将随机性添加到树的构建过程中,以确保每棵树都是不同的。随机森立的随机化方法有两种: 一种是 选择用于构造树的数据点,另一种是通过选择每次划分测试的特征。

想要构建一个随机森林模型,需要确定用于构建的树的个数(RandomForestClassifier 的 n_estimators=‘x’参数)。比如我们想构建10棵树。这些树在构建时候完全独立,算法对每棵树进行不同的随机选择,以用来确保每棵树之间都是不同的。想要构建一棵树,首先要对数据进行自助采样(bootstrapsample)。也就是说,从n_samples个数据点中有放回的(即同一个样本可以被多次抽取,)重复抽取一个样本,共抽取n_samples次,这样创建的一个原数据集大小相同的数据集,但是有些数据点绘缺失,有些会重复。

我们来举个例子,比如我们创建列表['a','b','c','d','f']的自助采样。一种可能的自主采样是['a','a','c','f','b']也可能是['d','a','f','c','d']

对所有的树的预测概率取平均值,然后将概率最大的类别作为预测结果

分析随机森林:

下边将由五5棵树组成的随机森林应用 two_moons数据集上

from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
import mglearn


X,y = make_moons(n_samples=100,noise=0.2,random_state=3)
X_train,X_test,y_train,y_test = train_test_split(X,y, stratify=y,random_state=41)
forest = RandomForestClassifier(n_estimators=5,random_state=2)
forest.fit(X_train,y_train)
# 作为随机森林的一部分,树被保存在estimators_属性中

fig,axes = plt.subplots(2,3,figsize=(20,10))
for i ,(ax,tree) in enumerate(zip(axes.ravel(),forest.estimators_)):
    ax.set_title("Tree{}".format(i))
    mglearn.plots.plot_tree_partition(X_train,y_train,tree,ax=ax)

mglearn.plots.plot_2d_classification(forest,X_train,fill=True,ax=axes[-1,-1],alpha=0.4)
axes[-1,-1].set_title("Random Forest")
mglearn.discrete_scatter(X_train[:,0],X_train[:,1],y_train)
plt.show()

决策树的集成 —随机森林

可以清楚的看到,这5棵树的决策边界大不相同。每棵树都犯了一些错误,因为这里画出的一些训练点实际上并没有包含在这些树的训练集中,这主要是由于自组采样

随机森林比单独一棵树的过拟合都要小,给出的决策边界也更符合直觉,但是在实际问题的解决中我们会用到更多的树木(成百上千)从而得到更平滑的界面。

调参测试:

决策树的集成 —随机森林

下边的这个例子是包含100课树的随机森林应用在乳腺癌数据集上

from sklearn.datasets import load_breast_cancer
from sklearn.ensemble import RandomForestClassifier
import matplotlib.pyplot as plt
import numpy as np

cancer = load_breast_cancer()
X_train,X_test,y_train,y_test =train_test_split(cancer.data,cancer.target,random_state=0)
forest = RandomForestClassifier(n_estimators=100,random_state=0)
forest.fit(X_train,y_train)
print("training set score:{:.3f}".format(forest.score(X_train,y_train)))
print("testing set score :{:.3f}".format(forest.score(X_test,y_test)))

def plot_feature_importance_cancer(model):
    n_features = cancer.data.shape[1]
    plt.barh(range(n_features),model.feature_importances_,align='center')
    plt.yticks(np.arange(n_features),cancer.feature_names)
    plt.xlabel('Feature importance')
    plt.ylabel('Feature')
    plt.show()
plot_feature_importance_cancer(forest)

运行结果:

training set score:1.000
testing set score :0.972

决策树的集成 —随机森林

我们可以看到与单棵树相比随机森林中有更多的特征重要性不为零。与单颗树类似,随机森林也给出了“worst radius”这种特征重要性比较大的,但是从总体看来的话,但是从整体来看的话他却选择了“worst perimeter”最为信息量最大的特征。由于构造随机森里你的随机性,算法需要考虑多种可能的考虑,结果及时随机森林比单棵树更能从整体把握数据的特征。

关于优点缺点和参数:

随机森林的有点弥补了单棵决策树的不足,但是有些情况并不需要成百上千棵树进行表示,在大型数据上构建随机森林可能比较浪费时间。

(random_state)参数可以改变模型,如果要固定模型的数据,应选用同样的(random_state)参数

(n_estimators)参数很重要,(n_estimators)越大,更多的树取平均能更好的降低过拟合,可以得到更好的集合,不过使用的计算机内存会更多和构建模型的时间也相应变得很长,在我们 的条件允许下可以这样做。


决策树中还有一个(max_depth) 预剪枝选项也是很重要的参数,它控制着树的深度层级

(max_depth=5),数据集 cancer


决策树的集成 —随机森林