示例#1
0
def generateTree(training, gain, objectiveValues, attributes = None):

    usedAttributes = []
    if attributes == None:
        remainingAttributes = copy(attributeNames)
    else:
        remainingAttributes = copy(attributes)
    root = Node(None)
    root.height = 0
    F = deque([root])
    E = [root]
    while len(F) > 0:
        curr = F.popleft()
        
        auxData = training
        for filter in curr.filters:
            auxData = auxData[ auxData[filter[0]] == filter[1]]
        gainsPerAttribute = {}
        if len(remainingAttributes) > 0:
            for aName in remainingAttributes:
                gainsPerAttribute[aName] = gain(training, [], obj, aName)
            currAttName = max(gainsPerAttribute, key=lambda key: gainsPerAttribute[key])
            remainingAttributes = [att for att in remainingAttributes if att != currAttName]
            curr.value = currAttName
            attValues = list(data[currAttName].unique())
            # print(auxData)
            for v in attValues:
                child = Node(curr)
                child.height = curr.height + 1
                child.filters = copy(curr.filters)
                child.filters.append([currAttName, v])
                childAuxData = auxData[auxData[currAttName] == v]
                # En este caso el subset para este nodo tiene ejemplos,
                # es decir, hay casos que cumplen con este filtro
                # más específico
                if len(childAuxData) != 0:
                    ## Acá me fijo si todos los elementos del conjunto 
                    ## que me queda agregándole el filtro de este nodo
                    ## son del mismo valor del objetivo -> el nodo es hoja
                    leaf = False
                    for ov in objectiveValues:
                        if len(childAuxData[childAuxData[obj] == ov]) == len(childAuxData):
                            leaf = True
                            break
                    if leaf:
                        child.value = ov
                    else:
                        F.append(child)
                # En este caso, no hay nodos que cumplan con este nuevo filtro:
                # se crea una hoja cuyo valor es el más frecuente del atributo
                # objetivo en el conjunto del padre
                else:
                    child.value = findMostFrequentObjectiveValue(auxData, obj, objectiveValues)
                
                curr.children[v] = child
                E.append(child)
        # Si no me quedan atributos, los nodos que quedan son hojas
        else:
            curr.value = findMostFrequentObjectiveValue(auxData, obj, objectiveValues)
    return root