机器学习之决策树算法前期(创建、分类及展示)

一、什么是决策树?

        决策树算法是一种逼近离散函数值的方法。它是一种典型的分类方法,首先对数据进行处理,利用归纳算法生成可读的规则和决策树,然后使用决策对新数据进行分析。本质上决策树是通过一系列规则对数据进行分类的过程。

决策树算法构造决策树来发现数据中蕴涵的分类规则.如何构造精度高、规模小的决策树是决策树算法的核心内容。决策树构造可以分两步进行。第一步,决策树的生成:由训练样本集生成决策树的过程。一般情况下,训练样本数据集是根据实际需要有历史的、有一定综合程度的,用于数据分析处理的数据集。第二步,决策树的剪枝:决策树的剪枝是对上一阶段生成的决策树进行检验、校正和修下的过程,主要是用新的样本数据集(称为测试数据集)中的数据校验决策树生成过程中产生的初步规则,将那些影响预衡准确性的分枝剪除。

机器学习之决策树算法前期(创建、分类及展示)_第1张图片

 

二、怎么完成决策树的创建?(递归算法实现)

在构建决策树的时候,我们得考虑哪个属性来当根节点?哪些属性来当内部决策节点?这里是有一个依据原则的。在说这个原则之前,我们先说一下熵的概念。

熵(entropy):用来表示物体内部的混乱程度。一个物体内部构成越纯,熵越小;越混乱,熵越大。在机器学习中,表示随机变量分布的混乱程度。

信息熵(information entropy):信息熵通常用来描述整个随机分布所带来的信息量平均值,更具统计特性。一个系统越是有序,信息熵就越低;反之,一个系统越是混乱,信息熵就越高。

假设样本集合 D 中第 i 类样本所占的比例是 pi(i=1,2,⋯,N) ,则样本集合 D 的信息熵为

 

注:随机变量的取值个数越多,信息熵就越大,混乱程度就越大。当随机分布为均匀分布时,熵最大。

条件熵 (Conditional entropy): 现在我们假设将样本集合 D 按属性 a 进行划分,假设属性 a 有 v 个可能的取值,则按 a 属性进行分裂出的 v 个子集(即树中的 v 个分支),每个可能取值集合为 D^v ,则 a 属性的条件熵计算方法为( |D^v| 和 |D| 表示集合中元素的个数)

 

1、模型创建:

       决策树模型创建的核心就是选择合适的树根 , 将重要的属性放在树根 , 然后子树中 , 继续选择子树中重要的属性放在子树的树根 , 依次递归 , 最终得到决策结果 ( 叶子节点 ) ;

①选取决策节点的原则

随着树深度的增加,节点的可以迅速地降低。熵降低的速度越来越快,得到一个最矮的高度树。

2、创建决策树的递归算法:

①递归操作:

a.选择属性 : 递归由上到下决定每一个节点的属性 , 依次递归构造决策树 ;

b.数据集划分 : 开始决策时 , 所有的数据都在树根 , 由树根属性来划分数据集 ;

c.属性离散化 : 如果属性的值是连续值 , 需要将连续属性值离散化 ; 如 : 100 分满分 , 将 60 分以下分为不及格数据 , 60 分以上分为及格数据 ;

②递归终止条件:

a.子树分类完成 : 节点上的子数据集都属于同一个类别 , 该节点就不再向下划分 , 称为叶子节点 ;

b.属性 ( 节点 ) 全部分配完毕 : 所有的属性都已经分配完毕 , 决策树的高度等于属性个数 ;

c.所有样本分类完毕 : 所有的样本数据集都分类完成 ;

3、具体创建代码:

