Example #1
0
def createTree(dataSet, labels):
    classList = [example[-1] for example in dataSet]
    # 如果数据集的最后一列的第一个值出现的次数=整个集合的数量,也就说只有一个类别,就只直接返回结果就行
    # 第一个停止条件:所有的类标签完全相同,则直接返回该类标签。
    # count() 函数是统计括号中的值在list中出现的次数
    if classList.count(classList[0]) == len(classList):
        return classList[0]
    # 如果数据集只有1列,那么最初出现label次数最多的一类,作为结果
    # 第二个停止条件:使用完了所有特征,仍然不能将数据集划分成仅包含唯一类别的分组。
    if len(dataSet[0]) == 1:
        return majorityCnt(classList)

    # 选择最优的列,得到最优列对应的label含义
    bestFeat = chooseBestFeatureToSplit(dataSet)
    # 获取label的名称
    bestFeatLabel = labels[bestFeat]
    # 初始化myTree
    myTree = {bestFeatLabel: {}}
    # 注:labels列表是可变对象,在PYTHON函数中作为参数时传址引用,能够被全局修改
    # 所以这行代码导致函数外的同名变量被删除了元素,造成例句无法执行,提示'no surfacing' is not in list
    del (labels[bestFeat])
    # 取出最优列,然后它的branch做分类
    featValues = [example[bestFeat] for example in dataSet]
    uniqueVals = set(featValues)
    for value in uniqueVals:
        # 求出剩余的标签label
        subLabels = labels[:]
        # 遍历当前选择特征包含的所有属性值,在每个数据集划分上递归调用函数createTree()
        myTree[bestFeatLabel][value] = createTree(
            splitDataSet(dataSet, bestFeat, value), subLabels)
    return myTree
Example #2
0
def chooseBestFeatureToSplit(dataSet):
    """chooseBestFeatureToSplit(选择最好的特征)

    Args:
        dataSet 数据集
    Returns:
        bestFeature 最优的特征列
    """
    # 求第一行有多少列的 Feature, 最后一列是label列嘛
    numFeatures = len(dataSet[0]) - 1
    # 数据集的原始信息熵
    baseEntropy = calcShannonEnt(dataSet)
    # 最优的信息增益值, 和最优的Featurn编号
    bestInfoGain, bestFeature = 0.0, -1
    # iterate over all the features
    for i in range(numFeatures):
        # create a list of all the examples of this feature
        # 获取对应的feature下的所有数据
        featList = [example[i] for example in dataSet]
        # get a set of unique values
        # 获取剔重后的集合,使用set对list数据进行去重
        uniqueVals = set(featList)
        # 创建一个临时的信息熵
        newEntropy = 0.0
        # 遍历某一列的value集合,计算该列的信息熵
        # 遍历当前特征中的所有唯一属性值,对每个唯一属性值划分一次数据集,计算数据集的新熵值,并对所有唯一特征值得到的熵求和。
        for value in uniqueVals:
            subDataSet = splitDataSet(dataSet, i, value)
            # 计算概率
            prob = len(subDataSet) / float(len(dataSet))
            # 计算信息熵
            newEntropy += prob * calcShannonEnt(subDataSet)
        # gain[信息增益]: 划分数据集前后的信息变化, 获取信息熵最大的值
        # 信息增益是熵的减少或者是数据无序度的减少。最后,比较所有特征中的信息增益,返回最好特征划分的索引值。
        infoGain = baseEntropy - newEntropy
        print('infoGain=', infoGain, 'bestFeature=', i, baseEntropy,
              newEntropy)
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = i
    return bestFeature
