代码.py文件下载地址:https://download.csdn.net/download/u012421852/10323938
如何设置免费下载,每次最少需要设置2C币下载,不是故意不免费提供.py文件,ε=(´ο`*)))唉
1.需求说明
在生成样本集的决策树过程中,在得到树根节点后,后面还需要选择子树的根节点,这时候不能使用前面的样本集了,需要将已选作根节点的样本特征从样本集中裁减掉,为了便于理解,下面举例说明:
样本特征列表: feature_type_list = ['youth','work','house','credit'] 样本集: samples_list = [ ['youth', 'work_no', 'house_no', '1', 'refuse'] ['youth', 'work_no', 'house_no', '2', 'refuse'] ['youth', 'work_yes', 'house_no', '2', 'agree'] ['youth', 'work_yes', 'house_yes', '1', 'agree'] ['youth', 'work_no', 'house_no', '1', 'refuse'] ['mid', 'work_no', 'house_no', '1', 'refuse'] ['mid', 'work_no', 'house_no', '2', 'refuse'] ['mid', 'work_yes', 'house_yes', '2', 'agree'] ['mid', 'work_no', 'house_yes', '3', 'agree'] ['mid', 'work_no', 'house_yes', '3', 'agree'] ['elder', 'work_no', 'house_yes', '3', 'agree'] ['elder', 'work_no', 'house_yes', '2', 'agree'] ['elder', 'work_yes', 'house_no', '2', 'agree'] ['elder', 'work_yes', 'house_no', '3', 'agree'] ['elder', 'work_no', 'house_no', '1', 'refuse'] ]
已经通过信息增益选出此样本集的决策树的最优根节点为特征house。
现在要选则子树的最优根节点,则需要更新样本集和样本特征列表。
需要将已选作根节点的样本特house征从样本集以及特征列表中裁减掉
通过如下规则得到新的样本集
step1:删除特征列表中的house new_feature_type_list = ['youth','work','house','credit'] step2:删除hourse特征值为house_yes所在的所有行并删除样本集中house特征值列 new_samples_list = [ ['youth', 'work_no', '1', 'refuse'] ['youth', 'work_no', '2', 'refuse'] ['youth', 'work_yes', '2', 'agree'] ['youth', 'work_no', '1', 'refuse'] ['mid', 'work_no', '1', 'refuse'] ['mid', 'work_no', '2', 'refuse'] ['elder', 'work_yes', '2', 'agree'] ['elder', 'work_yes', '3', 'agree'] ['elder', 'work_no', '1', 'refuse'] ]
本章的代码就是实现以上样本集的裁剪和特征列表的裁剪,供子决策树的根节点选择使用
2.代码
说明:裁剪工作主要由def tailer_work(self)方法来完成~~
# -*- coding: utf-8 -*- """ @author: 蔚蓝的天空Tom Aim:在决策树种,在得到一个树根节点后,需要选择子树的根节点,这时候就需要对样本集进行裁剪 Aim:裁剪规则详见下面 """ import numpy as np '''Tool Function''' 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: print(src_a) print('======\n') return def print_dict(self, src_dict, level, src_dict_namestr=''): ''' 逐行打印dict :param self:类实例自身 :param src_dict:被打印的dict :param level:递归level,初次调用为level=0 :param src_dict_namestr:对象变量名称字符串 ''' if isinstance(src_dict, dict): tab_str = '\t' for i in range(level): tab_str += '\t' if 0 == level: print(src_dict_namestr,'= {') for key, value in src_dict.items(): if isinstance(value, dict): has_dict = False for k,v in value.items(): if isinstance(v, dict): has_dict = True if has_dict: print(tab_str,key,":{") self.print_dict(value, level + 1) else: print(tab_str,key,':',value) else: print(tab_str,key,': ',value,) print(tab_str,'}') def dump_dict(self, src_dict, src_dict_namestr): ''' 逐行打印dict :param self:类实例自身 :param src_dict:被打印的dict对象 :return 无 ''' print('\n===============',src_dict_namestr,'===================') dict_len = len(src_dict) dict_shape = np.shape(src_dict) dict_type = type(src_dict) print('len(',src_dict_namestr,'):',dict_len) print('type(',src_dict_namestr,'):', dict_type) #<class 'dict'> print('np.shape(',src_dict_namestr,'):', dict_shape) print('len(dict_shape):', len(dict_shape)) self.print_dict(src_dict, 0, src_dict_namestr) print('======\n') return def dump(self, src_thing, src_thing_namestr): ''' 逐行打印变量(list, array, matrix等) :param self:类实例自身 :param src_things:被打印者 :return 无 ''' if isinstance(src_thing, list): return self.dump_list(src_thing, src_thing_namestr) elif isinstance(src_thing, np.ndarray): return self.dump_array(src_thing, src_thing_namestr) elif isinstance(src_thing, dict): return self.dump_dict(src_thing, src_thing_namestr) else: print(src_thing_namestr,':', src_thing) return #=========================================== ''' 裁剪规格简介 #每个样本example的特征列表 feature_type_list = ['youth','work','hourse','credit'] 即每个样本=[age_value, work_value, housr_value, crdit_value, class_label] 如下一个样本集: samples_list = [ ['youth', 'work_no', 'house_no', '1', 'refuse'] ['youth', 'work_no', 'house_no', '2', 'refuse'] ['youth', 'work_yes', 'house_no', '2', 'agree'] ['youth', 'work_yes', 'house_yes', '1', 'agree'] ['youth', 'work_no', 'house_no', '1', 'refuse'] ['mid', 'work_no', 'house_no', '1', 'refuse'] ['mid', 'work_no', 'house_no', '2', 'refuse'] ['mid', 'work_yes', 'house_yes', '2', 'agree'] ['mid', 'work_no', 'house_yes', '3', 'agree'] ['mid', 'work_no', 'house_yes', '3', 'agree'] ['elder', 'work_no', 'house_yes', '3', 'agree'] ['elder', 'work_no', 'house_yes', '2', 'agree'] ['elder', 'work_yes', 'house_no', '2', 'agree'] ['elder', 'work_yes', 'house_no', '3', 'agree'] ['elder', 'work_no', 'house_no', '1', 'refuse'] ] 假设已经通过信息增益选出此样本集的决策树的最优根节点为特征housre 如果想求子决策树的最优根节点的话,就需要对原始样本集进行裁剪了,然后用新的样本集筛选新的最优根节点 #通过如下规则得到新的样本集 step1:删除hourse特征值为house_yes所在的所有行 step2:然后再删除hourse特征值列 ''' class CTailorSamples(object): '''裁剪样本集''' def __init__(self, data_list, feat_type_list, feat_type_index, feat_value): self.data_list = data_list self.feat_type_list = feat_type_list self.feat_type_index_tailed = feat_type_index self.feat_value_tailed = feat_value #裁剪 self.tailer_work() def get_samples(self): ''' 返回裁剪后的样本集,特征类型列表 ''' return self.data_list, self.feat_type_list def get_all_indexs(self, src_list, dst_value): ''' 返回给定值的所有元素的下标 src_list = [10,20,30,30,30,50] e = 30 indexs_list = tailor.get_all_indexs(src_list, e) print(indexs_list) #[2, 3, 4] ''' dst_val_index = [i for i,x in enumerate(src_list) if x == dst_value] return dst_val_index def tailer_work(self): '''裁剪得到新的特征列表''' del self.feat_type_list[self.feat_type_index_tailed] '''裁剪数据集''' #摘取被删除的特征列 colum_to_del = self.feat_type_index_tailed self.feat_value_list = [example[colum_to_del] for example in self.data_list] #找出含有self.feat_value_tailed特征值的所有样本所在行的下标 rows_to_del = self.get_all_indexs(self.feat_value_list, self.feat_value_tailed) #删除row_index_list中行下标对应的self.src_data_list的行 #技巧:从大的行下标开始依次删除 #for row in list(reversed(rows_to_del)): #for row in rows_to_del[::-1]: rows_to_del.reverse() for row in rows_to_del: del self.data_list[row] #删除给定的特征列 for row in range(len(self.data_list)): del self.data_list[row][colum_to_del] return self.data_list, self.feat_type_list #测试&使用步骤展示 def CTailorSamples_manual(): #样本集 data_list = [['youth', 'work_no', 'house_no', '1', 'refuse'], ['youth', 'work_no', 'house_no', '2', 'refuse'], ['youth', 'work_yes', 'house_no', '2', 'agree'], ['youth', 'work_yes', 'house_yes', '1', 'agree'], ['youth', 'work_no', 'house_no', '1', 'refuse'], ['mid', 'work_no', 'house_no', '1', 'refuse'], ['mid', 'work_no', 'house_no', '2', 'refuse'], ['mid', 'work_yes', 'house_yes', '2', 'agree'], ['mid', 'work_no', 'house_yes', '3', 'agree'], ['mid', 'work_no', 'house_yes', '3', 'agree'], ['elder', 'work_no', 'house_yes', '3', 'agree'], ['elder', 'work_no', 'house_yes', '2', 'agree'], ['elder', 'work_yes', 'house_no', '2', 'agree'], ['elder', 'work_yes', 'house_no', '3', 'agree'], ['elder', 'work_no', 'house_no', '1', 'refuse']] #样本特征列表 feat_type_list = ['age', 'working', 'house', 'credit'] #需求1)删除dataSet中含有house_yes的所有样本行 feat_value_to_del = 'house_yes' #需求2)以及删除dataSet中的house特征列 #需求3)以及删除样本特征列表中的特征'house' feat_type_index = feat_type_list.index('house') #创建裁剪类CTailorSamples的实例 tailor = CTailorSamples(data_list, feat_type_list, feat_type_index, feat_value_to_del) #获取裁剪后的样本集,样本特征列表 new_data_list, new_feat_type_list = tailor.get_samples() #打印显示验证,看看是否裁剪正确 tool = CUtileTool() tool.dump(new_data_list, 'new_data_list') tool.dump(new_feat_type_list,'new_feat_type_list') if __name__=='__main__': CTailorSamples_manual()
3.执行结果
============ new_data_list ================ type( new_data_list ): <class 'list'> np.shape( new_data_list ): (9, 4) [ ['youth', 'work_no', '1', 'refuse'] ['youth', 'work_no', '2', 'refuse'] ['youth', 'work_yes', '2', 'agree'] ['youth', 'work_no', '1', 'refuse'] ['mid', 'work_no', '1', 'refuse'] ['mid', 'work_no', '2', 'refuse'] ['elder', 'work_yes', '2', 'agree'] ['elder', 'work_yes', '3', 'agree'] ['elder', 'work_no', '1', 'refuse'] ] ====== ============ new_feat_type_list ================ type( new_feat_type_list ): <class 'list'> np.shape( new_feat_type_list ): (3,) ['age', 'working', 'credit'] ======
enjoy it~
(end)