def clean_cxt(cxt: fca.Context,
              min_att_extent: int = None,
              min_att_len: int = None) -> fca.Context:
    if (min_att_extent and min_att_extent > 1) or (min_att_len):
        to_del = []
        for att in cxt.attributes:
            if ((min_att_extent and len(cxt.aprime([att])) < min_att_extent)
                    or (min_att_len and len(att) < min_att_len)):
                to_del.append(att)
        cxt.delete_attributes(to_del)
    return cxt
Exemple #2
0
    def __init__(self, x_table, q_table, objects, attributes):
        """
        Create a partial context from cross and question tables
        and list of objects, list of attributes.

        cross_table_x - the list of bool lists representing first context
            (only x in context)
        cross_table_q - the list of bool lists representing second context
            (only questions(q) in context)
                cross_table_x \subseteq cross_table_q
        objects - the list of objects
        attributes - the list of attributes
        """
        if not subseteq_table(x_table, q_table):
            raise ValueError('x table should be \subseteq q table')
        else:
            self.objects = copy(objects)
            self.attributes = copy(attributes)
            self.x_context = Context(x_table, objects[:], self.attributes[:])
            self.q_context = Context(q_table, objects[:], self.attributes[:])
Exemple #3
0
    def __init__(self, x_table, q_table, objects, attributes):
        """
        Create a partial context from cross and question tables
        and list of objects, list of attributes.

        cross_table_x - the list of bool lists representing first context
            (only x in context)
        cross_table_q - the list of bool lists representing second context
            (only questions(q) in context)
                cross_table_x \subseteq cross_table_q
        objects - the list of objects
        attributes - the list of attributes
        """
        if not subseteq_table(x_table, q_table):
            raise ValueError('x table should be \subseteq q table')
        else:
            self.objects = copy(objects)
            self.attributes = copy(attributes)
            self.x_context = Context(x_table, objects[:], self.attributes[:])
            self.q_context = Context(q_table, objects[:], self.attributes[:])
Exemple #4
0
class PartialContext(object):
    """
    A Partial Context consists of two sets: *objects* and *attributes*
    and of a ternary (x, q) relation between them.
    """
    def __init__(self, x_table, q_table, objects, attributes):
        """
        Create a partial context from cross and question tables
        and list of objects, list of attributes.

        cross_table_x - the list of bool lists representing first context
            (only x in context)
        cross_table_q - the list of bool lists representing second context
            (only questions(q) in context)
                cross_table_x \subseteq cross_table_q
        objects - the list of objects
        attributes - the list of attributes
        """
        if not subseteq_table(x_table, q_table):
            raise ValueError('x table should be \subseteq q table')
        else:
            self.objects = copy(objects)
            self.attributes = copy(attributes)
            self.x_context = Context(x_table, objects[:], self.attributes[:])
            self.q_context = Context(q_table, objects[:], self.attributes[:])

    def __deepcopy__(self, memo):
        return PartialContext(deepcopy(self.x_context.table, memo),
                              deepcopy(self.q_context.table, memo),
                              self.objects[:],
                              self.attributes[:])

    def transpose(self):
        """ Return new partial context with transposed x and q contexts """
        new_objects = self.attributes[:]
        new_attributes = self.objects[:]
        new_x_table = []
        new_q_table = []
        for j in range(len(self.attributes)):
            x_line = []
            q_line = []
            for i in range(len(self.objects)):
                x_line.append(self.x_context.table[i][j])
                q_line.append(self.q_context.table[i][j])
            new_x_table.append(x_line)
            new_q_table.append(q_line)
        return PartialContext(new_x_table, new_q_table, new_objects, new_attributes)

    def __repr__(self):
        output = ", ".join([str(a) for a in self.attributes]) + "\n"
        output += ", ".join([str(o) for o in self.objects]) + "\n"
        for o in self.objects:
            output += "\n"
            output += self._intent_to_str(self.x_context.get_object_intent(o),
                                          self.q_context.get_object_intent(o))
        return output
        
    def _intent_to_str(self, xintent, qintent):
        line = ""
        for a in self.attributes:
            if a in xintent:
                line += "X"
            elif a in qintent:
                line += "?"
            else:
                line += "."
        return line
        

    def xq_aclosure(self, aset):
        """ +? closure for Partial context """
        oset = aprime(aset, self.x_context)
        return oprime(oset, self.q_context)

    def get_attribute_implications(self,
                                   basis=compute_partial_dg_basis,
                                   confirmed=[],
                                   cond=lambda x: True):
        return basis(self, imp_basis=confirmed, cond=cond)

    def add_object_with_intent(self, intent, name):
        if not intent[0] <= intent[1]:
            raise ValueError('inconsistent partial example')
        self.x_context.add_object_with_intent(intent[0], name)
        self.q_context.add_object_with_intent(intent[1], name)
        self.objects.append(name)
        
    def complete(self, implications):
        for o in self.objects:
            xintent = self.x_context.get_object_intent(o)
            new_xintent = closure(xintent, implications)
            qintent = self.q_context.get_object_intent(o)
            if not new_xintent <= qintent:
                # TODO: undo the modifications
                raise ValueError(
                    'implications are inconsistent with the partial context')
            self.x_context.set_object_intent(new_xintent, o)
            new_qintent = set([a for a in qintent
                                 if a in new_xintent or
                                 closure(new_xintent | {a}, implications)
                                                                    <= qintent
                             ])
            self.q_context.set_object_intent(new_qintent, o)
            # TODO: Remove printing
            if xintent != new_xintent or qintent != new_qintent:
                print('Object', o)
                print(self._intent_to_str(xintent, qintent))
                print('completed to ')
                print(self._intent_to_str(new_xintent, new_qintent))
            
    def intents(self):
        for obj in self.objects:
            yield (self.x_context.get_object_intent(obj),
                   self.q_context.get_object_intent(obj))
