机器学习决策树(ID3)算法及案例腾讯云开发者社区

决策树是一个预测模型。它代表的是对象属性与对象值之间的一种映射关系。树中每个节点表示某个对象,每个分支路径代表某个可能的属性值,每个叶结点则对应从根节点到该叶节点所经历的路径所表示的对象的值。一般情况下,决策树由决策结点、分支路径和叶结点组成。在选择哪个属性作为结点的时候,采用信息论原理,计算信息增益,获得最大信息增益的属性就是最好的选择。信息增益是指原有数据集的熵减去按某个属性分类后数据集的熵所得的差值。然后采用递归的原则处理数据集,并得到了我们需要的决策树。

2

算法流程

检测数据集中的每个子项是否属于同一分类:

If是,则返回类别标签;

Else

计算信息增益,寻找划分数据集的最好特征

划分数据数据集

创建分支节点(叶结点或决策结点)

for每个划分的子集

递归调用,并增加返回结果到分支节点中

return分支结点

算法的基本思想可以概括为:

1)树以代表训练样本的根结点开始。

2)如果样本都在同一个类.则该结点成为树叶,并记录该类。

3)否则,算法选择最有分类能力的属性作为决策树的当前结点.

4)根据当前决策结点属性取值的不同,将训练样本根据该属性的值分为若干子集,每个取值形成一个分枝,有几个取值形成几个分枝。匀针对上一步得到的一个子集,重复进行先前步骤,递归形成每个划分样本上的决策树。一旦一个属性只出现在一个结点上,就不必在该结点的任何后代考虑它,直接标记类别。

5)递归划分步骤仅当下列条件之一成立时停止:

①给定结点的所有样本属于同一类。

②没有剩余属性可以用来进一步划分样本.在这种情况下.使用多数表决,将给定的结点转换成树叶,并以样本中元组个数最多的类别作为类别标记,同时也可以存放该结点样本的类别分布[这个主要可以用来剪枝]。

③如果某一分枝tc,没有满足该分支中已有分类的样本,则以样本的多数类生成叶子节点。

算法中2)步所指的最优分类能力的属性。这个属性的选择是本算法种的关键点,分裂属性的选择直接关系到此算法的优劣。

一般来说可以用比较信息增益和信息增益率的方式来进行。

其中信息增益的概念又会牵扯出熵的概念。熵的概念是香农在研究信息量方面的提出的。它的计算公式是:

Info(D)=-p1log(p1)/log(2.0)-p2log(p2)/log(2.0)-p3log(p3)/log(2.0)+...-pNlog(pN)/log(2.0)(其中N表示所有的不同类别)

而信息增益为:

Gain(A)=Info(D)-Info(Da)其中Info(Da)数据集在属性A的情况下的信息量(熵)。

3

算法的特点

缺点:可能会产生过度匹配问题

适用数据范围:数值型和标称型。

4

python代码实现

1、创建初始数据集,用于测试

#######################################功能:创建数据集#输入变量:空#输出变量:data_set,labels数据集,标签######################################defcreate_data_set():

returndata_set,labels

2、计算给定数据集的信息熵

##############################功能:计算信息熵#输入变量:data_set数据集#输出变量:shannon_ent信息熵#############################defcalc_shannon_ent(data_set):

num_entries=len(data_set)label_counts={}

forfeat_vecindata_set:current_label=feat_vec[-1]#get相当于一条if...else...语句#如果参数current_label不在字典中则返回参数0,#如果current_label在字典中则返回current_label对应的value值label_counts[current_label]=label_counts.get(current_label,0)+1

shannon_ent=0.0

forkeyinlabel_counts:prob=float(label_counts[key])/num_entriesshannon_ent-=prob*log(prob,2)

returnshannon_ent

3、按照给定特征划分数据集。分类算法除了需要测量信息熵,还需要划分数据集,这就需要对每个特征划分数据集的结果计算一次信息熵,然后判断按照哪个特征划分数据集是最好的划分方式。

##################################功能:划分数据集#输入变量:data_set,axis,value#数据集,数据集的特征,特征的值#输出变量:ret_data_set,划分后的数据集#################################

defsplit_data_set(data_set,axis,value):

ret_data_set=[]

forfeat_vecindata_set:iffeat_vec[axis]==value:

#把axis特征位置之前和之后的特征值切出来#没有使用del函数的原因是,del会改变原始数据reduced_feat_vec=feat_vec[:axis]reduced_feat_vec.extend(feat_vec[axis+1:])ret_data_set.append(reduced_feat_vec)

returnret_data_set

4、遍历整个数据集,循环划分数据并计算信息熵,通过计算最大信息增益来找到最好的特征划分方式。

具体做法是,遍历当前特征中的所有唯一属性值,对每个特征划分一次数据集,然后计算数据集的新熵值,并对所有唯一特征值得到的熵求和。最后用所求的和值与原始信息熵相减,计算寻找最大信息增益。

