Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >决策树分类鸢尾花数据集python实现

决策树分类鸢尾花数据集python实现

作者头像
kalifa_lau
发布于 2019-04-01 03:16:11
发布于 2019-04-01 03:16:11
1.3K01
代码可运行
举报
文章被收录于专栏:kalifaの日々kalifaの日々
运行总次数:1
代码可运行

代码行数230,由于每次执行代码选取的训练集不同,所以每次执行得到的正确率也不同,最好的情况是正确率达到83%。

特征值离散化的思路:

既然最终的分类是分成三种,那我猜测每个特征的取值也可以分成三个区间,那也就是求两个分割值。求分割值用双层for循环找使得信息熵最小的下标i和j。

代码整体思路:

1 . 先处理数据,shuffle函数随机抽取80%样本做训练集。 2 . 特征值离散化 3 . 用信息熵来递归地构造树 4 . 用构造好的树来判断剩下20%的测试集,求算法做分类的正确率

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# coding: utf-8

# In[1]:


from sklearn import datasets
import math
import numpy as np


# In[69]:


def getInformationEntropy(arr,leng):
    #print("length = ",leng)
    return -(arr[0]/leng*math.log(arr[0]/leng if arr[0]>0 else 1)+              arr[1]/leng*math.log(arr[1]/leng if arr[1]>0 else 1)+              arr[2]/leng*math.log(arr[2]/leng if arr[2]>0 else 1))

#informationEntropy = getInformationEntropy(num,length)
#print(informationEntropy)


# In[105]:


#离散化特征一的值
def discretization(index):
    
    feature1 = np.array([iris.data[:,index],iris.target]).T
    feature1 = feature1[feature1[:,0].argsort()]

    counter1 = np.array([0,0,0])
    counter2 = np.array([0,0,0])
    
    resEntropy = 100000
    for i in range(len(feature1[:,0])):

        counter1[int(feature1[i,1])] = counter1[int(feature1[i,1])] + 1
        counter2 = np.copy(counter1)

        for j in range(i+1,len(feature1[:,0])):

            counter2[int(feature1[j,1])] =  counter2[int(feature1[j,1])] + 1
            #print(i,j,counter1,counter2)
            #贪心算法求最优的切割点
            if i != j and j != len(feature1[:,0])-1:

                #print(counter1,i+1,counter2-counter1,j-i,np.array(num)-counter2,length-j-1)

                sum = (i+1)*getInformationEntropy(counter1,i+1) +                 (j-i)*getInformationEntropy(counter2-counter1,j-i) +                 (length-j-1)*getInformationEntropy(np.array(num)-counter2,length-j-1)
                if sum < resEntropy:
                    resEntropy = sum
                    res = np.array([i,j])
    res_value = [feature1[res[0],0],feature1[res[1],0]]
    print(res,resEntropy,res_value)
    return res_value
            


# In[122]:


#求合适的分割值
def getRazors():
    a = []
    for i in range(len(iris.feature_names)):
        print(i)
        a.append(discretization(i))

    return np.array(a)


# In[326]:


#随机抽取80%的训练集和20%的测试集
def divideData():
    completeData = np.c_[iris.data,iris.target.T]
    np.random.shuffle(completeData)
    trainData = completeData[range(int(length*0.8)),:]
    testData = completeData[range(int(length*0.8),length),:]
    return [trainData,testData]


# In[213]:


def getEntropy(counter):

    res = 0
    denominator = np.sum(counter)
    if denominator == 0:
        return 0
    for value in counter:
        if value == 0:
            continue
        res += value/denominator * math.log(value/denominator if value>0 and denominator>0 else 1)
    return -res



# In[262]:


def findMaxIndex(dataSet):
    maxIndex = 0
    maxValue = -1
    for index,value in enumerate(dataSet):
        if value>maxValue:
            maxIndex = index
            maxValue = value
    return maxIndex


# In[308]:


