机器学习之决策树介绍

简介

什么是决策树

        决策树(Decision Tree)是在已知各种情况发生概率的基础上,通过构成决策树来求取净现值的期望值大于等于零的概率,评价项目风险,判断其可行性的决策分析方法,是直观运用概率分析的一种图解法。决策树(Decision Tree)有以下特点:

  1. 决策树是在已知各种情况发生概率的基础上,通过构建决策树来进行分析的一种方式,是一种直观应用概率分析的一种图解法;
  2. 决策树是一种预测模型,代表的是对象属性与对象值之间的映射关系;
  3. 决策树是一种树形结构,其中每个内部节点表示一个属性的测试,每个分支表示一个测试输出,每个叶节点代表一种类别;
  4. 决策树是一种非常常用的有监督的分类算法。

决策过程

        决策树的决策过程就是从根节点开始,测试待分类项中对应的特征属性,并按照其值选择输出分支,直到叶子节点,将叶子节点的存放的类别作为决策结果。

决策树分类

类别分类:分类树和回归树

        分类树用于分类标签值,回归树用于预测连续值。常用算法有ID3、C4.5、CART等

特征属性分类:离散型和连续型

构建决策树步骤

  1. 将所有的特征看成一个一个的节点;
  2. 遍历每个特征的每一种分割方式,找到最好的分割点;将数据划分为不同的子节点,eg: N1、N2…Nm;计算划分之后所有子节点的’纯度’信息;
  3. 对第二步产生的分割,选择出最优的特征以及最优的划分方式;得出最终的子节点: N1、N2…Nm
  4. 对子节点N1、N2…Nm分别继续执行2-3步,直到每个最终的子节点都足够’纯’。

在这里插入图片描述

决策树算法效果评估

决策树的损失函数

在这里插入图片描述
        loss值越小,算法效果越好!

决策树生成算法以及比较

ID3算法

简介

        ID3算法是决策树的一个经典的构造算法,内部使用信息熵以及信息增益来进行构建;每次迭代选择信息增益最大的特征属性作为分割属性。
在这里插入图片描述H(D):信息熵
Gain:某特征的信息增益

优缺点

优点缺点
1.决策树构建速度快;2.实现简单,易于理解1.计算依赖于特征数目较多的特征,而属性值最多的属性并不一定最优;2.ID3算法不是递增算法;3.ID3算法是单变量决策树;4.抗噪性差;5.只适合小规模数据集

C4.5算法

简介

        C4.5算法使用信息增益率来取代ID3算法中的信息增益,在树的构造过程中会进行剪枝操作进行优化;能够自动完成对连续属性的离散化处理;
在这里插入图片描述H(D):信息熵
Gain:某特征的信息增益
Gain_ratio(A):某特征的信息增益率

优缺点

优点缺点
1.易于理解;2.准确率较高;3.实现简单1.效率较低;2.只适合小规模数据集

CART(Classification And Regression Tree)

简介

        CART(Classification And Regression Tree,分类回归树)算法是使用GINI增益作为分割属性选择的标准,选择GINI增益最大的作为当前数据集的分割属性;可用于分类和回归两类问题。CART构建是二叉树
在这里插入图片描述

ID3、C4.5、CART分类树算法总结

  1. ID3和C4.5算法均只适合在小规模数据集上使用
  2. ID3和C4.5算法都是单变量决策树
  3. 当属性值取值比较多的时候,最好考虑C4.5算法,ID3得出的效果会比较差
  4. 决策树分类一般情况只适合小数据量的情况(数据可以放内存)
  5. CART算法是三种算法中最常用的一种决策树构建算法。
  6. 三种算法的区别仅仅只是对于当前树的评价标准不同而已,ID3使用信息增益、
  7. C4.5使用信息增益率、CART使用基尼系数。
  8. CART算法构建的一定是二叉树,ID3和C4.5构建的不一定是二叉树

决策树案例

