一、什么是决策树

决策树(Decision Tree)是一种非参数的有监督学习方法,它能够从一系列有特征和标签的数据中总结出决策规则,并用树状图的结构来呈现这些规则,以解决分类和回归问题。
本文主要介绍分类树。

划分选择

决策树的关键在于如何选择最优划分属性。随着划分过程不断进行,我们希望决策树的分支节点所包含的样本尽可能属于同一类别,即节点的**“纯度”**越来越高(纯度高代表混合的数据少)。

划分准则:

(一)信息增益

“信息熵”是度量样本纯度最常用的准则,信息熵的定义公式为:

二分类决策树 分类树和回归树 分类树和决策树的区别_决策树


D:样本集合,共有n类样本。

P(xi):第i类样本的所占比。标签为i的样本数/总样本数

Ent(D)越小,D的纯度越高。信息增益(Information Gain)的是父节点的信息熵与其下所有子节点总信息熵之差。但这里要注意的是,此时计算子节点的总信息熵不能简单求和,而要在求和汇总之前进行修正(对不同子节点赋予不同的权重)。

信息增益的公式:

二分类决策树 分类树和回归树 分类树和决策树的区别_二分类决策树 分类树和回归树_02


a:属性

V:属性a共有V个可能得取值,若用a对D进行划分,会产生V个子节点。

Dv:在属性a上取值为av的样本数。

权重:分支节点的样本数/总样本数

划分数据集的准则是:选取最大的信息增益,即信息下降最快的方向。

计算信息熵的Python实现:

#计算信息熵函数,返回信息熵
def calEnt(dataSet):
    n=dataSet.shape[0]  #计算总行数
    iset=dataSet.iloc[:,-1].value_counts()   #计算标签个数
    p=iset/n                 #每类标签的所占比
    ent=(-p*np.log2(p)).sum()
    return ent

选择最优划分属性:

#根据信息增益选择最佳数据集切分的列   返回:数据集最佳切分列的索引
def bestSplite(dataSet):
    baseEnt=calEnt(dataSet)     #原始信息熵
    bestGain=0                  #初始化信息增益
    axis=-1    #初始化最佳切分列
    for i in range(dataSet.shape[1]-1):  #对特征的每列循环,去除标签列
        levels=dataSet.iloc[:,i].value_counts().index  #取出当前列所有取值
        ents=0  #初始化子节点信息熵
        for j in levels:  #对每列的每个取值循环
            childSet=dataSet[dataSet.iloc[:,i]==j]   #某个子节点
            ent=calEnt(childSet)     #子节点信息熵
            ents+=(childSet.shape[0]/dataSet.shape[0])*ent   #当前列的信息熵
        infoGain=baseEnt-ents    #当前列的信息增益
        if(infoGain>bestGain):
                bestGain=infoGain   #选取信息增益最大的
                axis=i
    return axis

(二)增益率
(三)基尼指数

决策树的基本流程

  1. 计算全部特征的不纯度指标
  2. 选取不纯度指标最优的特征进行分支
  3. 在第一个特征的分支下,计算全部特征的不纯度指标
  4. 选取不纯度指标最优的特征进行分支

重要参数

  • Criterion:用来决定不纯度的计算方法。
    1)输入”entropy“,使用信息熵(Entropy)
    2)输入”gini“,使用基尼系数(Gini Impurity)
  • random_state:用来设置分枝中的随机模式的参数。默认为None。输入任意整数,会一直长出同一棵树,让模型稳定下来。
  • splitter:也是用来控制决策树中的随机选项的。有两种输入值,输入”best",决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看);输入“random",决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对训练集的拟合。这 也是防止过拟合的一种方式。
  • 剪枝参数:为了防止过拟合,提高决策树的泛化性,要对决策树进行剪枝。剪枝策略对决策树的影响巨大,正确的剪枝策略是优化决策树算法的核心。
    max_depth:限制树的最大深度,超过设定深度的树枝全部剪掉。
    min_samples_leaf:限定,一个节点在分枝后的每个子节点都必须包含至少min_samples_leaf个训练样本,否则分枝就不会发生,或者,分枝会朝着满足每个子节点都包含min_samples_leaf个样本的方向去发生 。
    min_samples_splite:限定,一个节点必须要包含至少min_samples_split个训练样本,这个节点才允许被分枝,否则 分枝就不会发生。
    max_features:限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。
    min_impurity_decrease:限制信息增益的大小,信息增益小于设定数值的分枝不会发生。
  • 目标权重参数
    class_weight:对样本标签进行少量的均衡,给少量标签更多的权重,让模型更偏向少数标签,向捕获少数类的方向建模。默认值为None,表示给各类标签相同的权重。
    min_weight_fraction_leaf:当有了权重后需要搭配这个基于权重的剪枝参数来进行剪枝。

属性

feature_importances_:能够查看各个特征的重要性。

接口

fit:拟合数据。
score:对模型进行评估。
apply:输入测试集,返回测试样本所在叶子节点的索引。
predict:输入测试集返回每个测试样本的标签。

决策树示例

通过训练红酒数据集预测红酒的种类。
step1: 导入需要的算法库和模块

from sklearn import tree
from sklearn.datasets import load_wine
from sklearn.model_selection import train_test_split

step2:探索数据

wine=load_wine()

import pandas as pd
pd.concat([pd.DataFrame(wine.data),pd.DataFrame(wine.target)],axis=1)

二分类决策树 分类树和回归树 分类树和决策树的区别_决策树_03


step4 :分训练集和测试集

#70%训练集,30%测试集
Xtrian,Xtest,Ytrain,Ytest=train_test_split(wine.data,wine.target,test_size=0.3)

step5:创建模型(关键步骤)

#建模并进行探索
clf=tree.DecisionTreeClassifier(criterion='entropy')  #实例化,采用信息增益的方式
clf=clf.fit(Xtrian,Ytrain)  #拟合数据
score=clf.score(Xtest,Ytest) #评估,相当于accuracy
score

二分类决策树 分类树和回归树 分类树和决策树的区别_二分类决策树 分类树和回归树_04


step6 画出决策树

feature_name = ['酒精','苹果酸','灰','灰的碱性','镁','总酚',
                '类黄酮','非黄烷类酚类','花青素','颜色强度','色调','od280/od315稀释葡萄酒','脯氨酸']
import graphviz
dot_data=tree.export_graphviz(clf,
                             feature_names=feature_name,
                             class_names=["琴酒","雪莉","贝尔摩德"],
                             filled=True,
                             rounded=True)
graph=graphviz.Source(dot_data)
graph

二分类决策树 分类树和回归树 分类树和决策树的区别_信息熵_05


二分类决策树 分类树和回归树 分类树和决策树的区别_1024程序员节_06


step7:探索决策树

#特征重要性
clf.feature_importances_
 
[*zip(feature_name,clf.feature_importances_)]

二分类决策树 分类树和回归树 分类树和决策树的区别_信息熵_07