【机器学习】分类决策树基本介绍+代码实现
参考:https://blog.csdn.net/u012351768/article/details/73469813
1.基础知识
基于特征对实例进行分类。
优点:复杂度低,输出结果易于理解,缺失中间值不敏感,可处理不相关特征数据。
缺点:过度匹配。
适用数据类型:标称和数值型。(数值型需要离散化)
构建决策树时,在每次分支时都要选择最能区分数据的特征。
2.划分数据集依据
2.1 信息增益(ID3),越大越好
D:数据集
A:特征A
K:类别的集合 k~K
D的经验熵:
,(表示数据集D的纯度,H越小,纯度越高)
特征A将数据集D分成N个数据集,特征A对数据集D的经验条件熵:
,(即给定特征A,计算每个子数据集的纯度再求和,表示给定A后数据集的纯度,数值越小纯度越高)
特征A对数据集的信息增益:
,(即特征A帮助提升的纯度的大小,值越大越好)
2.2 信息增益率(C4.5)越大越好
由于信息增益会偏向取值较多的特征(过拟合),解释:当特征A取值很多,则划分出的组数增多,使得H(D|A)减小,则信息增益增大。但是过于精细的划分,会使得分类失去意义。(比如按照身份证号给人分类,则每一个人都是一类)。
特征A对数据集D的信息增益率:
其中,特征A将数据集分成N类,则对于所有特征A相对应的数据的N个类的信息经验熵为(即表示了特征A为类别标签时,数据D的纯度):
因为当A将数据集D分成太多类时,其纯度降低,H(A)增加,相当于给信息增益添加了一项惩罚项。
2.3 Gini系数(CART)越小越好
基尼指数:从数据集里随机选取子项,度量其被错误分类到其他分组里的概率。基尼系数指数据的不纯度,越小越好。
CART是一个二叉树分类。
K是数据集D的标签集合:k~K
数据D的基尼系数:
若特征A将数据D分成两个数据集:
但是若当特征A将数据集D分成超过两个数据集时,需要计算以每一个取值作为划分点,对样本D划分之后子集的纯度Gini(D,Ai),(其中Ai 表示特征A的可能取值),然后从所有的可能划分的Gini(D,Ai)中找出Gini指数最小的划分,这个划分的划分点,便是使用特征A对样本集合D进行划分的最佳划分点。
对各个概念的理解:熵描述了信息的不确定性,我们的目标是划分数据集D,使得划分后的数据集的不确定性降低。信息增益描述了特征A对于降低数据集D的不确定性的帮助,信息增益越大,说明A的引入增加了信息,降低了D的不确定性。然而,由于信息增益会偏向取值较多的特征,为了解决这个特征之间的选择不平衡的现象,我们添加了一项惩罚项,引入了信息增益率。
3. ID3, C4.5, CART比较
任务 | 准则 | 适合数据 | 优点 | 缺点 | |
ID3 | 分类 | 信息增益最大化 | 标称 | 基础算法,结构简单 | 偏好取值较多的特征,无法处理连续值 |
C4.5 | 分类 | 信息增益率最大化 | 标称,连续(二分法) | 解决ID3不平衡偏好,可处理连续值 | 过拟合(剪枝) |
回归 | 平方误差最小化 | ||||
CART | 分类 | 基尼指数最小化 | 标称,连续(二分法) | 既可以分类,又可以回归 | 二叉树,当离散型特征超过两个取值时,需要逐个比较选择。过拟合(剪枝) |
回归 | 平方误差最小化 |
4. 决策树剪枝
构建决策树时,根据最优的特征进行构建,往往会使得所得的树分支过多,过拟合。因此需要对树进行剪枝。
预剪枝:边构建树边剪枝。当到某一节点无法达到要求时,即停止分支。
后剪枝:先完整地构建出决策树,然后自下而上地进行剪枝。
判断是否剪枝的标准:剪枝前后的泛化能力,若剪枝后泛化能力增强,则剪枝,否则不剪枝。
泛化能力的判断方法:留出法。即在原数据集中拿出一部分做为验证集,剪枝时,判断该分支分与部分对验证集分类的影响(准确率的影响)。
注意:因为预剪枝含有“贪心”的思想,即一旦某个节点分支不能提高泛化能力,立即停止。此时可能会忽略后续泛化能力高的分支。因此预剪枝可能会造成“欠拟合”。
5. “连续属性&缺失属性”的分类问题
连续属性:使用二分法,属性值排序后取中点。C4.5使用该方法。
缺失属性:指样本数据不完整,某些属性的值缺失。当使用含有缺失属性的数据构建决策树时,一个方法是舍弃含有缺失属性的样本;当对含有缺失属性的数据进行分类时,将含有未知属性的样本用不同概率划分到不同的子节点。
6.代码实现
参考:《机器学习实战》
源码地址以及数据:https://github.com/JieruZhang/MachineLearninginAction_src
from math import *
import operator
import pickle#计算熵
def entropy(data):num = len(data)num_labels ={}for vec in data:num_labels[vec[-1]] = num_labels.get(vec[-1],0)+1ent = 0.0for key in num_labels.keys():prob = float(num_labels[key])/nument -= prob*log(prob,2)return ent#根据给定特征划分数据集, axis是特征对应的编号,value是匹配的值
def splitDataSet(data, axis, value):res = []for vec in data:if vec[axis] == value:res.append(vec[:axis] + vec[axis+1:])return res#遍历数据集,计算每种特征对应的信息增益,选出增益最小的,该特征即为用于分类的特征
def chooseFeature(data):num_feature = len(data[0])-1#计算H(D)base_ent = entropy(data)max_gain = 0.0best_feature = 0for i in range(num_feature):#找出feature的种类uniqueFeature = set([vec[i] for vec in data])#对每个feature计算其对应的条件信息熵sub_ent = 0.0for feature in uniqueFeature:sub_data = splitDataSet(data, i, feature)prob = len(sub_data)/float(len(data))sub_ent += prob*entropy(sub_data)#计算每个feature对应的信息增益gain = base_ent - sub_ent#选择最大的信息增益,其对应的feature即为最佳的featureif gain > max_gain:max_gain = gainbest_feature = ireturn best_feature#递归构建决策树
#原始数据集-> 递归地基于最好的属性划分数据集->终止条件:所有属性已经用过或划分后的数据集每个集合只属于一个label,
#若所有属性用完但是每个划分属性不都属于一个label,就使用“多数表决”的方法。#多数表决函数
def majority(classes):classCount = {}for item in classes:classCount[item] = classCount.get(item,0) + 1sortedClassesCount = sorted(classCount.items(), key = operator.itemgetter(1), reverse=True)#返回表决最多的labelreturn sortedClassCount[0][0]#递归构建树,存入字典中,以便随后的可视化.feature_name是feature的名字,仅是为了可视化方便。
def createTree(data, feature_names):#找出data数据集中所有的labelsclassList = [item[-1] for item in data]#如果只属于一种label,则停止构建树if len(set(classList)) == 1:return classList[0]#若果所有features属性都已经使用完,也停止构建树#每次用完一个特征都会删除,这样最后数据集data中只剩下最后一位的label位if len(data[0]) == 1:return majority(classList)bestFeat = chooseFeature(data)bestFeatName = feature_names[bestFeat]#bestFeatName是用于分离数据集的特征的名字,作为根tree = {bestFeatName:{}}#del只删除元素,但是原来的index不变sub_names = feature_names[:]del(sub_names[bestFeat])uniqFeats = set([item[bestFeat] for item in data])#对于每个feature,递归地构建树for feature in uniqFeats:tree[bestFeatName][feature] = createTree(splitDataSet(data,bestFeat,feature), sub_names)return tree#分类函数,也是递归地分类(从根到叶节点)
def classify(tree, feature_names, test_data):#找到根,即第一个用于分类的特征root = list(tree.keys())[0]#找到根对应的子树sub_trees = tree[root]#找出对应该特征的indexfeat_index = feature_names.index(root)#对所有子树,将测试样本划分到属于其的子树for key in sub_trees.keys():if test_data[feat_index] == key:#检查是否还有子树,或者已经到达叶节点if type(sub_trees[key]).__name__ == 'dict':#若还可以再分,则继续向下找return classify(sub_trees[key], feature_names,test_data)else:#否则直接返回分的类return sub_trees[key]#存储树(存储模型)
def stroeTree(tree, filename):fw = open(filename,'w')pickle.dump(tree,fw)fw.close()return#提取树
def grabTree(filename):fr = open(filename)return pickle.load(fr)#预测隐形眼镜类型,已知数据集,如何判断患者需要佩戴的眼镜类型
fr = open('lenses.txt')
lenses = [line.strip().split('\t') for line in fr.readlines()]
feature_names = ['age', 'prescript','astigmatic','tearRate']
#构建树
tree = createTree(lenses,feature_names)
#可视化树
createPlot(tree)
#测试
print(classify(tree,feature_names,['pre','myope','no','reduced']))
sklearn 实现,sklearn使用的是cart分类树。
from sklearn import treedef DT(train_data, test_data, train_class):clf = tree.DecisionTreeClassifier()clf = clf.fit(train_data, train_class)return clf.predict(test_data)
【机器学习】分类决策树基本介绍+代码实现相关推荐
- python决策树怎么选择_【机器学习+python(8)】分类决策树的介绍与实现
之前我们介绍过用逻辑回归根据鸢尾花萼片.花瓣的长度和宽度进行鸢尾花类别的判定:也通过朴素贝叶斯模型分享了如何根据男生专业和身高两大属性,判断其是否有女朋友.而本期我们将介绍另外一种有监督的机器学习分类 ...
- 机器学习实战 —— 决策树(完整代码)
声明: 此笔记是学习<机器学习实战> -- Peter Harrington 上的实例并结合西瓜书上的理论知识来完成,使用Python3 ,会与书上一些地方不一样. 机器学习实战-- 决策 ...
- 推荐 :使用Python了解分类决策树(附代码)
作者:Michael Galarnyk 翻译:李润嘉 校对:和中华 本文约3600字,建议阅读15分钟. 本教程介绍了用于分类的决策树,即分类树,包括分类树的结构,分类树如何进行预测,使用scikit ...
- 独家 | 使用Python了解分类决策树(附代码)
作者:Michael Galarnyk 翻译:李润嘉 校对:和中华 本文约3600字,建议阅读15分钟. 本教程介绍了用于分类的决策树,即分类树,包括分类树的结构,分类树如何进行预测,使用scikit ...
- 机器学习实战-决策树 java版代码开发实现
话不多说,直接上代码,若有帮助,帮忙点赞哦 python版,或其他机器学习算法,可发邮箱:476562571@qq.com 主要实现功能: 特征 二值判别 递归遍历文件目录加载训练数据集 召回率计算 ...
- 机器学习第1集——分类决策树tree.DecisionTreeClassifier()
一.首先,机器学习建模的基本流程分为3步 ①实例化(也就是建立模型对象) ②传入训练集和测试集,训练模型 ③通过模型接口提取需要的信息 那么分类树的基本代码是: from sklearn import ...
- 【机器学习】决策树分类(简介、原理、代码)
决策树分类 一.决策树分类简介: 决策树方法是利用信息论中的信息增益寻找数据库中具有最大信息量的属性字段,建立决策树的一个结点,再根据该属性字段的不同取值建立树的分支,再在每个分支子集中重复建立树的下 ...
- 独家 | 指南:不平衡分类的成本敏感决策树(附代码链接)
作者:Jason Brownlee 翻译:陈超 校对:冯羽 本文约3500字,建议阅读10+分钟 本文介绍了不平衡分类中的成本敏感决策树算法. 决策树算法对平衡分类是有效的,但在不平衡数据集上却表现不 ...
- svm多分类代码_跟我一起机器学习系列文章知识点与代码索引目录,持续更新…...
<跟我一起机器学习> 系列文章知识点与代码索引目录 0 环境配置 如何才能入门机器学习? 优雅的安装和使用Anaconda 使用Conda来进行环境的创建与管理 Pycharm安装与使用 ...
- 机器学习 | 关于决策树分类模型,你学得怎么样了?
这是一篇关于决策树分类模型的详解,身边的朋友看完的都说:这回透彻了! 目录 0 写在前面 1 决策树分类模型 1.1 信息熵 1.2 基尼系数 2 决策树分类模型的建立 3 总结一下 0 写在前面 机 ...
最新文章
- CALayer 了解与使用
- 中石油训练赛 - Bad Treap(数学)
- 一种常见的关于率指标的错误分析思路
- project 模板_不会绘制横道图?18个施工进度计划横道图模板,可一键自动生成,方便快捷易操作,直观形象,相当好用...
- spring(11)使用对象-关系映射持久化数据
- 重装linux之后gcc等下载不了,Redhat linux下安装gcc
- java nio copy_使用NIO快速复制Java文件
- 就9.5面试做个小结
- 上海大学c语言程序设计,上海大学2009-2010年度C语言程序设计秋季学期试卷.doc
- 5.3使用自定议的测试数据库文件
- 中国人工智能学会通讯——融合经济学原理的个性化推荐
- 72. 文件上传(1)
- 天天生鲜Django项目
- java max 函数_Java Math max()用法及代码示例
- 高一计算机教学,高一信息技术教学计划参考
- android svg路径动画,五、Android SVG动画
- 蓝牙4.0和3.0区别
- process monitor解决网络问题一则
- 安装程序无法继续,因为您的计算机上安装了更新的internet explorer
- pyqt5+qt desiger实例教程(1)创建含有三个按钮的窗口,点击按钮2输出消息、按钮3可退出
热门文章
- 月薪30k的PHP架构师的成长路线图1.0!
- (附源码)spring boot智能车APP毕业设计250623
- google浏览器截取长图
- kinect二次开发_Kinect2.0动作捕捉Super Mocap K2
- 一文带你了解dfs和bfs算法
- html支付宝图标,支付宝小程序基础组件 图标·Icon
- 苹果电脑怎样禁用首字母自动大写?
- 最新抖音视频无水印解析接口-突破频率限制
- [PKKS19] 《Revealing Scenes by Inverting Structure from Motion Reconstructions》(CVPR2019)阅读笔记(完)
- 怎样让Windows10系统的时间显示到秒——且可手动修改系统的时间