机器学习算法-决策树算法原理及其sklearn实现

前言

先梳理一下决策树的预测过程。预测时,从根节点开始,每次对一个特征分量进行判断,然后进入左子节点或者右子节点,直到抵达叶子节点,得到对应的类别标签或者回归值。

1.决策过程

先来看一个简单的决策树例子:
机器学习算法-决策树算法原理及其sklearn实现_第1张图片
银行要判断能否给一个人贷款,需要满足判断两个特征,一个是年收入,一个是是否有房产,这是一个二分类问题。
来走一下这个决策树的流程,首先是根节点,判断年收入是否大于20万。年收入大于20就可以给这个人贷款,不大于20万就去下一个判断,下一个节点的判断是是否有房产,有房产就可以贷款,没有就不能贷款。
决策树有两种类型的节点:
(1)决策节点:用特征分量的值和设定好的阈值比较,判断进入哪个分支,决策节点定有两个子节点。
(2)叶子节点:表示最终决策结果,对于分类问题就是类别标签,对于回归问题就是回归值。
决策树是一个判别模型,天然支持多分类。

2.训练流程

介绍一下决策树的训练流程,决策树的训练流程是一个递归的过程。首先创建根节点,然后递归地创建左子树和右子树。训练样本为X,训练算法流程如下:

1.用样本集X建立根节点,找到一个判定规则,将样本分裂称X1,X2两部分,同时为根节点设定判定规则。

2.用样本集X1递归建立左子树。

3.用样本集X2递归建立右子树。

4.如果不能再进行分裂,则把节点标记为叶子节点,同时为它赋值。

下面说说上面算法流程中的一些问题。第一,如何寻找最佳分类,对于分类问题,要保证分类之后左子树,右子树的样本尽量纯,也就是左右子树的样本尽可能属于不相交的某一类或者几类,简单来说,就是尽量让两个子树的样本里面尽量没有样本的类别重合。
第二个问题,何时停止分裂,建立叶子节点?有两种方法,一种是当节点的所有样本属于一个类的时候,另一种时当节点的样本树小于某一个阈值的时候。

3.寻找最佳分裂

1.不纯度定义

下面来介绍一下怎么寻找最佳分裂吧。首先,我们定义一个不纯度指标,当样本都属于一个类的时候,不纯度为0。当样本均匀地属于所有类的时候不纯度最大。满足这个条件的有熵不纯度,Gini不纯度,以及误分类不纯度。
不纯度指标用样本集中每类样本出现的概率构造:
pi=Ni/N
其中Ni为第i类样本数,N为样本总数。
样本的熵不纯度定义为:
机器学习算法-决策树算法原理及其sklearn实现_第2张图片
Gini不纯度定义为:
机器学习算法-决策树算法原理及其sklearn实现_第3张图片
样本的误分类不纯度定义为:
机器学习算法-决策树算法原理及其sklearn实现_第4张图片
上面定义出了样本集的不纯度,我们需要评价分裂的好坏,我们的目标时尽可能时分裂的子集都尽可能纯。因此计算左右两个子集的不纯度之和作为分裂的不纯度。但是分裂之后两边样本不一定时均衡的,因此还得用左右子树的样本数占根节点的样本数的比例最为权重。因此最终的分裂不纯度定义为:
机器学习算法-决策树算法原理及其sklearn实现_第5张图片

2.对于分类问题

如果采用Gini不纯度作为指标,对于样本集X(x1,x2…,xi),其中xi为某个特征分量,求最佳分裂。我们使用样本集的每个样本特征值xi依次作为分裂阈值,依次求出用这个阈值分裂之后得到左右子树的Gini不纯度,得到最小Gini不纯度对应的阈值既为所求,便是根节点的判定规则,根节点的分裂阈值。当然也可以对上面公式代入Gini不纯度公式,把它转换称一个求最大值的问题。

3.对于回归问题

对于回归问题,我们也是类似的处理。回归问题,节点的回归值就是所有样本标签值得均值。定义回归误差:
机器学习算法-决策树算法原理及其sklearn实现_第6张图片
分裂的回归指标即为(这个使用根节点的回归误差减去左右子树的回归误差,所以在下面要求对应的最大值的特征值) :
机器学习算法-决策树算法原理及其sklearn实现_第7张图片
这也是类似的过程,用每个样本对用的特征值作为分裂阈值,对应的最大的回归指标的特征值即为我们根节点的分裂阈值。当然,这个回归指标也能对公式代入化简,简化一下计算。

4.sklearn实现

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()

运行结果如下:
机器学习算法-决策树算法原理及其sklearn实现_第8张图片
看运行结果,感觉决策树就像分段函数。

你可能感兴趣的:(机器学习,机器学习,决策树,算法,sklearn,python)