决策树算法详解(2)
来源:互联网 发布:淘宝不支持该地区销售 编辑:程序博客网 时间:2024/06/06 02:26
Python决策树原生版参考
#encoding:utf-8import mathdef createDataSet(): #训练数据集 dataSet=[['young','myope','no','reduced','no lenses'], ['young','myope','no','normal','soft'], ['young','myope','yes','reduced','no lenses'], ['young','myope','yes','normal','hard'], ['young','hyper','no','reduced','no lenses'], ['young','hyper','no','normal','soft'], ['young','hyper','yes','reduced','no lenses'] ] #数据分为两类yes,no #labels为特征的名称 labels=['age','prescript','Astigmatic','tearRate'] return dataSet,labels#计算给定数据集的熵def calcShannonEnt(dataSet): #总的训练样本条数 numEntries=len(dataSet) #类标签,每条样本所属类别 labelCounts={} for featVec in dataSet: #每条最后一列为各自类别 currentLabel=featVec[-1] #为所有可能的类别取值建立<key,value>结构 #key表示类别,value表示该类出现次数 #此处初始化 if currentLabel not in labelCounts.keys():labelCounts[currentLabel]=0 #出现一次加一次 labelCounts[currentLabel]+=1 #保存信息熵 shannonEnt=0.0 #样本遍历完后,计算各类别占总样本的,比例,即概率 #遍历词典<key,value>结构 for key in labelCounts: #计算该类别的比例 prob=float(labelCounts[key])/numEntries #计算信息增益,以2为底数取对数 shannonEnt-=prob*math.log(prob,2) #返回数据集熵 return shannonEnt#计算条件熵,划分数据集def splitDataSet(dataSet,axis,value): #定义新变量,保存划分后的数据集 retDataSet=[] #遍历数据集每一条数据 for featVec in dataSet: #将符合要求的数据抽取出来存入retDataSet中 if featVec[axis]==value: #除给定的特征axis及值value,整行数据被保存下来 #如选取axis为年龄,value为青年 #这部分数据在数据集中有多少行都会被保存下来 #但年龄为青年这一列数据不会被保存 reducedFeatVec=featVec[:axis] reducedFeatVec.extend(featVec[axis+1:]) #保存去除该列后的数据 retDataSet.append(reducedFeatVec) #返回去除指定特征值列的数据,便于计算该条件下的条件熵 return retDataSet#选择最好的特征划分数据集,返回最佳特征下标。#最好的特征即为信息增益最大的特征def chooseBestFeatureToSplit(dataSet): #保存特征个数,最后一列为类标签,减一 numFeatures=len(dataSet[0])-1 #数据集的熵 baseEntropy=calcShannonEnt(dataSet) #保存最大信息增益值 bestInfoGain=0.0 #信息增益最大的特征 bestFeature=-1 #依次遍历数据集各个特征 for i in range(numFeatures): #取得当前特征对应列下的值 featList=[example[i] for example in dataSet] #当前特征下对应值去重,即每个特征值唯一 #如年龄,取值3个青年、中年、老年 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) #整个特征计算完成,计算该特征下的信息增益 #信息增益=数据集的熵-数据集按划分后的熵 infoGain=baseEntropy-newEntropy #最大的信息增益,为最好的特征 if(infoGain>bestInfoGain): bestInfoGain=infoGain bestFeature=i #返回最好的特征 return bestFeature#递归构建决策树#多数表决的方法决定叶子节点的分类#所有特征都用完时,以数据集中类别数量最多的类别作为最终类别def majorityCnt(classList): #<key,value>数据集中每个类别出现的次数 classCount={} #遍历数据集中的类别 for vote in classList: #初始类别第一次加入字典最终 if vote not in classCount.keys():classCount[vote]=0 #记录次数 classCount[vote]+=1 #遍历结束后,次数value值从大到小进行排列 sortedClassCount=sorted(classCount.iteritems(),key=operator.itemgetter(1),reverse=True) #返回数量最多的类别 return sortedClassCount[0][0]#创建树#输入:数据集、特征名#输出:树def createTree(dataSet,labels): #取出数据集最后列数据,即训练数据的类标签 classList=[example[-1] for example in dataSet] #类别完全相同则不划分,返回类标签 #具体所有数据值为同一个值,如classList[0]='yes'个数, #为整个列表长度,显然所有的值均为yes if classList.count(classList[0])==len(classList): #返回该类别 return classList[0] #如果数据集没有特征值 if len(dataSet[0])==1: #返回数据集中类别数量最多的类别 return majorityCnt(classList) #选出数据集中最佳的划分子集的特征 bestFeat=chooseBestFeatureToSplit(dataSet) #将该特征名作为树根节点 bestFeatLabel=labels[bestFeat] #初始赋值决策树 myTree={bestFeatLabel:{}} #删除已选择的特征名称 del(labels[bestFeat]) #取得最后划分特征列下的值 featValues=[example[bestFeat] for example in dataSet] #每个值去重 uniqueVals=set(featValues) #遍历去重后的特征的值 for value in uniqueVals: #获得除已删除的特征外,其余特征的名称 subLabels=labels[:] #以当前的特征值划分子集 #以子集为参数,递归调用创建树的方法 #将递归调用的结果作为树节点的一个分支 myTree[bestFeatLabel][value]=createTree(splitDataSet(dataSet,bestFeat,value),subLabels) #返回树 return myTree#使用决策树进行分类#输入:训练好的决策树#构建树的类别标签向量(用于确定特征在数据集中的位置)#测试数据#判断测试数据testVec,属于哪个类别def classify(inputTree,featLabels,testVec): #firstStr存放决策树的根节点名称 #取得根节点名称no surfacing #firstStr='no surfacing' firstStr=inputTree.keys()[0] #secondDict值为除树根节点名称外的值 #即{0:'no',1:{'filippers':{0:'no',1:'yes'}}} secondDict=inputTree[firstStr] #index方法查找当前列表中第一个匹配firstStr变量的元素的索引 #即找到树根节点在所有特征列的第几列 featIndex=featLabels.index(firstStr) #测试数据对应根节点下的取值 key=testVec[featIndex] #secondDict[0]='no' secondDict[1]='{'flippers':{0:'no',1:'yes'}}' valueOfFeat=secondDict[key] #判断valueOfFeat的类型 #valueOfFeat为dict词典类型,递归寻找 if isinstance(valueOfFeat,dict): classLabel=classify(valueOfFeat,featLabels,testVec) #valueOfFeat为数值,直接返回该值 #此处valueOfFeat=secondDict[key]='no' 返回no else:classLabel=valueOfFeat #返回最终类别 return classLabel#决策树的存储#pickle序列化对象,可以在磁盘上保存对象def storeTree(inputTree,filename): import pickle fw=open(filename,'w') pickle.dump(inputTree,fw) fw.close()#并在需要的时候将其读取出来def grabTree(filename): import pickle fr=open(filename) return pickle.load(fr)myDat,labels=createDataSet()myTree=createTree(myDat,labels)#print myTreestoreTree(myTree,'1.txt')Tree=grabTree('1.txt')#print Treeaaa=classify(Tree,['age','prescript','Astigmatic','tearRate'],['young','hypper','yes','normal'])print aaa
阅读全文
0 0
- 决策树算法详解(2)
- 决策树算法详解(1)
- 决策树算法详解(3)
- 决策树算法详解(ID3)
- 决策树2 -- CART算法
- [机器学习]详解分类算法--决策树算法
- [机器学习]详解分类算法--决策树算法
- 详解决策树ID3算法划分数据集
- 决策树之C4.5算法详解
- 分类算法之决策树ID3详解
- 机器学习—CART决策树算法详解
- 机器学习-决策树算法代码详解
- 1-2 决策树算法应用
- 机器学习算法(2) 决策树
- 决策树算法
- 决策树算法
- 决策树算法
- 决策树算法
- ajax跨域传递cookie,验证登录
- 1.虚拟机
- intelliJ idea 导入eclipse/myeclipse web project
- ubuntu16 caffe安装+测试(cpu)
- Java多线程基础——线程和线程安全
- 决策树算法详解(2)
- java集合类总结
- 关于.gitignore文件使用说明
- HDU 4006-The kth great number
- 【oracle】限定查询与排序显示
- mybatis动态sql参数为实体类时出现的问题
- win7下安装Ubuntu后进不去win7的完美解决方法
- HDU HDOJ 1124 Factorial
- 简单了解生成树协议