机器学习:决策树python实现

来源:互联网 发布:手机淘宝返现怎么操作 编辑:程序博客网 时间:2024/04/30 04:35

                                     机器学习:决策树python实现源码笔记


     打算今天开始回顾一下ml的经典算法,就去按照书上实现了决策树。其实,ml代码模式有很大的相似之处,特征的划分等等。

def createDataSet():    dataSet = [[1, 1, 'yes'],               [1, 1, 'yes'],               [1, 0, 'no'],               [0, 1, 'no'],               [0, 1, 'no']]# 下面的标签labels主要是对应dataset上的1和0,yes和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中    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:    //数据的从新组合--去掉当前的value。//[1,2,3]-->[1,3]-->用数值2去划分            reducedFeatVec = featVec[:axis]                 reducedFeatVec.extend(featVec[axis+1:])            retDataSet.append(reducedFeatVec)    return retDataSet//选择最好的划分属性所对应的索引-->也就是选择划分前后entory变化最大的划分    def chooseBestFeatureToSplit(dataSet):    numFeatures = len(dataSet[0]) - 1//特征的个数          baseEntropy = calcShannonEnt(dataSet)//计算当前data的entory    bestInfoGain = 0.0; bestFeature = -1    for i in range(numFeatures)://对不同的特征进行遍历                featList = [example[i] for example in dataSet]//找出当前特征下所对应的数值        uniqueVals = set(featList)//去掉相同的数值            newEntropy = 0.0        for value in uniqueVals:    //对特征i下不同的value进行划分数据,在计算划分之后的entory            subDataSet = splitDataSet(dataSet, i, value)//划分之后每个数据集所占的比例            prob = len(subDataSet)/float(len(dataSet))//计算划分之后的entory            newEntropy += prob * calcShannonEnt(subDataSet)          //计算划分前后entory的差        infoGain = baseEntropy - newEntropy            if (infoGain > bestInfoGain):                   bestInfoGain = infoGain                     bestFeature = i    return bestFeature                      //考虑到存在就算划分到最后,有些节点的还会存在两种以上的label//那就找出划分之后节点中label最多的那个labeldef majorityCnt(classList):    classCount={}    for vote in classList://计算每个label所对应的个数        if vote not in classCount.keys(): classCount[vote] = 0        classCount[vote] += 1//进行排序    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)    return sortedClassCount[0][0]def createTree(dataSet,labels):    //找出当前数据中存在的labels    classList = [example[-1] for example in dataSet]//只有一种label的话也就代表当前的data停止划分    if classList.count(classList[0]) == len(classList):         return classList[0]//当前的data中只有一个特征,就不要再划分了。    if len(dataSet[0]) == 1:         return majorityCnt(classList)//找出最好的划分特征索引    bestFeat = chooseBestFeatureToSplit(dataSet)//得到特征    bestFeatLabel = labels[bestFeat]//把当前的特征作为tree的根    myTree = {bestFeatLabel:{}}    del(labels[bestFeat])//当前的label已经划分过之后就不会再划分,删除//得到索引所对应的全部属性值    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                            


0 0
原创粉丝点击