决策树

决策树(Decision Tree)主要是用来处理分类问题,是最经常使用的数据挖掘算法之一。

决策树须知概念

指的是体系的混乱程度

信息熵(香农熵)是一种信息的度量方式,表示信息的混乱程度,信息越有序,熵越低。

信息增益:在划分数据集前后信息发生的变化称为信息增益

决策树工作原理:

决策树算法特点:

优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据。
缺点:可能会产生过度匹配问题。
适用数据类型:数值型和标称型。

'''
Created on 2019/6/6
Author: ZJ
'''
print(__doc__)
import operator
import decisionTreePlot as dtPlot
from math import log


#根据给定的数据集计算香农熵
def calcshannonEnt(dataSet):
    numEntries = len(dataSet)
    #统计每个标签出现的次数 使用字典保存
    labelCount = {}
    for i in dataSet:
        labelCount[i[-1]] = labelCount.get(i[-1],0) + 1
    #计算香农熵,香农熵越小越好
    shannonEnt = 0
    for key in labelCount:
        prob = float(labelCount[key]/numEntries)
        shannonEnt -= prob * log(prob,2)

    return shannonEnt

#划分数据集
def splitDataSet(dataSet,index,value):
    #就是依据index列进行分类,如果index列的数据等于 value的时候,就要将 index 划分到我们创建的新的数据集中
    retDataSet = []
    for feature in dataSet:
        temp = []
        if feature[index] == value:
            temp.extend(feature[:index])
            temp.extend(feature[index+1:])
            retDataSet.append(temp)

    return retDataSet

#选择最好的数据集划分方式,选择最好的特征,返回切割数据集最好的特征的列bestFeature
def chooseBestFeatureToSplit(dataSet):
    #特征的数目
    featurenum = len(dataSet[0]) - 1
    #label的原始香农熵
    baseEntropy = calcshannonEnt(dataSet)
    #最优的特征列数
    bestFeature = -1
    #最优的信息增益
    bestInfoGain = 0.0
    for  index in range(featurenum):
        featlist = [x[index] for x in dataSet]
        #将该特征的选项去重放到集合中
        uniqueVals = set(featlist)
        #临时信息熵
        newEntropy = 0.0
        for value in uniqueVals :
            #子数据集
            subDataSet = splitDataSet(dataSet,index,value)
            prob = len(subDataSet)/float(len(dataSet))
            newEntropy += prob*calcshannonEnt(subDataSet)

        #信息增益是熵的减少或者是数据无序度的减少。最后,比较所有特征中的信息增益,返回最好特征划分的索引值。
        infoGain = newEntropy - baseEntropy
        if bestInfoGain > infoGain:
            bestInfoGain = infoGain
            bestFeature = index

    return bestFeature

#选择出现次数最多的结果
def majorlabel(classList):
    majorCount = {}
    for i in classList:
        majorCount[i] = majorCount.get(i,0) + 1
    sortdeMajorCount = sorted(majorCount.items(),key = operator.itemgetter(1),reverser = True)
    return sortdeMajorCount[0][0]
    

#构建树的数据结构,返回构建好的决策树
def creatTree(dataSet,Labels):
    classList = [x[-1] for x in dataSet]
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    
    #用完了所有的特征仍然不能正常分类,那么就选label出现次数最多的标签
    if len(dataSet[0]) == 1:
        return majorlabel(classList)
    #得到最好的特征列
    bestFeature = chooseBestFeatureToSplit(dataSet)
    #该特征列的label名称
    bestLabel = Labels[bestFeature]
    #删除该名称从Labels中
    del Labels[bestFeature]
    myTree = {bestLabel:{}}
    #取出特征列,构建选项集合
    featValues = [x[bestFeature] for x in dataSet]
    uniqueVals = set(featValues)

    for i in uniqueVals:
        subLabels = Labels[:]
        myTree[bestLabel][i] = creatTree(splitDataSet(dataSet,bestFeature,i),subLabels)

    return myTree

#分类
def classify(inputTree,labels,testVec):
    '''
    inputTree 训练好的决策树模型
    labels 特征标签对应的标签名称
    testVec 测试向量
    '''
    #得到根节点  root为特征的label
    root = list(inputTree.keys())[0]
    #得到根节点对应的value字典
    valuedict = inputTree[root]
    featIndex = labels.index(root)
    key = testVec[featIndex]
    valueOfFeat = valuedict[key]
    print('+++', root, 'xxx', valuedict, '---', key, '>>>', valueOfFeat)
    if isinstance(valueOfFeat,dict):
        classify(valueOfFeat,labels,testVec)
    else:
        classifier = valueOfFeat

    return classifier


def ContactLensesTest():
    """
    Desc:
        预测隐形眼镜的测试代码,并将结果画出来
    Args:
        none
    Returns:
        none
    """

    # 加载隐形眼镜相关的 文本文件 数据
    fr = open('../data/DecisionTree/lenses.txt')
    # 解析数据,获得 features 数据
    lenses = [inst.strip().split('\t') for inst in fr.readlines()]
    # 得到数据的对应的 Labels
    lensesLabels = ['age', 'prescript', 'astigmatic', 'tearRate']
    # 使用上面的创建决策树的代码,构造预测隐形眼镜的决策树
    lensesTree = creatTree(lenses, lensesLabels)
    print(lensesTree)
    dtPlot.createPlot(lensesTree)

        

if __name__ == "__main__":
    ContactLensesTest()
Created on 2019/6/6
Author: ZJ

{'tearRate': {'normal': {'astigmatic': {'no': {'age': {'presbyopic': {'prescript': {'hyper': 'soft', 'myope': 'no lenses'}}, 'pre': 'soft', 'young': 'soft'}}, 'yes': {'prescript': {'hyper': {'age': {'presbyopic': 'no lenses', 'pre': 'no lenses', 'young': 'hard'}}, 'myope': 'hard'}}}}, 'reduced': 'no lenses'}}
决策树图
隐形眼镜决策树

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值