Exemple #5
0
    if indexes:
        if mode == "part":
            ret = _filter_part(lattice, indexes, opt)
        elif mode == "abs":
            ret = _filter_abs(lattice, indexes, opt)
        elif mode == "value":
            ret = _filter_value(lattice, indexes, opt)
    return ret


if __name__ == '__main__':
    # Test code
    from fca import ConceptLattice, Context
    from .probability import compute_probability
    from .stability import (compute_estability, compute_istability)
    from .separation import compute_separation_index

    ct = [[True, False, False, True], [True, False, True, False],
          [False, True, True, False], [False, True, True, True]]
    objs = ['1', '2', '3', '4']
    attrs = ['a', 'b', 'c', 'd']
    c = Context(ct, objs, attrs)
    cl = ConceptLattice(c)
    #    compute_index(cl, compute_probability, "Probability")
    #    cs = filter_concepts(cl, compute_probability, "abs", 4)
    #    compute_index(cl, compute_separation_index, "Separation")
    #    cs = filter_concepts(cl, compute_probability, "value", 0.5)
    # compute_index(cl, compute_istability, "Intensional Stability")
    # print cl
    cs = filter_concepts(cl, compute_istability, "abs", 2)
    print(cs)
Exemple #6
0
class PartialContext(object):
    """
    A Partial Context consists of two sets: *objects* and *attributes*
    and of a ternary (x, q) relation between them.
    """
    def __init__(self, x_table, q_table, objects, attributes):
        """
        Create a partial context from cross and question tables
        and list of objects, list of attributes.

        cross_table_x - the list of bool lists representing first context
            (only x in context)
        cross_table_q - the list of bool lists representing second context
            (only questions(q) in context)
                cross_table_x \subseteq cross_table_q
        objects - the list of objects
        attributes - the list of attributes
        """
        if not subseteq_table(x_table, q_table):
            raise ValueError('x table should be \subseteq q table')
        else:
            self.objects = copy(objects)
            self.attributes = copy(attributes)
            self.x_context = Context(x_table, objects[:], self.attributes[:])
            self.q_context = Context(q_table, objects[:], self.attributes[:])

    def __deepcopy__(self, memo):
        return PartialContext(deepcopy(self.x_context._table, memo),
                              deepcopy(self.q_context._table, memo),
                              self.objects[:], self.attributes[:])

    def transpose(self):
        """ Return new partial context with transposed x and q contexts """
        new_objects = self.attributes[:]
        new_attributes = self.objects[:]
        new_x_table = []
        new_q_table = []
        for j in xrange(len(self.attributes)):
            x_line = []
            q_line = []
            for i in xrange(len(self.objects)):
                x_line.append(self.x_context._table[i][j])
                q_line.append(self.q_context._table[i][j])
            new_x_table.append(x_line)
            new_q_table.append(q_line)
        return PartialContext(new_x_table, new_q_table, new_objects,
                              new_attributes)

    def __repr__(self):
        output = ", ".join([str(a) for a in self.attributes]) + "\n"
        output += ", ".join([str(o) for o in self.objects]) + "\n"
        for o in self.objects:
            output += "\n"
            output += self._intent_to_str(self.x_context.get_object_intent(o),
                                          self.q_context.get_object_intent(o))
        return output

    def _intent_to_str(self, xintent, qintent):
        line = ""
        for a in self.attributes:
            if a in xintent:
                line += "X"
            elif a in qintent:
                line += "?"
            else:
                line += "."
        return line

    def xq_aclosure(self, aset):
        """ +? closure for Partial context """
        oset = aprime(aset, self.x_context)
        return oprime(oset, self.q_context)

    def get_attribute_implications(self,
                                   basis=compute_partial_dg_basis,
                                   confirmed=[],
                                   cond=lambda x: True):
        return basis(self, imp_basis=confirmed, cond=cond)

    def add_object_with_intent(self, intent, name):
        if not intent[0] <= intent[1]:
            raise ValueError('inconsistent partial example')
        self.x_context.add_object_with_intent(intent[0], name)
        self.q_context.add_object_with_intent(intent[1], name)
        self.objects.append(name)

    def complete(self, implications):
        for o in self.objects:
            xintent = self.x_context.get_object_intent(o)
            new_xintent = closure(xintent, implications)
            qintent = self.q_context.get_object_intent(o)
            if not new_xintent <= qintent:
                # TODO: undo the modifications
                raise ValueError(
                    'implications are inconsistent with the partial context')
            self.x_context.set_object_intent(new_xintent, o)
            new_qintent = set([
                a for a in qintent if a in new_xintent
                or closure(new_xintent | set([a]), implications) <= qintent
            ])
            self.q_context.set_object_intent(new_qintent, o)
            # TODO: Remove printing
            if xintent != new_xintent or qintent != new_qintent:
                print 'Object', o
                print self._intent_to_str(xintent, qintent)
                print 'completed to '
                print self._intent_to_str(new_xintent, new_qintent)

    def intents(self):
        for obj in self.objects:
            yield (self.x_context.get_object_intent(obj),
                   self.q_context.get_object_intent(obj))