构造相关数据特征

在这里插入图片描述

代码实现

这里使用的是ID3算法

from math import log
import operator

def calcShannonEnt(dataSet):  # 计算数据的熵(entropy)
    numEntries=len(dataSet)  # 数据条数
    labelCounts={}
    for featVec in dataSet:
        currentLabel=featVec[-1] # 每行数据的最后一个字(类别)
        if currentLabel not in labelCounts.keys():
            labelCounts[currentLabel]=0
        labelCounts[currentLabel]+=1  # 统计有多少个类以及每个类的数量
    shannonEnt=0
    for key in labelCounts:
        prob=float(labelCounts[key])/numEntries # 计算单个类的熵值
        shannonEnt-=prob*log(prob,2) # 累加每个类的熵值
    return shannonEnt

def createDataSet1():    # 创造示例数据
    dataSet = [['长', '粗', '男'],
               ['短', '粗', '男'],
               ['短', '粗', '男'],
               ['长', '细', '女'],
               ['短', '细', '女'],
               ['短', '粗', '女'],
               ['长', '粗', '女'],
               ['长', '粗', '女']]
    labels = ['头发','声音']  #两个特征
    return dataSet,labels

def splitDataSet(dataSet,axis,value): # 按某个特征分类后的数据
    retDataSet=[]
    for featVec in dataSet:
        if featVec[axis]==value:
            reducedFeatVec =featVec[:axis]
            reducedFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reducedFeatVec)
    return retDataSet

def chooseBestFeatureToSplit(dataSet):  # 选择最优的分类特征
    numFeatures = len(dataSet[0])-1
    baseEntropy = calcShannonEnt(dataSet)  # 原始的熵
    bestInfoGain = 0
    bestFeature = -1
    for i in range(numFeatures):
        featList = [example[i] for example in dataSet]
        uniqueVals = set(featList)
        newEntropy = 0
        for value in uniqueVals:
            subDataSet = splitDataSet(dataSet,i,value)
            prob =len(subDataSet)/float(len(dataSet))
            newEntropy +=prob*calcShannonEnt(subDataSet)  # 按特征分类后的熵
        infoGain = baseEntropy - newEntropy  # 原始熵与按特征分类后的熵的差值
        if (infoGain>bestInfoGain):   # 若按某特征划分后,熵值减少的最大,则次特征为最优分类特征
            bestInfoGain=infoGain
            bestFeature = i
    return bestFeature

def majorityCnt(classList):    #按分类后类别数量排序,比如:最后分类为2男1女,则判定为男;
    classCount={}
    for vote in classList:
        if vote not in classCount.keys():
            classCount[vote]=0
        classCount[vote]+=1
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortedClassCount[0][0]

def createTree(dataSet,labels):
    classList=[example[-1] for example in dataSet]  # 类别:男或女
    if classList.count(classList[0])==len(classList):
        return classList[0]
    if len(dataSet[0])==1:
        return majorityCnt(classList)
    bestFeat=chooseBestFeatureToSplit(dataSet) #选择最优特征
    bestFeatLabel=labels[bestFeat]
    myTree={bestFeatLabel:{}} #分类结果以字典形式保存
    del(labels[bestFeat])
    featValues=[example[bestFeat] for example in dataSet]
    uniqueVals=set(featValues)
    for value in uniqueVals:
        subLabels=labels[:]
        myTree[bestFeatLabel][value]=createTree(splitDataSet\
                            (dataSet,bestFeat,value),subLabels)
    return myTree


if __name__=='__main__':
    dataSet, labels=createDataSet1()  # 创造示列数据
    print(createTree(dataSet, labels))  # 输出决策树模型结果

输出结果

{'声音': {'细': '女', '粗': {'头发': {'短': '男', '长': '女'}}}}

结果说明:首先按声音分类,声音细为女生;然后再按头发分类:声音粗,头发短为男生;声音粗,头发长为女生。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值