#######################################功能:选择最好的数据集划分方式#输入变量:data_set待划分的数据集#输出变量:best_feature计算得出最好的划分数据集的特征######################################defchoose_best_feature_to_split(data_set):

num_features=len(data_set[0])-1#最后一个是类别标签,所以特征属性长度为总长度减1base_entropy=calc_shannon_ent(data_set)#计算数据集原始信息熵

best_info_gain=0.0best_feature=-1

foriinxrange(num_features):

#feat_vec[i]代表第i列的特征值,在for循环获取这一列的所有值feat_list=[feat_vec[i]forfeat_vecindata_set]unique_vals=set(feat_list)#set函数得到的是一个无序不重复数据集

new_entropy=0.0

#计算每种划分方式的信息熵forvalueinunique_vals:

sub_data_set=split_data_set(data_set,i,value)prob=len(sub_data_set)/float(len(data_set))new_entropy+=prob*calc_shannon_ent(sub_data_set)

info_gain=base_entropy-new_entropy

ifinfo_gain>best_info_gain:

best_info_gain=info_gainbest_feature=i

returnbest_feature

5

递归构建决策树

工作原理:得到原始数据集,然后基于最好的属性值划分数据集,由于特征值可能多于两个,因此可能存在大于两个分支的数据集划分。第一次划分之后,数据将被向下传递到树分支的下一个节点,在这个节点上,我们可以再次划分数据。因此我们可以采用递归的原则处理数据集。

递归结束条件是:第一、所有的类别标签(叶结点)完全相同。第二、使用完了所有的特征,仍然不能将数据集划分成仅包含唯一类别的分组,则挑选出次数最多的类别作为返回值。

#######################################功能:多数表决分类#输入变量:class_list所有数据的标签数组#输出变量:sorted_class_count[0][0]出现次数最多的分类名称######################################defmajority_vote_sort(class_list):

class_count={}

forvoteinclass_list:class_count[vote]=class_count.get(vote,0)+1

#items以列表方式返回字典中的键值对,iteritems以迭代器对象返回键值对,而键值对以元组方式存储,即这种方式[(),()]#operator.itemgetter(0)获取对象的第0个域的值,即返回的是key值#operator.itemgetter(1)获取对象的第1个域的值,即返回的是value值#operator.itemgetter定义了一个函数,通过该函数作用到对象上才能获取值#reverse=True是按降序排序sorted_class_count=sorted(class_count.iteritems(),key=operator.itemgetter(1),reverse=True)

returnsorted_class_count[0][0]

#######################################功能:创建数#输入变量:data_set,labels待分类数据集,标签#输出变量:my_tree决策树######################################defcreate_tree(data_set,labels):

class_list=[example[-1]forexampleindata_set]

#判断类别标签是否完全相同#count()是列表内置的方法,可以统计某个元素在列表中出现的次数ifclass_list.count(class_list[0])==len(class_list):returnclass_list[0]

#遍历完所有特征时返回出现次数最多的iflen(data_set[0])==1:returnmajority_vote_sort(class_list)

best_feat=choose_best_feature_to_split(data_set)best_feat_label=labels[best_feat]my_tree={best_feat_label:{}}del(labels[best_feat])

#得到列表包含的所有属性值feat_values=[example[best_feat]forexampleindata_set]unique_vals=set(feat_values)

forvalueinunique_vals:

sub_labels=labels[:]#:复制特征标签,为了保证循环调用函数create_tree()不改变原始的内容ret_data_set=split_data_set(data_set,best_feat,value)my_tree[best_feat_label][value]=create_tree(ret_data_set,sub_labels)

returnmy_tree

6

测试代码

defmain():

1、测试决策树分类算法性能

#######################################功能:决策树的分类函数#输入变量:input_tree,feat_labels,test_vec#决策树,分类标签,测试数据#输出变量:class_label类标签######################################defclassify(input_tree,feat_labels,test_vec):first_str=input_tree.keys()[0]second_dict=input_tree[first_str]class_label=-1

#index方法用于查找当前列表中第一个匹配first_str变量的索引feat_index=feat_labels.index(first_str)

2、对决策树算法进行存储#######################################功能:将决策树存储到磁盘中#输入变量:input_tree,filename决策树,存储的文件名######################################defstore_tree(input_tree,filename):

3、对决策树算法进行读取#######################################功能:从磁盘中读取决策树信息#输入变量:filename存储的文件名######################################defgrab_tree(filename):

4、代码测试defmain():

案例分析:使用决策树预测隐形眼镜类型

隐形眼镜类型包括硬材质、软材质以及不适合佩戴隐形眼镜。而眼科医生需要从age、prescript、astigmatic和tearRate这四个方面对患者进行询问,以此来判断患者佩戴的镜片类型。利用决策树算法,我们甚至也可以帮助人们判断需要佩戴的镜片类型。

