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

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

基本概念

决策树是分类算法。

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

工作原理

利用香浓熵找到信息增益***的特征,按照信息增益***的特征划分数据,如此反复,让无序的数据变的更加有序。使用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) 

优点

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

缺点

  • 可能产生过度匹配问题
责任编辑:未丽燕 来源: 36大数据
相关推荐

2017-11-21 13:00:20

机器学习决策树可视化

2017-07-18 16:25:31

机器学习算法决策树

2022-12-21 14:39:35

机器学习案发决策树

2014-07-07 10:05:57

机械学习

2012-08-06 09:04:01

决策树建模

2017-10-18 14:11:20

机器学习决策树随机森林

2024-09-11 08:34:28

2022-11-11 08:00:00

决策树机器学习监督学习

2018-02-02 17:08:48

机器学习算法决策树

2020-12-22 19:37:04

决策树机器学习人工智能

2009-08-14 09:41:03

C#遗传算法

2009-10-14 09:27:30

VB.NET编码算法

2017-02-23 08:45:36

Python决策树数据集

2023-08-11 17:30:54

决策树机器学习算法

2016-09-30 16:12:47

GBDT算法决策树

2022-01-24 09:00:00

机器学习决策树算法

2018-02-02 15:50:07

决策树Apache Spar数据

2019-05-15 09:00:00

决策树机器学习人工智能

2017-08-04 14:28:40

决策树随机森林CART模型

2009-08-14 17:38:08

C#改写方法
点赞
收藏

51CTO技术栈公众号