def recursion(featureSet,dataSet,counterSet):
    #print("函数开始,剩余特征:",featureSet,"  剩余结果长度:",len(dataSet))
    
    if(counterSet[0]==0 and counterSet[1]==0 and counterSet[2]!=0):
        return iris.target_names[2]
    if(counterSet[0]!=0 and counterSet[1]==0 and counterSet[2]==0):
        return iris.target_names[0]
    if(counterSet[0]==0 and counterSet[1]!=0 and counterSet[2]==0):
        return iris.target_names[1]
    
    if len(featureSet) == 0:
        return iris.target_names[findMaxIndex(counterSet)]
    if len(dataSet) == 0:
        return []
    
    res = 1000
    final = 0
    #print("剩余特征数目", len(featureSet))
    for feature in featureSet:
        i = razors[feature][0]
        j = razors[feature][1]
        #print("i = ",i," j = ",j)
        set1 = []
        set2 = []
        set3 = []
        counter1 = [0,0,0]
        counter2 = [0,0,0]
        counter3 = [0,0,0]
        for data in dataSet:
            index = int(data[-1])
            #print("data ",data," index ",index)
            
            if data[feature]< i :
                set1.append(data)
                counter1[index] = counter1[index]+1
            elif data[feature] >= i and data[feature] <=j:
                set2.append(data)
                counter2[index] = counter2[index]+1
            else:
                set3.append(data)
                counter3[index] = counter3[index]+1

        
        a =( len(set1)*getEntropy(counter1) +         len(set2)*getEntropy(counter2) +         len(set3)*getEntropy(counter3) )/ len(dataSet)
  
        #print("特征编号:",feature,"选取该特征得到的信息熵:",a)
        if a<res :
            res = a
            final = feature

    #返回被选中的特征的下标
    #sequence.append(final)
    #print("最终在本节点上选取的特征编号是:",final)        
    featureSet.remove(final)
    child = [0,0,0,0]
    child[0] = final
    child[1] = recursion(featureSet,set1,counter1)
    child[2] = recursion(featureSet,set2,counter2)
    child[3] = recursion(featureSet,set3,counter3)
    
    return child 

                 

# In[322]:



def judge(data,tree):

    root = "unknow"
    while(len(tree)>0):
        if isinstance(tree,str) and tree in iris.target_names:
            return tree
        root = tree[0]
        if(isinstance(root,str)):
            return root
        
        if isinstance(root,int):
            if data[root]<razors[root][0] and tree[1] != [] :
                tree = tree[1]
            elif tree[2] != [] and (tree[1]==[] or (data[root]>=razors[root][0] and data[root]<=razors[root][1])):
                tree = tree[2]
            else :
                tree = tree[3]
    return root            

# In[327]:


if __name__ == '__main__':
    
    iris = datasets.load_iris()
    num = [0,0,0]
    for row in iris.data:
        num[int(row[-1])] = num[int(row[-1])] + 1

    length = len(iris.target)
    [trainData,testData] = divideData()
    
    razors = getRazors()

    tree = recursion(list(range(len(iris.feature_names))),           trainData,[np.sum(trainData[:,-1]==0),            np.sum(trainData[:,-1]==1),np.sum(trainData[:,-1]==2)])
    print("本次选取的训练集构建出的树: ",tree)
    index = 0
    right = 0
    for data in testData:
        result = judge(testData[index],tree)
        truth = iris.target_names[int(testData[index][-1])]
                       
        print("result is ",result ,"  truth is ",truth)
        index = index + 1
        if result == truth:
            right = right + 1
    print("正确率 : ",right/index)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019.03.28 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Unity零基础到入门 ☀️| 学会这些Unity常用组件,Unity中必备组件技能学习!