def chooseBestFeatureToSplit(dataSet):
    numFeatures = len(dataSet[0]) - 1
    #前提:数据是由列表元素组成的列表,列表元素具有相同的长度;除去标签,假设有两个特征
    baseEntropy = calcShannonEnt.calcShannonEnt(dataSet)  #计算出最初的无序度量度
    bestInfoGain = 0.0
    bestFeature = -1
    for i in range(numFeatures):  #2;i代表索引值;第几个特征
        featList = [example[i] for example in dataSet]  #除去标签,提取出了所有的特征
        uniqueVals = set(featList)  #set:每个值互不相同;除去相同的特征
        newEntropy = 0.0
        #以上代码创建出了唯一的分类标签列表;将数据集中所有i个特征值写入新的列表中
        for value in uniqueVals:
            subDataSet = splitDataSet.splitDataSet(dataSet, i,
                                                   value)  #i代表第几个特征
            prob = len(subDataSet) / float(len(dataSet))
            newEntropy += prob * calcShannonEnt.calcShannonEnt(subDataSet)
            # 这个for循环计算每一种划分方法的信息熵;
            infoGain = baseEntropy - newEntropy
            if (infoGain > bestInfoGain):
                bestInfoGain = infoGain
                bestFeature = i
#计算出最好的信息增益,比较所有特征中的信息增益,返回最最好特征划分的索引值
    return bestFeature
Example #4
0
def createTree(dataSet, labels):  #输入数据集和标签列表
    classList = [example[-1] for example in dataSet]  #取出数据集的最后一列:即这个样本的类别,分类结果
    if classList.count(classList[0]) == len(classList):  #count用来计数
        return classList[0]
#第一个停止条件:类别完全相同则灵芝划分
    if len(dataSet[0]) == 1:
        return majorityCnt.majorityCnt(classList)
# 第二个停止条件:遍历完所有特征是返回出现次数最多的
    bestFeat = chooseBestFeatureToSplit.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.splitDataSet(dataSet, bestFeat, value), subLabels)
    return myTree
Example #5
0
def createTree(dataSet, labels):
    from majorityVote import majorityVote
    from chooseBestFeatureToSplit import chooseBestFeatureToSplit
    from splitDataSet import splitDataSet
    classList = [example[0] for example in dataSet]
    #提取dataSet的样本标签集
    if classList.count(classList[0]) == len(classList):
        #dataSet只有一类
        return classList[0]
    if len(dataSet[0]) == 1:
        return majorityVote(classList)
        #当递归算法使用完所有特征后,这里不用单纯的一类作返回值,而是以majorityVote投票选多数类作返回值
    Trainlabels = labels.copy()
    #不要直接用labels,copy一下,要不会破坏原数据

    bestFeature = chooseBestFeatureToSplit(dataSet)
    bestFeatureLabel = Trainlabels[bestFeature - 1]
    #这里和书中不同,要-1
    tree = {bestFeatureLabel: {}}
    #结构初始化

    del (Trainlabels[bestFeature - 1])
    #已写入树结构的标签可以去掉了
    #这里和书中不同,要-1

    #以下步骤为基于目前的最佳分割特征来分割现有的数据集
    featureValues = [example[bestFeature] for example in dataSet]
    featureValuesSet = set(featureValues)
    for value in featureValues:
        subLabels = Trainlabels[:]
        tree[bestFeatureLabel][value] = createTree(
            splitDataSet(dataSet, bestFeature, value), subLabels)
        #用递归的方法建立嵌套字典
        #字典先成型的是最底下的叶节点,然后再自下而上往上层嵌套构造的整个树

    return tree
Example #6
0
def chooseBestFeatureToSplit(dataSet):
    from shannonEnt import calShannonEnt
    from splitDataSet import splitDataSet
    numOfFeature = len(dataSet[0]) - 1
    #减1是因为第一列是标签,不是特征
    baseEnrtopy = calShannonEnt(dataSet)
    #在子函数调用自制模组只有这样不报错...不懂
    bestInfoGain = 0.0
    bestFeature = -1
    #初始化
    for indexOfFeature in range(1, numOfFeature + 1):
        featureValueList = [example[indexOfFeature] for example in dataSet]
        featureValueSet = set(featureValueList)
        #取第IndexOfFeature个特征所右可能的取值
        newEntropy = 0.0
        for featureValue in featureValueSet:
            subDataSet = splitDataSet(dataSet, indexOfFeature, featureValue)
            prob = len(subDataSet) / float(len(dataSet))
            newEntropy += prob * calShannonEnt(subDataSet)
        infoGain = baseEnrtopy - newEntropy
        if (infoGain > bestInfoGain):
            bestInfoGain = infoGain
            bestFeature = indexOfFeature
    return bestFeature