决策树简单算法思想:
构造决策树,它主要是属性的选择,来选择将元组最好的划分成不同的类的属性。
关键:
在于分裂属性。所谓分列属性就是在某个节点处按照某一个特征属性的不同划分构造不同的分支,其目标是让各个分裂子集尽可能的“纯”。尽可能的纯意味着尽量让一个分裂子集中待分类项属于同一类别。
分列属性有三种不同情形:
1:属性离散,且不要求生成二叉决策树。此时属性的每一个划分作为一个分支。
2:属性离散,要求生成二叉决策树。此时,属于此子集,不属于此子集作为一个划分。
3:属性是连续的,此时确定一个值作为分类点。大于此值,作为一个分支;小于此值,作为一个分支。
属性选择度量:ID3,C4.5
说明:熵越大,表明信息越混乱。所以用信息增益时,选择,信息增益值越大,表明混乱程度减少越大,分类越纯,特征越有益于分类。
@机器学习实战
from math import log
def createDataSet():
dataSet=[[1,1,'maybe'],[1,1,'yes'],[1,0,'no'],[0,1,'no'],[0,1,'no']]
labels = ['no surfacing','flippes']
return dataSet,labels;
def calcShannonEnt(dataSet):
numEntries = len(dataSet)
labelCounts ={};
for feat in dataSet:
currentLabel= feat[-1] #取得标签
if currentLabel not in labelCounts:
labelCounts[currentLabel]=0
labelCounts[currentLabel]+=1 #统计不同标签的样本的个数
shannonEnt =0.0;
for key in labelCounts:
prob = float(labelCounts[key])/numEntries
shannonEnt -=prob*log(prob,2)
return shannonEnt
#axis是特征 value是特征取值
#由 某一特征的不同取值分列样本集
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 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] #遍历所有样本的第i个特征的取值情况
uniqueVals = set(featList) #第i条特征的取值 去重
newEntropy=0.0
for value in uniqueVals: #遍历特征的所有取值
subDataSet = splitDataSet(dataSet,i,value) #对某一条样本 按照第i特征,取值为value的进行划分子集
prob = len(subDataSet)/float(len(dataSet))
newEntropy+=prob*calcShannonEnt(subDataSet)#计算某一条样本,按照第i特征划分后的信息增益
infoGain = baseEntropy-newEntropy
if( infoGain>bestInfoGain):
bestInfoGain=infoGain
bestFeature=i
return bestFeature
##多数表决
import operator
def majorityCnt(classList):
classCount={}
for vote in classList:
if vote not in classCount:
classCount[vote]=0
classCount[vote]+=1
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] #取得样本的所有类别
if classList.count(classList[0])==len(classList): #如果只有一种类别
return classList[0] #停止划分
if( len(dataSet[0]))==1: #如果样本只有一个属性
return majorityCnt( classList) #停止划分
bestFeat = chooseBestFeatureToSplit(dataSet) #选择最好的特征
print bestFeat
bestFeatLabel = labels[bestFeat] #特征对应的标签
myTree={bestFeatLabel:{}}
del(labels[bestFeat]) #去除已选特征
featValues =[example[bestFeat] for example in dataSet] #找到最好特征所对应的取值:比如说:是,否
uniqueVals = set(featValues) #取值去重
for value in uniqueVals:
subLabels = labels[:]
subDataSet = splitDataSet(dataSet,bestFeat,value)#由最好的特征属性,划分子数据集
myTree[bestFeatLabel][value] = createTree(subDataSet,subLabels) #子数据集递归调用
return myTree
参考文献
1:机器学习实战
2:之前记录的部分网上资源,如有侵权,联系我删除。