决策树的集成 —随机森林

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

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

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

想要构建一个随机森林模型,需要确定用于构建的树的个数(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






猜你喜欢

转载自blog.csdn.net/RedPintings/article/details/80924023
今日推荐