当前位置: 首页 > news >正文

使用决策树预测隐形眼镜类型

1、算法思想:从根节点开始,对实例的某一特征进行测试,根据测试结果将实例分配到其子节点;每一个子节点对应着该特征的一个取值。如此递归地对实例进行测试并分配,直至达到叶节点。最后将实例分配到叶节点的类中。

    k近邻算法可以完成多分类任务,缺点是无法给出数据的内在含义,决策树的主要优势在于数据形式容易理解

 2、伪代码:

      思路是:如果某个分支下的数据属于同一类型,则无需分割 返回类标签;如果数据子集的数据不属于同一类型,则需要重复划分数据子集,直到相同类型的数据在同一个数据子集内。

3、度量数据集的无须程度

    划分数据集的原则是将无序的数据变得有序,集合信息的度量方式称为香农熵

  

   熵越高 混合的数据越多,得到熵之后就可以按照最大信息增益的方法划分数据集

   测量信息熵-划分的数据集-度量划分数据集的熵

   代码如下:

# -*- coding: utf-8 -*-

from math import log
import operator
#创建数据集
def createDataSet():
    dataSet = [[1, 1, 'yes'],
               [1, 1, 'yes'],
               [1, 0, 'no'],
               [0, 1, 'no'],
               [0, 1, 'no']]
    labels = ['no surfacing','flippers']
    return dataSet, labels
#计算香农熵
def calcShannonEnt(dataSet):
    numEntries = len(dataSet)
    labelCounts = {}    #字典
    for featVec in dataSet:  #the the number of unique elements and their occurance
        currentLabel = featVec[-1]
        if currentLabel not in labelCounts.keys(): 
            labelCounts[currentLabel] = 0
        labelCounts[currentLabel] += 1
    shannonEnt = 0.0
    for key in labelCounts:
        #字典的运用,dict[key]=value
        prob = float(labelCounts[key])/numEntries
        shannonEnt -= prob * log(prob,2)   #log base 2
    return shannonEnt
#划分数据集
def splitDataSet(dataSet,axis,value):
    retDataSet=[]
    for featVec in dataSet:
        if featVec[axis]==value:
            reduceFeatVec=featVec[:axis]
            reduceFeatVec.extend(featVec[axis+1:])
            retDataSet.append(reduceFeatVec)  
            #append() 向列表尾部追加一个新元素,列表只占一个索引位,在原有列表上增加,如果处理对象是列表 则将整个列表作为一个元素添加
            #extend() 向列表尾部追加一个列表,将列表中的每个元素都追加进来,在原有列表上增加
    return retDataSet
