机器学习决策树算法学习笔记

作者: 佚名 2017-05-10 15:41:29

基本概念

决策树是分类算法。

数据类型:数值型和标称型。因为构造算法只适用于标称型,所以数值型数据必须离散化。

工作原理

利用香浓熵找到信息增益最大的特征,按照信息增益最大的特征划分数据,如此反复,让无序的数据变的更加有序。使用ID3算法构建树结构。当传入一个新数据时,按照数据找到对应树节点,直到最后没有叶子节点时,完成分类。

样例

机器学习决策树算法学习笔记

不浮出水面是否可以生存? 是否有脚蹼? 是否是鱼类?

通过“不浮出水面是否可以生存”和“是否有脚蹼”这两个特征来判断是否是鱼类。构建一个简单决策树,如果得到一个新的生物,可以用此来判断是否是鱼类。

样例代码

  1. def createDataSet():   
  2.     dataSet = [[1, 1, 'yes'], 
  3.                [1, 1, 'yes'], 
  4.                [1, 0, 'no'], 
  5.                [0, 1, 'no'], 
  6.                [0, 1, 'no']] 
  7.     labels = ['no surfacing','flippers'
  8.     return dataSet, labels 

香农熵公式

如果待分类的事务可能划分在多个分类之中,则符号Xi的信息定义为:

机器学习决策树算法学习笔记

其中P(Xi)是选择该分类的概率

为了计算熵,需要计算所有类别所有可能值包含的信息期望值总和,公式为:

机器学习决策树算法学习笔记

其中n是分类的数目

香农熵算法

  1. def calcShannonEnt(dataSet):   
  2.     # 选择该分类的概率 就是每个类型/总个数 
  3.     # 总数,多少行数据 
  4.     numEntries = len(dataSet) 
  5.     labelCounts = {} 
  6.     # 取到的每个类型个数 
  7.     for featVec in dataSet: 
  8.         currentLabel = featVec[-1] 
  9.         if currentLabel not in labelCounts.keys(): labelCounts[currentLabel] = 0 
  10.         labelCounts[currentLabel] += 1 
  11.  
  12.     shannonEnt = 0.0 
  13.     for key in labelCounts: 
  14.         # 得到选择该分类的概率 
  15.         prob = float(labelCounts[key])/numEntries 
  16.         # 按照公式 
  17.         shannonEnt -= prob * log(prob,2) #log base 2 
  18.     return shannonEnt 

按照香农熵划分数据

除了需要测量信息熵,还需要划分数据集,度量花费数据集的熵,以便判断当前是否正确划分。 循环计算香浓熵和splitDataSet(),找到最好的特征划分方式。

  1. def splitDataSet(dataSet, axis, value):   
  2.     # 这个算法返回axis下标之外的列 
  3.     retDataSet = [] 
  4.     for featVec in dataSet: 
  5.         if featVec[axis] == value: 
  6.             reducedFeatVec = featVec[:axis]     #chop out axis used for splitting 
  7.             reducedFeatVec.extend(featVec[axis+1:]) 
  8.             retDataSet.append(reducedFeatVec) 
  9.     return retDataSet 
  10.  
  11. def chooseBestFeatureToSplit(dataSet):   
  12.     # 先取最后一列,用在标签结果:是鱼或不是鱼。 
  13.     numFeatures = len(dataSet[0]) - 1 
  14.     # 原始香浓熵 
  15.     baseEntropy = calcShannonEnt(dataSet) 
  16.  
  17.     bestInfoGain = 0.0; bestFeature = -1 
  18.     # 遍历所有的特征 
  19.     for i in range(numFeatures): 
  20.         # 创建一个列表包含这个特征的所有值 
  21.         featList = [example[i] for example in dataSet] 
  22.         # 利用set去重 
  23.         uniqueVals = set(featList) 
  24.         newEntropy = 0.0 
  25.         # 计算该特征所包含类型的香浓熵之和 
  26.         for value in uniqueVals: 
  27.             subDataSet = splitDataSet(dataSet, i, value) 
  28.             prob = len(subDataSet)/float(len(dataSet)) 
  29.             newEntropy += prob * calcShannonEnt(subDataSet) 
  30.         # 得到信息增益 
  31.         infoGain = baseEntropy - newEntropy 
  32.         # 取最大的信息增益,并记录下标 
  33.         if (infoGain > bestInfoGain): 
  34.             bestInfoGain = infoGain 
  35.             bestFeature = i 
  36.     # 返回下标 
  37.     return bestFeature 

数据集需要满足一定的要求:

  • 数据必须是一种有列表元素组成的列表。(二维数组)
  • 所有列表元素必须有相同长度。
  • 最后一列必须是当前实例的标签。

递归构建决策树

机器学习决策树算法学习笔记

多数表决算法

如果数据集已经处理了所有属性,但是类标签依然不是唯一的,此时需要决定如何定义该叶子节点,在这种情况下,我们通常会采用多数表决决定该叶子节点。

  1. import operator   
  2. def majorityCnt(classList):   
  3.     # 排序取出种类最多的 
  4.     classCount={} 
  5.     for vote in classList: 
  6.         if vote not in classCount.keys(): classCount[vote] = 0 
  7.         classCount[vote] += 1 
  8.     sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True
  9.     return sortedClassCount[0][0] 

构建树算法

  1. def createTree(dataSet,labels):   
  2.     # 取出结果 
  3.     classList = [example[-1] for example in dataSet] 
  4.     # 如果结果里的第一个元素所代表的数据个数等于结果本身,说明没有其他分类了 
  5.     if classList.count(classList[0]) == len(classList):  
  6.         return classList[0] 
  7.     # 如果没有更多数据了,超过一个才有分类的意义 
  8.     if len(dataSet[0]) == 1: 
  9.         # 多数表决,返回出现次数最多的 
  10.         return majorityCnt(classList) 
  11.  
  12.     # 选出最适合用于切分类型的下标 
  13.     bestFeat = chooseBestFeatureToSplit(dataSet) 
  14.     # 根据下标取出标签 
  15.     bestFeatLabel = labels[bestFeat] 
  16.     # 构建树 
  17.     myTree = {bestFeatLabel:{}} 
  18.     # 删除取出过的标签,避免重复计算 
  19.     del(labels[bestFeat]) 
  20.     featValues = [example[bestFeat] for example in dataSet] 
  21.  
  22.     # 利用set去重 
  23.     uniqueVals = set(featValues) 
  24.  
  25.  
  26.     for value in uniqueVals: 
  27.         # 复制所有的子标签,因为是引用类型,以避免改变原始标签数据 
  28.         subLabels = labels[:] 
  29.         # 递归的构建树 
  30.         myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels) 
  31.     return myTree 