在构造决策树前,我们需要获取隐形眼镜数据集,从lenses.txt文件读取。还需要获取特征属性(或者说决策树的决策结点),从代码输入。将数据集和特征属性代入决策树分类算法,就能构造出隐形眼镜决策树,沿着不同分支,我们可以得到不同患者需要的眼镜类型。

THE END
1.python机器学习算法之决策树入门讲解决策树分类算法python4.局部最优解:决策树构建时使用贪婪算法,可能导致生成局部最优的树结构,而不一定是全局最优。这可能需要在多个不同的初始条件下训练多个决策树来减轻这一问题。 5.特征连续性处理:决策树通常将特征看作离散值,不擅长处理连续特征。尽管有方法可以将连续特征处理为离散特征,但这增加了复杂性。 https://blog.csdn.net/2301_82059354/article/details/144252079
2.回归二分类和多分类交叉验证交叉熵损失函数k使用该参数方案对整个训练数据集训练之后,得到最后的f函数。 04 为什么逻辑回归采用交叉熵损失函数,而不是平方损失函数? 我的作答: 因为交叉熵损失函数能够体现逻辑回归的预测结果与真实值之间的相关程度,而平方损失函数只能简单地计算预测https://mp.weixin.qq.com/s?__biz=Mzg4MzcxMjIzMQ==&mid=2247487593&idx=2&sn=d3964fd19f5a13282aa2c22b6dbacff7&chksm=cee34e498619c573b898af986c0fe8ec1202474a05301d131f366b29771e77f6cf011dfd0771&scene=27
3.python机器学习笔记:深入学习决策树算法原理特征选择是指从训练数据中众多的特征中选择一个特征作为当前节点的分裂标准,如何选择特征有着很多不同量化评估标准,从而衍生出不同的决策树算法。 1.2 决策树生成 根据选择的特征评估标准,从上至下递归地生成子节点,直到数据集不可分则停止决策树停止生长。树结构来说,递归结构是最容易理解的方式。 https://www.flyai.com/article/622
4.python实现决策树C4.5算法详解(在ID3基础上改进)python下面小编就为大家带来一篇python实现决策树C4.5算法详解(在ID3基础上改进)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 一、概论 C4.5主要是在ID3的基础上改进,ID3选择(属性)树节点是选择信息增益值最大的属性作为节点。而C4.5引入了新概念“信息增益率”,C4.5是选择信息增益率https://www.jb51.net/article/115025.htm
5.增强回归树模型mob64ca1411e411的技术博客在前面决策树的介绍中,我们使用ID3算法来构建决策树;这里我们使用CART算法来构建回归树和模型树。ID3算法是每次选取当前最佳的特征来分割数据,并按照该特征的所有可能取值来区分。比如,如果一个特征有4种取值,那么数据将被切分成4份。很明显,该算法不适用于标签值为连续型的数据。 https://blog.51cto.com/u_16213690/12764986
6.机器学习——全套PPT课件.pptx机器学习概述复旦大学赵卫东博士第1章机器学习基础.pptx第2章机器学习基本方法PCA和SVD.pptx第2章机器学习基本方法回归分析.pptx第2章机器学习基本方法可视化.pptx第3章决策树与分类算法.pptx第4章1聚类分析.pptx第4章2EM算法.pptx第5章文本分析.pptx第6章神经网络.pptx第7章贝叶斯网络.pptx第8章支持向量机.pptxhttps://m.book118.com/html/2024/0909/6125221241010220.shtm
7.基于聚类分析和决策树算法的装车工时预测模型其特征在于:它包括聚类分析算法模块和决策树算法模块,所述预测模型将历史数据通过聚类分析算法,划分时长区间,进而得出决策树算法的分类方案,再通过历史数据输入包括包装方式、吊装方式等影响最终装车工时的属性集合,与聚类分析的分类方案联系起来,利用C4.5决策树算法生成最终的决策树数据模型,最终来预测出未来的装车工时;https://wenku.baidu.com/view/682051b2cf1755270722192e453610661fd95ac7.html
8.常用数据挖掘算法总结及Python实现第四章 KNN(k 最邻近分类算法)16 第五章 决策树19 第六章 朴素贝叶斯分类https://www.modb.pro/db/1798520229306912768
9.决策树——ID3C4.5CART决策树ID3算法的过程为: 输入:训练数据集 ,每个样本有 个离散特征,特征集合为 ; 输出:决策树 。 1 初始化信息增益的阈值 ; 2 判断样本是否为同一类输出 ,如果是则返回单节点树 ,标记类别为 ; 3 判断特征 是否为空,如果是,则返回单节点树 ,标记类别为样本中输出类别 https://www.jianshu.com/p/3acd4150db05