#选择最好的数据集划分方式
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0])-1   #特征的个数
    bestEntroy = calcShannonEnt(dataSet)   #entroy熵,初始值设为数据集的熵
    bestInfoGain = 0.0   #信息增益初始值
    bestFeature = -1
    for i in range(numFeatures):
        featureList = [example[i] for example in dataSet] #第i个特征所有的取值
        uniqueVals = set(featureList)  #去重,set表示集合 集合的特点是每个值互不相同 从列表中创建集合可以得到列表中的唯一元素值
        newEntropy = 0.0
        for value in uniqueVals: #对每一种唯一属性划分数据集
            subDataSet = splitDataSet(dataSet,i,value)   
            prob = len(subDataSet)/float(len(subDataSet))
            newEntropy += prob * calcShannonEnt(subDataSet)  ##每种划分方式经验条件熵的和
        infoGain = bestEntroy - newEntropy  ##信息增益
        if infoGain > bestInfoGain:
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature
#多数表决规则
def majorityCnt(classList):
    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):
    #将dataSet中最后一列的元素(也就是类标签)放入到classList列表中
    classList = [example[-1] for example in dataSet]
    # count()方法用于统计字符串里某个字符出现的次数  
    #若相等表示List中的标签属于同一列别
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    # len()方法返回字符串长度或者列表元素个数
    #表示只有类别列,没有属性列
    if len(dataSet[0])==1:
        #多数表决原则 返回出现次数最多的列别
        return mahorityCnt(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
#--------------以上完成了决策树的构建----------------
#--------------以下的是使用决策树分类----------------  
#完成决策树的构造后,采用决策树实现具体应用
def classify(inputTree,featLabels,testVec):
    #找到树的第一个分类特征,或者说根节点'no surfacing'
    #注意python2和3区别,2可写成firstStr=inputTree.keys()[0] 而不支持3
    firstStr=list(inputTree.keys())[0]
    #从树中得到该分类特征的分支,有0和1
    secondDict=inputTree[firstStr]
    #根据分类特征的索引找到对应的标称型数据值
    #'no surfacing'对应的索引为0
    featIndex=featLabels.index(firstStr)
    #遍历分类特征所有的取值
    for key in secondDict.keys():
        #测试实例的第0个特征取值等于第key个子节点
        if testVec[featIndex]==key:
            #type()函数判断该子节点是否为字典类型
            if type(secondDict[key]).__name__=='dict':
                #子节点为字典类型,则从该分支树开始继续遍历分类
                classLabel=classify(secondDict[key],featLabels,testVec)
            #如果是叶子节点,则返回节点取值
            else: 
                classLabel=secondDict[key]
    return classLabel
#--------------决策树的存储----------------
#构造决策树好费时间,因此可以将构造好的决策树存储起来下次直接用
#决策树的存储:python的pickle模块序列化决策树对象,使决策树保存在磁盘中
def storeTree(inputTree,filename):
    #导入pickle模块
    import pickle
    #创建一个可以'写'的文本文件
    #pickle存储方式默认是二进制方式
    #这里,如果按树中写的'w',将会报错write() argument must be str,not bytes
    #所以这里改为二进制写入'wb'
    fw=open(filename,'wb')
    #pickle的dump函数将决策树写入文件中
    pickle.dump(inputTree,fw)
    #写完成后关闭文件
    fw.close()
#取决策树操作    
def grabTree(filename):
    import pickle
    #对应于二进制方式写入数据,'rb'采用二进制形式读出数据
    fr=open(filename,'rb')
    return pickle.load(fr)
#--------------示例:使用决策树预测隐形眼镜类型----------------
def predictLensesType(filename):
    #打开文本数据
    fr=open(filename)
    #将文本数据的每一个数据行按照tab键分割,并依次存入lenses
    lenses=[inst.strip().split('\t') for inst in fr.readlines()]
    #创建并存入特征标签列表
    lensesLabels=['age','prescript','astigmatic','tearRate']
    #根据继续文件得到的数据集和特征标签列表创建决策树
    lensesTree=createTree(lenses,lensesLabels)
    return lensesTree

def test():
    myData, labels = createDataSet()
    myTree = createTree(myData, labels)
    # 再创建一次数据的原因是创建决策树函数会将labels值改动
    myData, labels = createDataSet()
    print (classify(myTree, labels, [1,1]))


# 主方法
if __name__ == "__main__":
    myData,labels=tree.createDataSet()
    myTree=tree.createTree(myData,labels)
    print (myTree)

 

转载于:https://www.cnblogs.com/Aaron12/p/8883209.html

相关文章:

  • 致远a8-v5-6.0协同管理软件_易达酒吧管理软件下载-易达酒吧管理软件v10.0免费版...
  • 如何让你产品的用户拥有一流的上传体验
  • fedora如何隐藏顶部状态栏_装修冷知识 厨房管道怎么隐藏?
  • 感悟
  • 2020cf自动准备怎么用_天天都在用的转向灯是怎么自动回位的?
  • 第一学期《计算机网络》作业一_【实用】新学期学习计划范文九篇
  • linux下创建普通用户并赋予某个目录的读写权限
  • 第六周小组作业:软件测试和评估
  • 在matlab上利用fft进行信号频谱分析_MATLAB下使用fft进行频域分析
  • 如何确定电脑主板坏了_维修变频器的前景如何?
  • HashMap的实现原理
  • 小米id锁状态查询_揭秘:苹果隐藏ID到底是什么?你可能就被坑了!
  • 典型系统~广告系统和记数系统(转)
  • rexrothnbsp;vfc36_Rexroth工业液压4.0趋势:I/O Link中的执行器和传感器
  • 证明利用快慢指针寻找有环单链表中环的起点算法
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 4个实用的微服务测试策略
  • ES6核心特性
  • hadoop集群管理系统搭建规划说明
  • iOS仿今日头条、壁纸应用、筛选分类、三方微博、颜色填充等源码
  • java多线程
  • npx命令介绍
  • PAT A1092
  • PHP 小技巧
  • unity如何实现一个固定宽度的orthagraphic相机
  • 创建一种深思熟虑的文化
  • 反思总结然后整装待发
  • 关于字符编码你应该知道的事情
  • 算法之不定期更新(一)(2018-04-12)
  • 通过git安装npm私有模块
  • 智能合约Solidity教程-事件和日志(一)
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • #设计模式#4.6 Flyweight(享元) 对象结构型模式
  • (9)目标检测_SSD的原理
  • (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (原創) 如何使用ISO C++讀寫BMP圖檔? (C/C++) (Image Processing)
  • .describe() python_Python-Win32com-Excel
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET 依赖注入和配置系统
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • @html.ActionLink的几种参数格式
  • [ CTF ] WriteUp- 2022年第三届“网鼎杯”网络安全大赛(白虎组)
  • [Android 数据通信] android cmwap接入点
  • [C/C++]数据结构 堆的详解
  • [CERC2017]Cumulative Code
  • [Flutter]WindowsPlatform上运行遇到的问题总结
  • [HCTF 2018]WarmUp (代码审计)
  • [HTML]Web前端开发技术28(HTML5、CSS3、JavaScript )JavaScript基础——喵喵画网页
  • [Leetcode] 寻找数组的中心索引
  • [LeetCode]-225. 用队列实现栈
  • [NAND Flash 6.4] NAND FLASH基本读操作及原理_NAND FLASH Read Operation源码实现
  • [PAT练级笔记] 44 Basic Level 1044 火星数字
  • [SpringCloud] OpenFeign核心架构原理 (一)