def learn(self): self.running_time = time() current_attributes = [] while len(current_attributes) < len(self.attributes): while True: current_closure = aclosure(current_attributes, self.context) if current_attributes == current_closure: break implication = Implication(set(current_attributes), set(current_closure)) counterexample = (self.implication_expert. provide_counterexample(implication)) if counterexample is None: self.basis.append(implication) break else: self.context.add_object( _get_mask(sorted(counterexample), self.attributes), self.context.get_size()[0]) attributes_closure = lambda attributes_subset: sorted( lin_closure(set(attributes_subset), self.basis)) current_attributes = next_closure(current_attributes, self.attributes, attributes_closure) self.running_time = time() - self.running_time self.learning_statistics['running time'] = self.running_time self.learning_statistics['implication queries'] = ( self.implication_expert.implication_query_count) self.implication_expert.implication_query_count = 0
def setUp(self): 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'] self.cxt = fca.Context(ct, objs, attrs) self.basis = [Implication({'c', 'd'}, {'b'})]
def setUp(self): 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'] self.cxt = fca.Context(ct, objs, attrs) self.basis = [Implication(set(['c', 'd']), set(['b']))]
def is_member(self, attribute_subset): """ Checks whether the given subset of attributes is a model of actual implication basis. Args: attribute_subset: An object represented as a subset of attributes. Returns: True if the given subset of attributes is a model of actual implication basis and False otherwise. """ self.membership_query_count += 1 implication = Implication(attribute_subset, set()) for attribute in self.attributes: if attribute not in attribute_subset: implication = Implication(attribute_subset, {attribute}) if self.implication_expert.is_valid(implication): return False return True
def learn(self, max_iterations=None, verbose=False): """ Computes PAC-basis by interacting with MembershipEquivalenceExpert. Args: max_iterations: The maximum number of iterations for correction of the hypothetical basis. If None, then the number of iterations is not limited. verbose (default=False): Enable verbose output. """ self._verbose_learning = verbose self.running_time = time() self.pac_basis = [] while True: self._log_info( '%d. Hypothetical basis:' % (self.expert.approximately_equivalence_query_count + 1), self.pac_basis) counterexample = self.query_equivalence_counterexample() if counterexample is None: return 0 if _closed(counterexample, self.pac_basis): # Negative counterexample. self._log_info('Negative counterexample:', list(counterexample), end='\n\n') found = False for implication in self.pac_basis: premise = implication.premise new_premise = premise & counterexample if new_premise < premise and not self.expert.is_member( new_premise): implication.set_premise(new_premise) found = True break if not found: self.pac_basis.append( Implication(counterexample, set(self.attributes))) else: # Positive counterexample. self._log_info('Positive counterexample:', list(counterexample), end='\n\n') for implication in self.pac_basis: if not implication.is_respected(counterexample): implication.set_conclusion(implication.conclusion & counterexample) if (max_iterations and self.expert.approximately_equivalence_query_count > max_iterations): return 1
def updated_basis(intent, basis, attributes): valid = [] invalid = [] for imp in basis: if not imp.premise <= intent or imp.conclusion <= intent: valid.append(imp) else: invalid.append(imp) new_valid = [] for imp in invalid: new_imp = Implication(imp.premise, imp.conclusion & intent) add_smartly(new_imp, new_valid, valid) valid += new_valid new_valid = [] for imp in invalid: for a in attributes - intent: aset = set([a]) new_imp = Implication(imp.premise | aset, imp.conclusion | aset) if (remove_subsumed(new_imp, valid) and remove_subsumed_plus(new_imp, new_valid)): new_valid.append(new_imp) return valid + new_valid
def compute_implication_cover(cxt, close=closure_operators.closure): """ Compute an implication cover for a given *cxt* using an object-incremental algorithm """ attributes = set(cxt.attributes) basis = [Implication(set(), attributes.copy())] i = 0 for intent in cxt.examples(): i += 1 print 'object ', i # print_basis(basis) # print 'Adding ', intent # raw_input() basis = updated_basis(intent, basis, attributes) print len(basis), 'implications' return basis
def generalized_compute_dg_basis(attributes, aclose, close=closure_operators.simple_closure, imp_basis=[], cond=lambda x: True): """Compute the Duquenne-Guigues basis using optimized Ganter's algorithm. *aclose* is a closure operator on the set of attributes. We need this to implement the exploration algorithm with partially given examples. """ 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(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
def is_strongly_approximately_equivalent(self, hypothetical_basis, epsilon, delta): """ Checks whether the given basis is equivalent to the actual one with accuracy epsilon and confidence delta. This function tries to find a counterexample for hypothetical basis by checking random subsets of attributes generated at random uniformly. Args: hypothetical_basis: A basis to check. epsilon: The number from (0, 1) indicating the accuracy. delta: The number from (0, 1) indicating the confidence level. Returns: A counterexample if found, None otherwise. """ self.approximately_equivalence_query_count += 1 n = self.approximately_equivalence_query_count q = self.degree if self.mode == 'telescoping': num_attempts = math.log(n**q * (n + 1)**q / (delta * ((n + 1)**q - n**q))) / epsilon elif self.mode == 'pow2': num_attempts = (self.approximately_equivalence_query_count - math.log(delta)) / epsilon num_attempts = int(math.ceil(num_attempts)) for _ in xrange(num_attempts): random_subset = _select_random_uniform_subset(self.attributes) closed_random_subset = lin_closure(random_subset, hypothetical_basis) implication = Implication(random_subset, closed_random_subset) counterexample = self.implication_expert.provide_counterexample( implication) if counterexample: return counterexample if not self.is_member(closed_random_subset): return closed_random_subset return None
def generalized_dg_basis_iter(attributes, aclose, close=closure_operators.simple_closure, imp_basis=[], cond=lambda x: True): """Compute iterator over 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): basis_imp = Implication(a.copy(), a_closed.copy()) yield basis_imp relative_basis.append(basis_imp) if (a_closed - a) & set(attributes[:i]): a -= set(attributes[i:]) else: if len(a_closed) == len(attributes): break 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 | {m}, relative_basis + imp_basis) if not (b - a) & set(attributes[:j]): a = b i = j break
# 'Ansett Australia', 'The Australian Airlines Group', # 'British Midland', 'Lufthansa', 'Mexicana', # 'Scandinavian Airlines', 'Singapore Airlines', # 'Thai Airways International', 'United Airlines', # 'VARIG'] # attributes = ['Latin America', 'Europe', 'Canada', 'Asia Pasific', # 'Middle East', 'Africa', 'Mexico', 'Carribean', # 'United States'] # table = [[True, True, True, True, True, False, True, True, True], # [False, True, False, True, False, False, False, False, True], # [False, True, False, True, False, False, False, False, True], # [False, False, False, True, False, False, False, False, False], # [False, True, True, True, True, True, False, False, True], # [False, True, False, False, False, False, False, False, False], # [True, True, True, True ,True, True, True, False, True], # [True, False, True, False, False, False, True, True, True], # [True, True, False, True, False, True, False, False, True], # [False, True, True, True, True, True, False, False, True], # [True, True, False, True, False, False, False, True, True], # [True, True, True, True, False, False, True, True, True], # [True, True, False, True, False, True, True, False, True]] # cxt = fca.Context(table, objects, attributes) ct = [[True]] objs = ['1'] attrs = ['a'] cxt = fca.Context(ct, objs, attrs) imp_basis = compute_dg_basis(cxt, imp_basis=[Implication(set(), {'a'})]) for imp in imp_basis: print(imp)
def test_attribute_implications(self): self.attribute_implications = [ Implication(set([ 'Carribean', ]), set([ 'United States', 'Carribean', 'Latin America', ])), Implication(set([ 'Mexico', ]), set([ 'United States', 'Latin America', 'Mexico', ])), Implication( set([ 'Africa', ]), set([ 'Europe', 'United States', 'Asia Pasific', 'Africa', ])), Implication( set([ 'Middle East', ]), set([ 'Canada', 'Europe', 'Asia Pasific', 'United States', 'Middle East', ])), Implication(set([ 'United States', 'Asia Pasific', ]), set([ 'Europe', 'United States', 'Asia Pasific', ])), Implication(set([ 'Canada', ]), set([ 'Canada', 'United States', ])), Implication(set([ 'Europe', 'United States', ]), set([ 'Europe', 'United States', 'Asia Pasific', ])), Implication(set([ 'Europe', 'Asia Pasific', ]), set([ 'Europe', 'United States', 'Asia Pasific', ])), Implication( set([ 'Canada', 'Europe', 'Asia Pasific', 'Africa', 'United States', ]), set([ 'Canada', 'Europe', 'Asia Pasific', 'Africa', 'United States', 'Middle East', ])), Implication(set([ 'Latin America', ]), set([ 'United States', 'Latin America', ])), Implication( set([ 'United States', 'Carribean', 'Latin America', 'Mexico', ]), set([ 'Canada', 'United States', 'Carribean', 'Latin America', 'Mexico', ])), Implication( set([ 'Canada', 'United States', 'Latin America', ]), set([ 'Canada', 'United States', 'Latin America', 'Mexico', ])), Implication( set([ 'Europe', 'Asia Pasific', 'Africa', 'United States', 'Carribean', 'Latin America', ]), set([ 'Canada', 'Europe', 'Asia Pasific', 'Mexico', 'Africa', 'United States', 'Middle East', 'Carribean', 'Latin America', ])), ] imp_basis = compute_dg_basis(self.cxt) self.assertEqual(len(imp_basis), len(self.attribute_implications)) for imp in self.attribute_implications: self.assertTrue(imp in imp_basis)
def test_relative_basis(self): imp_basis = [Implication(set(), set(['c']))] relative_basis = compute_dg_basis(self.cxt, imp_basis=imp_basis) self.assertFalse(imp_basis[0] in relative_basis)
# 'British Midland', 'Lufthansa', 'Mexicana', # 'Scandinavian Airlines', 'Singapore Airlines', # 'Thai Airways International', 'United Airlines', # 'VARIG'] # attributes = ['Latin America', 'Europe', 'Canada', 'Asia Pasific', # 'Middle East', 'Africa', 'Mexico', 'Carribean', # 'United States'] # table = [[True, True, True, True, True, False, True, True, True], # [False, True, False, True, False, False, False, False, True], # [False, True, False, True, False, False, False, False, True], # [False, False, False, True, False, False, False, False, False], # [False, True, True, True, True, True, False, False, True], # [False, True, False, False, False, False, False, False, False], # [True, True, True, True ,True, True, True, False, True], # [True, False, True, False, False, False, True, True, True], # [True, True, False, True, False, True, False, False, True], # [False, True, True, True, True, True, False, False, True], # [True, True, False, True, False, False, False, True, True], # [True, True, True, True, False, False, True, True, True], # [True, True, False, True, False, True, True, False, True]] # cxt = fca.Context(table, objects, attributes) ct = [[True]] objs = ['1'] attrs = ['a'] cxt = fca.Context(ct, objs, attrs) imp_basis = compute_dg_basis(cxt, imp_basis=[Implication(set(), set(['a']))]) for imp in imp_basis: print imp