使用决策树分类

  1. def classify(inputTree,featLabels,testVec):   
  2.     firstStr = inputTree.keys()[0] 
  3.     secondDict = inputTree[firstStr] 
  4.     featIndex = featLabels.index(firstStr) 
  5.     # print 'featIndex %s' % (featIndex) 
  6.     key = testVec[featIndex] 
  7.     # print 'key %s' % (key
  8.     valueOfFeat = secondDict[key
  9.     if isinstance(valueOfFeat, dict):  
  10.         classLabel = classify(valueOfFeat, featLabels, testVec) 
  11.     else: classLabel = valueOfFeat 
  12.     return classLabel 
  13.  
  14. dataSet, labels = createDataSet()   
  15. mytree = createTree(dataSet, labels[:]) #因为内部会删除labels里的值所以用这样copy一份   
  16. print mytree   
  17. # {'no surfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}} 
  18. print classify(mytree, labels, [0,1])   
  19. no 

决策树的存储

构造决策树是耗时的任务,即使处理很小的数据集。所以我们可以使用构造好的决策树。

  1. def storeTree(inputTree,filename):   
  2.     import pickle 
  3.     fw = open(filename,'w'
  4.     pickle.dump(inputTree,fw) 
  5.     fw.close()  
  6. def grabTree(filename):   
  7.     import pickle 
  8.     fr = open(filename) 
  9.     return pickle.load(fr) 

优点

  • 计算复杂度不高
  • 输出结果易于理解
  • 对中间值缺失不敏感
  • 可以处理不相关特侦

缺点

  • 可能产生过度匹配问题
机器学习 算法 数据
上一篇:正在涌现的新型神经网络模型:优于生成对抗网络 下一篇:为什么有些数学研究者会看不惯甚至鄙视深度学习(Deep Learning)?
评论
取消
暂无评论,快去成为第一个评论的人吧

更多资讯推荐

机器学习与预测分析的区别在何处?

如今,认知学习的应用比以往更为普遍。通常意义上讲,认知学习与认知计算就是涉及AI技术与信号处理的操作过程或技术平台。

读芯术 ·  16h前
大盘点:8月Github上7个值得关注的数据科学项目

本文带你来看看GitHub上创建于2019年8月的7个数据科学项目。笔者所选项目的范围十分广泛,涉及从机器学习到强化学习的诸多领域。

读芯术 ·  17h前
全球十大AI训练芯片大盘点

AI芯片哪家强?现在,有直接的对比与参考了。英国一名资深芯片工程师James W. Hanlon,盘点了当前十大AI训练芯片。

乾明 ·  17h前
模型仅1MB,更轻量的人脸检测模型开源,效果不弱于主流算法

AI模型越来越小,需要的算力也也来越弱,但精度依旧有保障。最新代表,是一个刚在GitHub上开源的中文项目:一款超轻量级通用人脸检测模型。

乾明 ·  17h前
非监督学习最强攻略

本次主要讲解的内容是机器学习里的非监督学习经典原理与算法,非监督,也就是没有target(标签)的算法模型。

SAMshare ·  22h前
PyTorch终于能用上谷歌云TPU,推理性能提升4倍,该如何薅羊毛?

Facebook在PyTorch开发者大会上正式推出了PyTorch 1.3,并宣布了对谷歌云TPU的全面支持,而且还可以在Colab中调用云TPU。

晓查 ·  23h前
机器学习转化为生产力,警惕这4个常见陷阱!

几乎每个人都想在他们的业务中引入机器学习,但是这些人也遇到了一个大问题:让模型可持续发展十分困难,尤其是在云架构的基础上。medium上一位博主也指出了这个问题,并提出了将机器学习模型投入生产的4个常见陷阱。

大数据文摘 ·  1天前
500亿参数,支持103种语言:谷歌推出「全球文字翻译」模型

由于缺乏平行数据,小语种的翻译一直是一大难题。来自谷歌的研究者提出了一种能够翻译 103 种语言的大规模多语言神经机器翻译模型,在数据丰富和匮乏的语种翻译中都实现了显著的性能提升。

机器之心 ·  2天前
Copyright©2005-2019 51CTO.COM 版权所有 未经许可 请勿转载