⭐️组件Component ????前言 ????简介 ????Unity工程结构 ????几种常用组件介绍 ????Transform组件 ????Mesh Filter(网格过滤器)和Mesh R
呆呆敲代码的小Y
2021/08/20
3.3K0
Unity零基础到入门 ☀️| 学会这些Unity常用组件,Unity中必备组件技能学习!
Unity-UI(UGUI详解)01基础概念、自动布局、动画集成、富文本
Canvas应该包含全部UI元素,全部的UI元素应该时Canvas的子物体 调整元素的显示顺序可以从Hierarchy中直接拖拽他们,顺序从也可以被控制通过Scripting使用 SetAsFirstSibling, SetAsLastSibling, and SetSiblingIndex.这些方法。
祝你万事顺利
2019/07/18
2.5K0
Unity-UI(UGUI详解)01基础概念、自动布局、动画集成、富文本
Unity3D学习笔记(一)
1、解释 游戏对象(GameObjects)和 资源(Assets)的区别与联系。
梦飞
2022/06/23
9340
Unity3D学习笔记(一)
Unity3d:UGUI源码,Rebuild优化
Unity中渲染的物体都是由网格(Mesh)构成的,而网格的绘制单元是图元(点、线、三角面) 绘制信息都存储在Vertexhelper类中,除了顶点外,还包括法线、UV、颜色、切线。
立羽
2023/08/24
8410
Unity3D入门Demo-Cube移动-触发球体-切换场景[通俗易懂]
同样的操作方法,在 Hierarchy 面板下 右键Create Empty ,创建空的GameObject ,修改名称为 ChangeScenes。 如下图
全栈程序员站长
2022/09/22
1.4K0
Unity3D入门Demo-Cube移动-触发球体-切换场景[通俗易懂]
[学习笔记]unity3d-UGUI
简介 Unity 图形用户界面(unity Graphical User Interface) Unity4.6版本之后引入的界面显示系统 Unity公司自己研发的一套界面显示系统 UGUI和OnGUI、NGUI的区别 uGUI的Canavas有世界坐标和屏幕坐标 uGUI的Image可以使用material UGUI通过Mask来裁剪,而NGUI通过Panel的Clip NGUI的渲染前后顺序是通过Widget的Depth,而UGUI渲染顺序根据Hierarchy的顺序,越下面渲染在顶层。 UGUI不需要
六月丶
2022/12/26
3K0
[学习笔记]unity3d-UGUI
Unity-BattleStar丨5. 给BattleStar游戏添加UI
根据上篇文章内容,Meun的锚点要在Canvas中心,这样缩放屏幕时会保持相对位置不变
星河造梦坊官方
2024/08/14
1440
Unity-BattleStar丨5. 给BattleStar游戏添加UI
UGUI系列-实现层级菜单(Unity3D)
层级菜单在Unity中用到的并不多,主要是做分类的时候用的比较多,今天就给大家分享几个层级代码,扩充一下,写成插件也是不错的。
恬静的小魔龙
2022/08/07
1.9K0
UGUI系列-实现层级菜单(Unity3D)
一键完成对话需求?这款插件你不能错过(Unity3D)
Dialogue System是一个分支式的统一会话系统。它不需要任何脚本,但它是设计为易于由程序员扩展。
恬静的小魔龙
2022/08/07
5K0
一键完成对话需求?这款插件你不能错过(Unity3D)
UGUI系列-UI菜单列表,滑动展示UI(Unity3D)
&emsp; 大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧。
恬静的小魔龙
2022/08/07
7380
UGUI系列-UI菜单列表,滑动展示UI(Unity3D)
Unity-Optimizing Unity UI(UGUI优化)01 导航、Unity UI的基础概念与原理
摘要: 通过Unity UI优化用户的界面驱动是一门艺术,以下将讨论基本的概念、算法和在Unity UI相关代码
祝你万事顺利
2019/07/19
2.4K0
Unity3D 用对象创建对象
在 Unity3d 中会用到从一个游戏对象复制出一个新的游戏物体的方式,如制作射击游戏的子弹等。在 Unity3d 中可以使用 GameObject.Instantiate 的方式从一个 GameObject 里面创建一个和这个 GameObject 一样的对象
林德熙
2020/03/22
2.2K0
Unity ugui拖动控件(地图模式与物件模式)
拖动在游戏中使用频繁,例如将装备拖动到指定的快捷栏,或者大地图中拖动以查看局部信息等。
汐夜koshio
2020/05/19
1.6K0
Unity-UGUI
画布 Canvas 画布是摆放容纳所有的UI元素的区域,所有的UI元素需要在Canvas上组装。 Canvas 组件
祝你万事顺利
2019/05/29
8000
【Unity3d游戏开发】浅谈UGUI中的Canvas以及三种画布渲染模式
  Canvas画布是承载所有UI元素的区域。Canvas实际上是一个游戏对象上绑定了Canvas组件。所有的UI元素都必须是Canvas的自对象。如果场景中没有画布,那么我们创建任何一个UI元素,都会自动创建画布,并且将新元素置于其下。
马三小伙儿
2018/09/12
2.1K0
【Unity3d游戏开发】浅谈UGUI中的Canvas以及三种画布渲染模式
Unity3D学习笔记1——绘制一个三角形
最近想学习一下Unity3d,无奈发现现在大部分教程不仅是视频形式的,面对的也是美术、设计之类的非程序员,更多的时候都是把Unity3d当作PS一样的工具来用,真正面对程序开发的教程反而非常少,更不用说希望能研究到一些底层图形技术的技术工作者了。
charlee44
2021/06/29
1.4K0
unity3d:UGUI源码EventSystem输入系统常见问题
1.先是EventSystem在Update中调用当前输入模块InputModules的Process方法处理所有的鼠标事件, 2.并且输入模块会调用RaycastAll来得到目标信息, 3.通过子物体未挂载IEventSystemHandler,再找父物体方式找到事件实际接收者并执行点击事件
立羽
2023/08/24
6240
unity3d:UGUI源码EventSystem输入系统常见问题
Unity-UI(UGUI详解)02.2 Interaction组件、Auto Layout
此类是交互组件的基类 Property: Interactible:组件是否接受输入,当设置为false,组件将不可用 Transition:在可选组件中这又几个状态转换选项,其取决于选中的状态。不同的状态有:normal、highLighted、pressed和disabled Navigation:这又许多导航选项控制键盘的导航如何实现
祝你万事顺利
2019/07/18
2.2K0
Unity-UI(UGUI详解)02.2 Interaction组件、Auto Layout
【学习笔记】Unity3D官方游戏教程:Tanks Tutorial
2017-08-03 by Liuqingwen | Tags: Unity3D | Hits
IT自学不成才
2019/01/08
1.3K0
Unity3D学习笔记(四)分别使用IMGUI和UGUI实现血条的预制设计
思路:用HorizontalScrollbar(水平滚动条)的宽度作为血条的显示值。 直接上代码:
梦飞
2022/06/23
1.1K0
推荐阅读
相关推荐
Unity零基础到入门 ☀️| 学会这些Unity常用组件,Unity中必备组件技能学习!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验