机器学习(三):分类算法之决策树算法
来源:互联网 发布:linux操作系统入门书籍 编辑:程序博客网 时间:2024/05/16 17:46
一、特点
优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据
缺点:可能会产生过度匹配问题
适用数据类型:数值型和标称型
二、原理与实现
根据某个特征,划分数据集。如果某个分支下的数据属于同一类型,则无需进一步分割;否则需要重复划分数据子集。而其中最重要的问题就是,选取哪个特征进行数据划分。
选取哪个特征进行划分?
划分数据集的最大原则是,将无序的数据变的更加有序。在划分数据集之后信息所发生的变化称为信息增益,计算每个特征值划分数据集获得的信息增益,获得信息增益最高的特征就是最好的选择。
如何计算信息增益?
集合信息的度量方式称为香农熵或者简称为熵。熵定义为信息的期望值。(没错,就是这么费解,但是多看看就还好)
1. 计算数据集合的熵的方法
一个数据集中,X是这个集合每个数据对应的类别(比如要不要出去玩、是不是鱼等等)。对于变量X,它可能的取值有n多种,分别是x1,x2,……,xn,每一种取到的概率分别是P1,P2,……,Pn,那么集合的熵(对于x而言)就定义为:
一个集合类别可能的变化越多(只和值的种类多少以及发生概率有关,与具体值是多少无关),它携带的信息量就越大
下面给出计算数据集香农熵的python代码:
from math import log#伪造一些关于是否为鱼类的特征和标签def createDataSet(): dataSet= [ [1,1,'yes'], #每个字段分别代表 在水下是否可以生存, 是否有脚蹼, 是否属于鱼类 [1,1,'yes'], [1,0,'no'], [0,1,'no'], [0,1,'no'] ] labels=['noSurfacing' , 'flippers'] return dataSet, labels #计算香农熵 参数说明: dataSet是一个数据集合,indexOfLabel是表明每条数据所属类别的下标def calcShannonEnt(dataSet, indexOfLabel): entriesNum=len(dataSet) #计算数据总条目数 labelCounts={} #每个类别有多少个 for featVec in dataSet: label = featVec[indexOfLabel] if label not in labelCounts.keys(): labelCounts[label]=0 labelCounts[label] +=1 shannonEnt=0.0 for key in labelCounts: #套用上方的计算式 prob=float(labelCounts[key])/entriesNum shannonEnt -= prob* log(prob,2) return shannonEnt
2.选择最好的数据集划分方式
计算按每个特征来划分之后的熵,与原数据集的熵做差,求出最好的信息增益#根据给定特征划分数据集def splitDataSet(dataSet, axis, value): #待划分的数据集, 划分数据集的特征,特征的值 retDataSet = [] for featVec in dataSet: if featVec[axis] == value: #把符合要求的这条数据加入到返回集合中,但是要除去传入的特征 reducedFeatVec= featVec[:axis] reducedFeatVec.extend(featVec[axis+1:]) retDataSet.append(reducedFeatVec) return retDataSetdef chooseBestFeatToSplit(dataSet): featureNum=len(dataSet[0])-1 baseEntropy = calcShannonEnt(dataSet,-1) #原始香农熵 bestInfoGain=0.0 ; bestFeature=-1 for i in range(featureNum): #创建唯一的分类标签列表 featList=[example[i] for example in dataSet] uniqueVals=set(featList) newEntropy=0.0 #计算每种划分方式的熵 for value in uniqueVals: subDataSet=splitDataSet(dataSet,i,value) prob=len(subDataSet)/float(len(dataSet)) newEntropy +=prob*calcShannonEnt(subDataSet,-1) infoGain=baseEntropy-newEntropy #计算最好的信息增益 if infoGain>bestInfoGain: bestInfoGain=infoGain bestFeature=i return bestFeatureif __name__=="__main__": dataset,labels=createDataSet() print chooseBestFeatToSplit(dataset)
3.递归创建决策树
#获取出现次数最多的类别def getMostType(typeList): typeCounts={} #每个类别有多少个 for type in typeList: if type not in typeCounts.keys(): typeCounts[type]=0 typeCounts[type] +=1 mostCount=0; mostType=''; for type in typeCounts.keys(): if typeCounts[type] > mostCount: mostCount=typeCounts[type] mostType=type return mostType#递归创建def createTree(dataSet,labels,indexOfType): typeList=[example[-1] for example in dataSet] #类别完全相同则停止划分 if typeList.count(typeList[0]) == len(typeList): return typeList[0] if len(dataSet[0]) ==1: return getMostType(typeList) bestFeat = chooseBestFeatToSplit(dataSet) bestFeatLabel = labels[bestFeat] myTree={bestFeatLabel:{}} del(labels[bestFeat]) featValues=[example[bestFeat] for example in dataSet] uniqueValues=set(featValues) for value in uniqueValues: subLabels = labels[:] myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels,indexOfType) return myTreeif __name__=="__main__": dataset,labels=createDataSet() print createTree(dataset,labels,-1)
递归函数第一个停止的条件是所有类别完全相同,直接返回该类别。第二个停止条件是,所有的特征都用完之后,仍然不能将数据集划分为仅包含唯一类别的分组。
上述代码的输出为:
{'noSurfacing': {0: 'no', 1: {'flippers': {0: 'no', 1: 'yes'}}}}
之后拿到新的数据,就可以利用这个结果来判断属于何种类别。可以将结果保存起来,达到一次计算,多次使用的效果。
1 0
- 机器学习(三):分类算法之决策树算法
- 机器学习算法之决策树(三)
- 机器学习之分类决策树算法
- 机器学习--分类算法(一)决策树
- [机器学习]详解分类算法--决策树算法
- [机器学习]详解分类算法--决策树算法
- 机器学习算法(分类算法)—决策树之ID3算法
- 机器学习算法(分类算法)—决策树之ID3算法
- Python机器学习(三)--决策树算法
- Python机器学习(三)--决策树算法
- 王小草【机器学习】笔记--分类算法之决策树
- 【机器学习】分类算法之决策树(Decision tree)
- 机器学习之决策树分类和预测算法原理
- 机器学习算法之决策树(二)
- 机器学习之决策树算法(1)
- 机器学习算法之决策树(python)
- 【机器学习算法】之决策树
- 机器学习算法之决策树
- OC为什么需要copy
- 使用Windbg解析dump文件
- 两标关联update
- 2016, 新的一年,新的起点
- [easyui]单例模式封装组件,提高性能,按需使用
- 机器学习(三):分类算法之决策树算法
- 20160103
- poj 1144 Network
- Android大牛博客
- 关于字符串匹配算法研究 http://www.cnblogs.com/Su-30MKK/archive/2012/09/17/2688122.html
- Lost executor on YARN
- mysql学习心得之二进制安装(4)
- 109_征兵问题 conscription (poj 3723)
- ZigZag Conversion