赞
踩
先梳理一下决策树的预测过程。预测时,从根节点开始,每次对一个特征分量进行判断,然后进入左子节点或者右子节点,直到抵达叶子节点,得到对应的类别标签或者回归值。
先来看一个简单的决策树例子:
银行要判断能否给一个人贷款,需要满足判断两个特征,一个是年收入,一个是是否有房产,这是一个二分类问题。
来走一下这个决策树的流程,首先是根节点,判断年收入是否大于20万。年收入大于20就可以给这个人贷款,不大于20万就去下一个判断,下一个节点的判断是是否有房产,有房产就可以贷款,没有就不能贷款。
决策树有两种类型的节点:
(1)决策节点:用特征分量的值和设定好的阈值比较,判断进入哪个分支,决策节点定有两个子节点。
(2)叶子节点:表示最终决策结果,对于分类问题就是类别标签,对于回归问题就是回归值。
决策树是一个判别模型,天然支持多分类。
介绍一下决策树的训练流程,决策树的训练流程是一个递归的过程。首先创建根节点,然后递归地创建左子树和右子树。训练样本为X,训练算法流程如下:
下面说说上面算法流程中的一些问题。第一,如何寻找最佳分类,对于分类问题,要保证分类之后左子树,右子树的样本尽量纯,也就是左右子树的样本尽可能属于不相交的某一类或者几类,简单来说,就是尽量让两个子树的样本里面尽量没有样本的类别重合。
第二个问题,何时停止分裂,建立叶子节点?有两种方法,一种是当节点的所有样本属于一个类的时候,另一种时当节点的样本树小于某一个阈值的时候。
下面来介绍一下怎么寻找最佳分裂吧。首先,我们定义一个不纯度指标,当样本都属于一个类的时候,不纯度为0。当样本均匀地属于所有类的时候不纯度最大。满足这个条件的有熵不纯度,Gini不纯度,以及误分类不纯度。
不纯度指标用样本集中每类样本出现的概率构造:
pi=Ni/N
其中Ni为第i类样本数,N为样本总数。
样本的熵不纯度定义为:
Gini不纯度定义为:
样本的误分类不纯度定义为:
上面定义出了样本集的不纯度,我们需要评价分裂的好坏,我们的目标时尽可能时分裂的子集都尽可能纯。因此计算左右两个子集的不纯度之和作为分裂的不纯度。但是分裂之后两边样本不一定时均衡的,因此还得用左右子树的样本数占根节点的样本数的比例最为权重。因此最终的分裂不纯度定义为:
如果采用Gini不纯度作为指标,对于样本集X(x1,x2…,xi),其中xi为某个特征分量,求最佳分裂。我们使用样本集的每个样本特征值xi依次作为分裂阈值,依次求出用这个阈值分裂之后得到左右子树的Gini不纯度,得到最小Gini不纯度对应的阈值既为所求,便是根节点的判定规则,根节点的分裂阈值。当然也可以对上面公式代入Gini不纯度公式,把它转换称一个求最大值的问题。
对于回归问题,我们也是类似的处理。回归问题,节点的回归值就是所有样本标签值得均值。定义回归误差:
分裂的回归指标即为(这个使用根节点的回归误差减去左右子树的回归误差,所以在下面要求对应的最大值的特征值) :
这也是类似的过程,用每个样本对用的特征值作为分裂阈值,对应的最大的回归指标的特征值即为我们根节点的分裂阈值。当然,这个回归指标也能对公式代入化简,简化一下计算。
sklearn中用DecisionTreeClassifier类实现分类决策树,使用DecisionTreeRegressor类实现回归决策树。
一个用决策树做分类问题代码示例如下:
import numpy as np import matplotlib.pyplot as plt from sklearn import datasets from sklearn import tree import matplotlib # 生成所有测试样本点 def make_meshgrid(x, y, h=.02): x_min, x_max = x.min() - 1, x.max() + 1 y_min, y_max = y.min() - 1, y.max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) return xx, yy # 对测试样本进行预测,并显示 def plot_test_results(ax, clf, xx, yy, **params): Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) #画等势图 ax.contourf(xx, yy, Z, **params) # 载入iris数据集 iris = datasets.load_iris() # 只使用前面连个特征 X = iris.data[:, :2] # 样本标签值 y = iris.target # 创建并训练决策树 clf = tree.DecisionTreeClassifier() clf.fit(X,y) title = ('DecisionTreeClassifier') fig, ax = plt.subplots(figsize = (5, 5)) plt.subplots_adjust(wspace=0.4, hspace=0.4) X0, X1 = X[:, 0], X[:, 1] # 生成所有测试样本点 xx, yy = make_meshgrid(X0, X1) # 显示测试样本的分类结果 plot_test_results(ax, clf, xx, yy, cmap=plt.cm.coolwarm, alpha=0.8) # 显示训练样本 ax.scatter(X0, X1, c=y, cmap=plt.cm.coolwarm, s=20, edgecolors='k') ax.set_xlim(xx.min(), xx.max()) ax.set_ylim(yy.min(), yy.max()) ax.set_xlabel('x1') ax.set_ylabel('x2') ax.set_xticks(()) ax.set_yticks(()) ax.set_title(title) plt.show()
运行结果如下:
看运行结果,感觉决策树就像分段函数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。