def CreateTree(DataSet):
    #获取所有特征标签
    index_list = list(DataSet.columns)
    #获取最后一列(分类标签)的类别
    label_series = DataSet.iloc[:,-1].value_counts()
    #判断类别标签最多一个是否等于数据样本数、或者数据集是否只有一列
    if label_series[0]==DataSet.shape[0] or DataSet.shape[1] == 1:
        return label_series.index[0] #返回类标签
    # 获取最优特征列索引
    col = ChooseBF(DataSet)
    # 获取最优特征
    BestFeature = index_list[col]
    #将最优特征依次填入字典中
    TheTree = {BestFeature:{}}
    # 从标签列表中删去该特征标签
    del index_list[col]
    #提取最佳切分列的所有属性值
    value_list = set(DataSet.iloc[:,col])
    #利用递归方法建树,每次对象为当前最优特征
    for value in value_list:
        TheTree[BeatFeature][value] = CreateTree(splitSet(DataSet,col,value))
    return TheTree

运行上述代码即可得到 TheTree:

{'tearRate': {0: 'no lenses', 1: {'astigmatic': {0: {'age': {0: 'soft', 1: 'soft', 2: {'prescript': {0: 'no lenses', 1: 'soft'}}}}, 1: {'prescript': {0: 'hard', 1: {'age': {0: 'hard', 1: 'no lenses', 2: 'no lenses'}}}}}}}}

三、如何代码实现利用决策树进行分类及展示?

1、使用决策树进行分类:

"""
函数功能:对一个测试实例进行分类
参数说明:
	inputTree:已经生成的决策树
	labels:存储选择的最优特征标签
	testVec:测试数据列表,顺序对应原数据集
返回:
	classLabel:分类结果
"""
def classify(inputTree,labels, testVec):
    firstStr = next(iter(inputTree))                   #获取决策树第一个节点
    secondDict = inputTree[firstStr]                   #下一个字典
    featIndex = labels.index(firstStr)     			   #第一个节点所在列的索引
    for key in secondDict.keys():
        if testVec[featIndex] == key:
            if type(secondDict[key]) == dict :
                classLabel = classify(secondDict[key], labels, testVec)
            else: 
                classLabel = secondDict[key]
    return classLabel
"""
函数功能:对测试集进行预测,并返回预测后的结果
参数说明:
	train:训练集
	test:测试集
返回:
	test:预测好分类的测试集
"""
def acc_classify(train,test):
    inputTree = createTree(train)						#根据测试集生成一棵树
    labels = list(train.columns)						#数据集所有的列名称
    result = []
    for i in range(test.shape[0]):						#对测试集中每一条数据进行循环
        testVec = test.iloc[i,:-1]						#测试集中的一个实例
        classLabel = classify(inputTree,labels,testVec)	#预测该实例的分类
        result.append(classLabel)						#将分类结果追加到result列表中
    test['predict']=result								#将预测结果追加到测试集最后一列
    acc = (test.iloc[:,-1]==test.iloc[:,-2]).mean()		#计算准确率
    print(f'模型预测准确率为{acc}')
    return test 

测试函数:

train = dataSet
test = dataSet.iloc[:3,:]
acc_classify(train,test)

 2、使用SKlearn中graphviz包实现决策树的绘制:

#导入相应的包
from sklearn import tree
from sklearn.tree import DecisionTreeClassifier
import graphviz

#特征
Xtrain = dataSet.iloc[:,:-1]
#标签
Ytrain = dataSet.iloc[:,-1]
labels = Ytrain.unique().tolist()
Ytrain = Ytrain.apply(lambda x: labels.index(x))  #将本文转换为数字

#绘制树模型
clf = DecisionTreeClassifier()
clf = clf.fit(Xtrain, Ytrain)
tree.export_graphviz(clf)
dot_data = tree.export_graphviz(clf, out_file=None)
graphviz.Source(dot_data)

#给图形增加标签和颜色
dot_data = tree.export_graphviz(clf, out_file=None,
                                feature_names=['no surfacing', 'flippers'],
                                class_names=['fish', 'not fish'],
                                filled=True, rounded=True,
                                special_characters=True)
graphviz.Source(dot_data)

#利用render方法生成图形
graph = graphviz.Source(dot_data)
graph.render("fish")

 这样就实现了决策树的分类及展示了

你可能感兴趣的:(决策树,算法)