Exemplo n.º 1
0
def horn1(formal_concept,
          closure_operator,
          membership_oracle,
          equivalence_oracle=None):
    """Computes DG Basis for a given set of attributes using horn1 algorithm
    """
    hypothesis = set()
    # NOTE: counter_example is a set
    while True:
        # sample `hypothesis` => set([a, e, d => c, b])
        counter_example = equivalence_oracle(hypothesis, formal_concept,
                                             membership_oracle,
                                             closure_operator)
        # terminating condition
        if counter_example['value'] is None:
            break

        # starting edge case
        if len(hypothesis) == 0:
            hypothesis.add(
                imp.Implication(frozenset(counter_example['value']),
                                frozenset(formal_concept.context.attributes)))
            continue

        for implication in hypothesis.copy():
            # if an implication doesn't repect the counter example,
            # modify it's conclusion (also called strengthening)
            if not implication.is_respected(counter_example['value']):
                hypothesis.remove(implication)
                hypothesis.add(
                    imp.Implication(
                        frozenset(implication.premise),
                        frozenset(
                            implication.conclusion.intersection(
                                counter_example['value']))))
            else:
                # special_implication (A --> B) is the first implication
                # such that it's premise(A) is not a subset of
                # counter_example(C) and member(C ∩ A) is false. The latter
                # condition can also be interpreted as C ∩ A is not a model
                # of context(K)
                special_implication = imp.findSpecialImplication(
                    hypothesis, membership_oracle, closure_operator,
                    counter_example['value'])
                if special_implication:
                    hypothesis.remove(special_implication)
                    hypothesis.add(
                        imp.Implication(
                            frozenset(counter_example['value'].intersection(
                                special_implication.premise)),
                            frozenset(
                                special_implication.conclusion.union(
                                    special_implication.premise.difference(
                                        counter_example['value'])))))
                else:
                    hypothesis.add(
                        imp.Implication(
                            counter_example['value'],
                            set(formal_concept.context.attributes)))
    return hypothesis
Exemplo n.º 2
0
def process_modified_concept(p, m, min_mod_impl, mod_concepts, new_preclosed):
    # p is of the form (extent, intent)
    for i in min_mod_impl:
        if i.premise <= p[1]:  # p[1] is no longer preclosed
            break
    else:  # p[1] becomes psuedo-closed
        impl = imp.Implication(p[1].copy(), p[1].copy())
        impl.get_conclusion().add(m)
        min_mod_impl.append(impl)
        new_preclosed.append((p[0], impl.premise, impl))
    p[1].add(m)
    mod_concepts.append(p)
Exemplo n.º 3
0
def process_stable_concept(p, m, extent, new_stable_impl, new_preclosed,
                           closure):
    # p is of the form (extent, intent)
    new_extent = p[0] & extent
    new_premise = p[1].copy()
    new_premise.add(m)
    for i in new_stable_impl:
        if not i.is_respected(new_premise):
            break
    else:
        new_conclusion = closure(new_premise)
        if new_conclusion == new_premise:
            new_preclosed.append((new_extent, new_premise))
        else:
            impl = imp.Implication(new_premise, new_conclusion)
            new_stable_impl.append(impl)
            new_preclosed.append((new_extent, impl.premise, impl))
Exemplo n.º 4
0
def generalizedComputeDgBasis(attributes,
                              aclose,
                              close=closure_operators.simple_closure,
                              imp_basis=[],
                              cond=lambda x: True):
    """Computes the Duquenne-Guigues basis using optimized Ganter's algorithm.

    `aclose` is a closure operator on the set of attributes.
    """
    relative_basis = []

    a = close(set(), imp_basis)
    i = len(attributes)

    while len(a) < len(attributes):
        a_closed = set(aclose(a))
        if a != a_closed and cond(a):
            relative_basis.append(imp.Implication(a.copy(), a_closed.copy()))
        if (a_closed - a) & set(attributes[:i]):
            a -= set(attributes[i:])
        else:
            if len(a_closed) == len(attributes):
                return relative_basis
            a = a_closed
            i = len(attributes)
        for j in range(i - 1, -1, -1):
            m = attributes[j]
            if m in a:
                a.remove(m)
            else:
                b = close(a | set([m]), relative_basis + imp_basis)
                if not (b - a) & set(attributes[:j]):
                    a = b
                    i = j
                    break
    return relative_basis
Exemplo n.º 5
0
def pac_basis(formal_concept,
              closure_operator,
              membership_oracle,
              epsilon=0.1,
              delta=0.1):
    hypothesis = set()
    # NOTE: counter_example is a set
    i = 0  # number of queries
    spec = 0
    weak = 0
    no_resp = 0
    t_spec = 0
    t_weak = 0
    t_no_resp = 0
    while True:
        counter_example = oracle.approx_equivalent(set(hypothesis),
                                                   membership_oracle,
                                                   formal_concept,
                                                   closure_operator, i, {
                                                       'no_resp': no_resp,
                                                       'spec': spec,
                                                       'weak': weak
                                                   }, epsilon, delta)

        if counter_example['value'] is None:
            # TODO: Remove this
            print('# equivalence queries: {0}, # disrespect trigger: {3},\
 # special trigger: {1}, # weak triggers: {2}'.format(i, t_spec, t_weak,
                                                      t_no_resp))
            break

        if len(hypothesis) == 0:
            hypothesis.add(
                imp.Implication(counter_example['value'],
                                set(formal_concept.context.attributes)))
            continue

        i += 1
        for implication in hypothesis.copy():
            # if an implication doesn't repect the counter example,
            # modify it's conclusion (also called strengthening)
            if not implication.is_respected(counter_example['value']):
                hypothesis.remove(implication)
                hypothesis.add(
                    imp.Implication(
                        implication.premise,
                        implication.conclusion.intersection(
                            counter_example['value'])))
                no_resp += 1
                t_no_resp += 1
                weak = 0
                spec = 0
            else:
                # special_implication (A --> B) is the first implication
                # such that it's premise(A) is not a subset of
                # counter_example(C) and member(C ∩ A) is false. The latter
                # condition can also be interpreted as C ∩ A is not a model
                # of context(K)
                special_implication = imp.findSpecialImplication(
                    hypothesis, membership_oracle, closure_operator,
                    counter_example['value'])
                if special_implication:
                    hypothesis.remove(special_implication)
                    hypothesis.add(
                        imp.Implication(
                            counter_example['value'].intersection(
                                special_implication.premise),
                            special_implication.conclusion.union(
                                special_implication.premise.difference(
                                    counter_example['value']))))
                    spec += 1
                    t_spec += 1
                    no_resp = 0
                    weak = 0
                else:
                    hypothesis.add(
                        imp.Implication(
                            counter_example['value'],
                            set(formal_concept.context.attributes)))
                    weak += 1
                    t_weak += 1
                    no_resp = 0
                    spec = 0
    return hypothesis