【机器学习】【决策树】ID3算法,Python代码实现生成决策树的系统

除了绘制树部分代码有借鉴,其他代码都是自己亲手完成,历时2天时间,过程稍微痛苦,当看到运行结果出现在面前时,一切都是高兴的,感觉过程也变得美妙了~

由于更喜欢C++编程,所以使用python类来完成~~~~,个人感觉面向对象更容易和更适合实现生成决策树的软件系统

由于是代码的第一稿,还没有精简,比较长,所以先贴出来运行结果,再给出代码

此软件系统:可以指定决策树的深度

1.使用的样本集

    ''''' 
    提供训练样本集 
     
    每个example由多个特征值+1个分类标签值组成 
    比如第一个example=['youth', 'no', 'no', '1', 'refuse'],此样本的含义可以解读为: 
    如果一个人的条件是:youth age,no working, no house, 信誉值credit为1 
    那么此类人会被分类到refuse一类中,即在相亲中被拒绝 
     
    每个example的特征值类型为: 
    ['age', 'working', 'house', 'credit'] 
     
    每个example的分类标签class_label取值范围为:'refuse'或者'agree' 
    '''  
    data_list = [['youth', 'no',  'no',   '1', 'refuse'],  
                 ['youth', 'no',  'no',   '2', 'refuse'],  
                 ['youth', 'yes', 'no',   '2', 'agree'],  
                 ['youth', 'yes', 'yes',  '1', 'agree'],  
                 ['youth', 'no',  'no',   '1', 'refuse'],  
                 ['mid',   'no',  'no',   '1', 'refuse'],  
                 ['mid',   'no',  'no',   '2', 'refuse'],  
                 ['mid',   'yes', 'yes',  '2', 'agree'],  
                 ['mid',   'no',  'yes',  '3', 'agree'],  
                 ['mid',   'no',  'yes',  '3', 'agree'],  
                 ['elder', 'no',  'yes',  '3', 'agree'],  
                 ['elder', 'no',  'yes',  '2', 'agree'],  
                 ['elder', 'yes', 'no',   '2', 'agree'],  
                 ['elder', 'yes', 'no',   '3', 'agree'],  
                 ['elder', 'no',  'no',   '1', 'refuse']]  
    feat_list = ['age', 'working', 'house', 'credit']  

2. 运行得到的样本集的决策树

=============== samples decision-tree dict ===================

len( samples decision-tree dict ): 1

type( samples decision-tree dict ): <class 'dict'>
np.shape( samples decision-tree dict ): ()
len(dict_shape): 0
samples decision-tree dict = {
         house :{
                 no :{
                         working :{
                                 no :{
                                         age : {'elder': 'refuse', 'youth': 'refuse'}
                                         }
                                 yes :  agree
                                 }
                         }
                 yes :  agree
                 }
         }
======

绘制的决策树图形


总上面可以看到,当决策树在age特征节点时,age的子节点都是refuse,说明此人不管什么年龄,都会被决绝,很容易知道age节点在决策树中没有任何意义,完全可以将working特征值=no时的子节点设置为refuse,下面我们对决策树的生成终止条件重新设置后,再看得到的决策树。设置leastFeatNum=4,上面决策树是leastFeatNum=3时生成的。

    #决策树生成终止的条件,当样本的特征少于leastFeatNum个时,不再继续求样本集的决策树
    leastFeatNum = 3
    #创建ID3算法生成决策树类的对象
    samples = CID3DecisionTree(train_data_list, feat_list, leastFeatNum)
    #生成决策树字典
    samples.create_tree()

leastFeatNum=4时,得到的决策树字典和绘制图形如下所示:

=============== samples decision-tree dict ===================
len( samples decision-tree dict ): 1
type( samples decision-tree dict ): <class 'dict'>
np.shape( samples decision-tree dict ): ()
len(dict_shape): 0
samples decision-tree dict = {
         house :{
                 no :{
                         working : {'no': 'refuse', 'yes': 'agree'}
                         }
                 yes :  agree
                 }
         }

======


可以看到,此时决策树更简洁更效率~

3.代码

# -*- coding: utf-8 -*-  
""" 
@author: 蔚蓝的天空Tom 
Talk is cheap,show me the code 
Aim:ID3算法生成决策树(字典存储), 并绘制决策树图形
"""  

import numpy as np  
import math
import matplotlib.pyplot as plt
varnamestr = lambda v,nms: [ vn for vn in nms if id(v)==id(nms[vn])][0]  
class CUtileTool(object):  
    '''提供有用的方法 比如dump_list方法,可以打印给定的list的相关信息'''  
    def dump_list(self, src_list, src_list_namestr):  
        '''逐行打印list 
        :param self:类实例自身 
        :param src_list:被打印的源list 
        :return 无 
        '''  
        print('\n============',src_list_namestr,'================')  
        list_len = len(src_list)  
        list_shape = np.shape(src_list)  
        print('type(',src_list_namestr,'):',type(src_list))  #<class 'list'>  
        print('np.shape(',src_list_namestr,'):',np.shape(src_list))  
        if 1 == len(list_shape):  
            print(src_list)  
        elif 2 == len(list_shape):  
            for i in range(list_len):  
                if 0 == i:  
                    print('[',src_list[i])  
                elif (list_len - 1) == i:  
                    print(src_list[i],']')  
                else:  
                    print(src_list[i])  
        else:  
            print(src_list)  
        print('======\n')  
        return  
   
    def dump_array(self, src_a, src_dict_namestr):  
        ''''' 
        逐行打印array 
        :param self:类实例自身 
        :param src_a:被打印的源array 
        :return 无 
        '''  
        print('\n===============',src_dict_namestr,'===================')  
        a_len = len(src_a)  
        a_shape = np.shape(src_a)  
        print('type(',src_dict_namestr,'):',type(src_a))  #<class 'list'>  
        print('np.shape(',src_dict_namestr,'):',np.shape(src_a))  
        if 1 == len(a_shape):  
            print(src_a)  
        elif 2 == len(a_shape):  
            for i in range(a_len):  
                if 0 == i:  
                    print('[',src_a[i])  
                elif (a_len - 1) == i:  
                    print(src_a[i],']')  
                else:  
                    print(src_a[i])  
        else:  
        
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值