世界服装鞋帽网免费做网站,上海网站建设哪里便宜,wordpress攻击跳转,深圳seo优化关键词排名决策树可以使用不熟悉的数据集合#xff0c;并从中提取出一系列的规则#xff0c;这是机器根据数据集创建规则的过程#xff0c;就是机器学习的过程。用一个小案例分析#xff1a;通过No surfacing 和 flippers判断该生物是否是鱼#xff0c;No surfacing 是离开水面是否… 决策树可以使用不熟悉的数据集合并从中提取出一系列的规则这是机器根据数据集创建规则的过程就是机器学习的过程。用一个小案例分析通过No surfacing 和 flippers判断该生物是否是鱼No surfacing 是离开水面是否可以生存flippers判断是否有脚蹼
引入信息增益和信息熵的概念
信息熵计算熵我们需要计算所有类别所有可能值包含的信息期望值。p(x)是类别出现的概率
条件熵表示在已知随机变量X的条件下随机变量Y的不确定性。信息增益划分数据集前后的信息发生的变化通俗的说就是信息熵减去条件熵代码实现加载数据:
def createDataSet():dataSet [[1,1,yes],[1,1,yes],[1,0,no],[0,1,no],[0,1,no]]labels [no surfacing,flippers]return dataSet,labels
计算原始熵
def calcShannonEnt(dataSet):numEntries len( dataSet)labelCounts { }for featVec in dataSet:currentLabel featVec[-1]if currentLabel not in labelCounts.keys():labelCounts[currentLabel] 0labelCounts [currentLabel]1shannonEnt 0.0 for key in labelCounts :prob float (labelCounts[key])/numEntriesshannonEnt -prob * log(prob,2)return shannonEnt 划分数据集def splitDataSet(dataSet,axis,value): # 待划分的数据集 划分数据集的特征需要返回的特征的值retDataSet[]for featVec in dataSet:if featVec[axis] value :reduceFeatVecfeatVec[:axis] #取不到axis这一行reduceFeatVec.extend(featVec[axis1:])retDataSet.append(reduceFeatVec)return retDataSet
测试数据及结果myDat01 myDat是数据集0是第一次划分数据集1是第一列为1的数据
计算出条件熵然后求出信息增益并找到最大的信息增益最大的信息增益就是找到最好的划分数据集的特征
def chooseBestFeatureToSplit(dataSet):numFeatureslen(dataSet[0])-1#计算出原始的香农熵baseEntropy calcShannonEnt(dataSet)bestInfoGain 0.0; bestFeature -1for i in range (numFeatures):#创建唯一的分类标签列表featList [example[i] for example in dataSet]uniqueVals set (featList) #去重复#条件熵的初始化newEntropy 0.0for value in uniqueVals :#划分 获得数据集subDataSet splitDataSet(dataSet,i ,value)problen(subDataSet)/float(len(dataSet)) # 概率#条件熵的计算newEntropy prob * calcShannonEnt (subDataSet)# 信息增益infoGain baseEntropy -newEntropyif (infoGain bestInfoGain):bestInfoGain infoGain #找到最大的信息增益bestFeature i #找出最好的划分数据集的特征return bestFeature
测试数据
dataSet,labels createDataSet()
print(dataSet)
print(chooseBestFeatureToSplit(dataSet))
输入结果投票机制def majorityCnt(classList):classCount{}for vote in classList:if vote not in classCount.keys() :classCount[vote]0sortedClassCount sorted (classCount.iteritems(),keyoperator.itemgetter(1),reverseTrue)return sortedClassCount[0][0]
创建树
def createTree(dataSet,labels):classList [example[-1] for example in dataSet]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
结果该方法是用信息增益的方法来构建树在查阅其他的博客得知ID3算法主要是通过信息增益的大小来判定最大信息增益的特征就是当前节点这个算法存在许多的不足第一它解决不了过拟合问题和缺失值的处理第二信息增益偏向取值较多的特征第三不能处理连续特征问题。
因此引入C4.5算法是利用信息增益率来代替信息增益。为了减少过度匹配问题我们通过剪枝来处理冗余的数据生成决策树时决定是否要剪枝叫预剪枝生成树之后进行交叉验证的叫后剪枝。
还有一个是引入基尼指数来进行计算叫CART树以后再做介绍。
绘制树形图
decisionNode dict(boxstyle sawtooth, fc0.8)
leafNode dict(boxstyle round4 ,fc0.8)
arrow_args dict(arrowstyle-)
def plotNode(nodeTxt,centerPt,parentPt,nodeType):createPlot.ax1.annotate(nodeTxt,xyparentPt,xycoordsaxes fraction ,\xytextcenterPt ,textcoordsaxes fraction,vacenter ,\ha center ,bboxnodeType,arrowprops arrow_args)def getNumLeafs(myTree):numLeafs 0firstStr list(myTree.keys())[0]secondDict myTree[firstStr]for key in secondDict.keys():if type(secondDict[key]).__name__dict:numLeafs getNumLeafs(secondDict[key])else : numLeafs1return numLeafs
def getTreeDepth(myTree) :maxDepth0firstStr list(myTree.keys())[0]secondDict myTree[firstStr]for key in secondDict.keys():if type(secondDict[key]).__name__dict:thisDepth 1 getTreeDepth(secondDict[key])else : thisDepth 1if thisDepth maxDepth : maxDepththisDepthreturn maxDepth
def plotMidText(cntrPt , parentPt ,txtString) :xMid (parentPt[0]-cntrPt[0])/2.0 cntrPt[0]yMid (parentPt[1]-cntrPt[1])/2.0 cntrPt[1]createPlot.ax1.text(xMid,yMid,txtString)
def plotTree(myTree,parentPt,nodeTxt):numLeafs getNumLeafs(myTree)depth getTreeDepth(myTree)firstStr list(myTree.keys())[0]cntrPt (plotTree.xOff(1.0float(numLeafs))/2.0/plotTree.totalW,plotTree.yOff)plotMidText(cntrPt,parentPt,nodeTxt)plotNode(firstStr,cntrPt,parentPt,decisionNode)secondDict myTree[firstStr]plotTree.yOff plotTree.yOff - 1.0/plotTree.totalDfor key in secondDict.keys():if type(secondDict[key]).__name__dict:plotTree(secondDict[key],cntrPt,str(key))else:plotTree.xOff plotTree.xOff 1.0 /plotTree.totalWplotNode(secondDict[key],(plotTree.xOff,plotTree.yOff),cntrPt,leafNode)plotMidText((plotTree.xOff,plotTree.yOff) ,cntrPt,str(key))plotTree.yOff plotTree.yOff 1.0/plotTree.totalDdef createPlot(inTree) :fig plt.figure(1,facecolor white)fig.clf()axprops dict(xticks[],yticks[])createPlot.ax1 plt.subplot(111,frameon False ,**axprops)plotTree.totalW float(getNumLeafs(inTree))plotTree.totalDfloat(getTreeDepth(inTree))plotTree.xOff -0.5/plotTree.totalW;plotTree.yOff 1.0plotTree(inTree,(0.5,1.0),)plt.show()
createPlot(myTree)