def test_add_concept_correct(self): space.init(4, {0: [0, 1], 1: [2, 3]}) s = Core([Cuboid([1, 2, 3, 4], [3, 4, 5, 6], { 0: [0, 1], 1: [2, 3] })], { 0: [0, 1], 1: [2, 3] }) dom = {0: 2, 1: 1} dim = {0: {0: 1, 1: 1}, 1: {2: 3, 3: 2.0}} w = Weights(dom, dim) f = Concept(s, 0.5, 2.0, w) space.add_concept(42, f) self.assertTrue(42 in space._concepts) self.assertEqual(space._concepts[42], f) self.assertFalse(42 in space._concept_colors) space.add_concept(43, f, 'r') self.assertTrue(43 in space._concepts) self.assertEqual(space._concepts[43], f) self.assertTrue(43 in space._concept_colors) self.assertEqual(space._concept_colors[43], 'r')
def one_shot(point, supercategory='none'): #todo find lowest concept '''print(point)''' for concept in space._concepts: '''print(concept) print('membership:') print(space._concepts[concept].membership_of(point)) print()''' if supercategory=='none': superkey = max(space._concepts,key= lambda candidate:space._concepts[candidate].membership_of(point)) else: superkey = supercategory supercategory = space._concepts[superkey] avg = lambda values: sum(values)/len(values) if len(values) else float('inf') #print([[cuboid._p_max[dim]-cuboid._p_min[dim] for cuboid in supercategory._core._cuboids if not cuboid._p_max[dim]==float('inf')]for dim in range(space._n_dim)]) avg_sizes=[avg([cuboid._p_max[dim]-cuboid._p_min[dim] for cuboid in supercategory._core._cuboids if not cuboid._p_max[dim]==float('inf')]) for dim in range(space._n_dim)] print('supercategory is:') print(superkey) print(avg_sizes) print() p_min = [point[i]-1/2*avg_sizes[i] for i in range(space._n_dim)] p_max = [point[i]+1/2*avg_sizes[i] for i in range(space._n_dim)] cuboid=Cuboid(p_min, p_max, space._domains)#not working in bigger examples core=Core([cuboid],space._domains) weights=Weights(space._def_dom_weights,space._def_dim_weights) concept=Concept(core, 1.0, 0.5, weights) return concept
def point_to_concept2(point, name, size=100000, weights=[]): domains = domains_from_point(point) p_min = [-size for value in point] p_max = [size for value in point] c_example = Cuboid(p_min, p_max, domains) s_example = Core([c_example], domains) if not weights: weights = space._def_dom_weights w_example = Weights(weights, space._def_dim_weights) concept = Concept(s_example, 1.0, C, w_example) space.add_concept(name, concept) return concept
def point_to_concept(point, name, weights=[]): domains = domains_from_point(point) p_min = [ value if not value == float('inf') else float('-inf') for value in point ] c_example = Cuboid(p_min, point, domains) s_example = Core([c_example], domains) if not weights: weights = space._def_dom_weights w_example = Weights(weights, space._def_dim_weights) concept = Concept(s_example, 1.0, C, w_example) space.add_concept(name, concept) return concept
def family_into_space(name, values, add=True): cuboids = [] domains = {} for point in values: subdomains = point_to_domains(point) cuboids.append( Cuboid([dim if not dim == float('inf') else -dim for dim in point], point, subdomains)) domains.update(subdomains) core = from_cuboids(cuboids, domains) weights = Weights(space._def_dom_weights, space._def_dim_weights) concept = Concept(core, 1.0, C, weights) if add: space.add_concept(name, concept) return concept
def concepts_into_space(concepts, domains={}, except_for=None, colors=['b','g','r','c','m','brown','rosybrown','darkslategrey','pink','grey']): if except_for: for concept in list(concepts.keys()): if concepts[concept]['supercategory']==except_for: del(concepts[concept]) ordered_dict={} for example in concepts: if concepts[example]['supercategory'] in ordered_dict: ordered_dict[concepts[example]['supercategory']].append(example) else: ordered_dict[concepts[example]['supercategory']]=[example] '''for key in ordered_dict: print(key)''' #ordered_dict={'mammal':ordered_dict['mammal']} #print(ordered_dict) colors=iter(colors) concept_colors={} if(domains=={}): for concept in concepts.values(): domains.update(concept) del(domains['supercategory']) #domains = mapping: domain->dimension indices domain_mapping = {} i=0 for key in domains: domain_mapping[key]=list(range(i,i+len(domains[key]))) i+=len(domains[key]) dimension_names = [] for domain in domains.values(): dimension_names += [dim for dim in domain.keys()] space.init(len(dimension_names),domain_mapping,dimension_names) for category in ordered_dict: print('putting',category,'into space') cuboids=[] domains = {} for example in ordered_dict[category]: if not is_consistent(concepts[example]): print(example,' is inconsistent') else: subdomains={domain:space._domains[domain] for domain in concepts[example] if not domain == 'supercategory'} point=[concepts[example].get(domain,{str(key):float("inf") for key in range(len(space._domains[domain]))}).values() for domain in space._domains] point=[p for dom in point for p in dom] #print(example) #print('point: ',point) cuboids.append(Cuboid([dim if not dim==float('inf') else -dim for dim in point], point, subdomains)) domains.update(subdomains) #print(cuboids[-1]._p_max) #for cuboid in cuboids: #print('cuboid:',cuboid) core=from_cuboids(cuboids,domains) weights=Weights(space._def_dom_weights,space._def_dim_weights) concept=Concept(core, 1.0, 0.5, weights) space.add_concept(category,concept,next(colors)) animal_concept=[] for concept in space._concepts.values(): animal_concept+=concept._core._cuboids #print('animal cubs:\n',animal_concept) core=from_cuboids(animal_concept,space._domains) weights=Weights(space._def_dom_weights,space._def_dim_weights) concept=Concept(core, 1.0, 0.5, weights) space.add_concept('animal',concept,next(colors))
ordered_dict[concepts[example]['supercategory']]=[example] for category in ordered_dict: print('putting',category,'into space') cuboids=[] domains = {} for example in ordered_dict[category]: if not is_consistent(concepts[example]): print(example,' is inconsistent') else: subdomains={domain:space._domains[domain] for domain in concepts[example] if not domain == 'supercategory'} point=[concepts[example].get(domain,{str(key):float("inf") for key in range(len(space._domains[domain]))}).values() for domain in space._domains] point=[p for dom in point for p in dom] #print(example) #print('point: ',point) cuboids.append(Cuboid([dim if not dim==float('inf') else -dim for dim in point], point, subdomains)) domains.update(subdomains) #print(cuboids[-1]._p_max) #for cuboid in cuboids: #print('cuboid:',cuboid) core=from_cuboids(cuboids,domains) weights=Weights(space._def_dom_weights,space._def_dim_weights) concept=Concept(core, 1.0, 0.5, weights) space.add_concept(category,concept,'orange') #print(space._concepts[concept].membership_of([p if not p==float('-inf') else 0 for p in p_min])) #print(space._concepts[concept].membership_of(p_max)) #print(bear.subset_of(space._concepts[concept])) '''print('amphibian:') print(space._concepts['amphibian'])''' ci.init()
from cs.cuboid import Cuboid from cs.core import Core from cs.concept import Concept import visualization.concept_inspector as ci # define the conceptual space domains = {"color": [0], "taste": [1, 2]} dimension_names = ["hue", "sour", "sweet"] space.init(3, domains, dimension_names) # define red property c_red = Cuboid([0.7, float("-inf"), float("-inf")], [1.0, float("inf"), float("inf")], {"color": [0]}) s_red = Core([c_red], {"color": [0]}) w_red = Weights({"color": 1.0}, {"color": {0: 1.0}}) red = Concept(s_red, 1.0, 40.0, w_red) space.add_concept("red", red, 'r') # define yellow property c_yellow = Cuboid([0.4, float("-inf"), float("-inf")], [0.6, float("inf"), float("inf")], {"color": [0]}) s_yellow = Core([c_yellow], {"color": [0]}) w_yellow = Weights({"color": 1.0}, {"color": {0: 1.0}}) yellow = Concept(s_yellow, 1.0, 40.0, w_yellow) space.add_concept("yellow", yellow, 'y') # define green property c_green = Cuboid([0.0, float("-inf"), float("-inf")], [0.3, float("inf"), float("inf")], {"color": [0]}) s_green = Core([c_green], {"color": [0]}) w_green = Weights({"color": 1.0}, {"color": {0: 1.0}})
from cs.concept import Concept import visualization.concept_inspector as ci # define the conceptual space domains = {"color": [0], "shape": [1], "taste": [2]} dimension_names = ["hue", "round", "sweet"] space.init(3, domains, dimension_names) # standard weights for the dimensions within each domain w_dim = {"color": {0: 1}, "shape": {1: 1}, "taste": {2: 1}} # define pear concept c_pear = Cuboid([0.5, 0.4, 0.35], [0.7, 0.6, 0.45], domains) s_pear = Core([c_pear], domains) w_pear = Weights({"color": 0.50, "shape": 1.25, "taste": 1.25}, w_dim) pear = Concept(s_pear, 1.0, 24.0, w_pear) space.add_concept("pear", pear, 'g') # define orange concept c_orange = Cuboid([0.8, 0.9, 0.6], [0.9, 1.0, 0.7], domains) s_orange = Core([c_orange], domains) w_orange = Weights({"color": 1.0, "shape": 1.0, "taste": 1.0}, w_dim) orange = Concept(s_orange, 1.0, 30.0, w_orange) space.add_concept("orange", orange, 'orange') # define lemon concept c_lemon = Cuboid([0.7, 0.45, 0.0], [0.8, 0.55, 0.1], domains) s_lemon = Core([c_lemon], domains) w_lemon = Weights({"color": 0.5, "shape": 0.5, "taste": 2.0}, w_dim) lemon = Concept(s_lemon, 1.0, 40.0, w_lemon) space.add_concept("lemon", lemon, 'y')
def two_cubs_PCA(point, sibblings, learn_weights=False): #sibbling is list of sibbling names or dict with sibbling names as keys #We can play around with artificial_scaling to see the effect of arbitrary generalization (<1 does not really mean more specific, but rather just smaller/conservative) artificial_scaling = 1 n_dims = len(point) if sibblings == None: #not implemented for some reason sibblings = get_sibblings(supercategory) variances = [] pc1s = [] #correlations=[] examples_x_stds = [] #Matrix examples x stds avg = np.average #lambda values: sum(values)/len(values) allcenters = [] for sibbling in sibblings: #centers of all cuboids of the sibbling concept centers = np.array([[ (p_max + p_min) / 2 for p_max, p_min in zip(cuboid._p_max, cuboid._p_min) ] for cuboid in space._concepts[sibbling]._core._cuboids]) #throw away concepts with less than 2 cuboids (not happening with dataset) if len(centers) > 1: allcenters.append(centers) #Centers are translated to data cloud that has std=1 in every dimension. stds remembers the multiplicative(eng?) part of the reverse operation #as simpler version compared to regression stds, data = normalize_to_standard_score(centers) examples_x_stds.append(stds) #np.cov input: rows=dimensions, columns=observations!! (very likely to produce error down the line if done wrong though) #np.linalg.eig output: values=eigenvalues, vectors=eigenvectors in columns!! (no error when done wrong because square matrix!) values, vectors = np.linalg.eig(np.cov(data.T)) #the first PC has unit length so multiplying it with std lets it have (euclidean) length=std (in direction of largest var) pc1s.append( np.array(vectors[:, np.argmax(values)]) * (max(values)**(1 / 2))) #The sign of a whole PC is only meaningfull in relation to the other PCs, so we assume that all first PCs point in a somewhat similar direction. Size is ignored. pc1s = brush_vectors(np.array(pc1s)) #makes signs point in a direction so that the size dimension still correlate with each other over all examples pc1s = brush_to_size(pc1s) #A dimension of a PC that is zero because the original values where all undefined is considered uninformative, since examples #that have an undefined value lead to a concept with no variance in that dimension anyways meanpc = [] for dimension, dimindex in zip(pc1s.T, range(len(pc1s.T))): #all meaningfull values of the 1st PCs of all known concepts in a single dimension cleanvalues = [] for value, conceptindex in zip(dimension, range(len(dimension))): #print([np.isnan(examplevalue[dimindex]) for examplevalue in allcenters[conceptindex]]) #print(conceptindex) if not value == 0: cleanvalues.append(value) #a variance of 0 in a certain dimension in the first PC can be due to all known examples of a category being undefined in that dimension #the other way round this implies that some values have not been included because of the wrong reasons beforehand elif not all([ np.isnan(examplesvalues[dimindex]) for examplesvalues in allcenters[conceptindex] ]): cleanvalues.append(value) if len(cleanvalues): #quite some information is lost in this step (PCs canceling out each other because of wrong reasons), but we need to generalize meanpc.append(sum(cleanvalues) / len(cleanvalues)) else: #Should not happen, since uninformative dimensions have already been kicked out. If it happens anyways, zero is actually the correct value #(i.e. no variance in dim with only undefined values) meanpc.append(0) meanstds = np.average(examples_x_stds, axis=0) #for some reason i=0 happens quite often, although the docu promises that real values are used in these cases meanpc = [np.real(val) for val in meanpc] #We have our background knowledge. Nice! Multiplying with the mean 'size' in each dimension is improvable (multiplicative part of regression would be better) learnt_vector = meanstds * meanpc #start building our new concept cub1 = np.zeros(n_dims) cub2 = np.zeros(n_dims) for dim in range(n_dims): #point as central region, multiply by two to reverse taking center of cuboids cub1[dim] = point[dim] - learnt_vector[dim] * 2 * artificial_scaling cub2[dim] = point[dim] + learnt_vector[dim] * 2 * artificial_scaling c1_p_min = [ cub1[dim] if cub1[dim] < point[dim] else float('-inf') if point[dim] == float('inf') else point[dim] for dim in range(n_dims) ] c1_p_max = [ cub1[dim] if cub1[dim] > point[dim] else point[dim] for dim in range(n_dims) ] c2_p_min = [ cub2[dim] if cub2[dim] < point[dim] else float('-inf') if point[dim] == float('inf') else point[dim] for dim in range(n_dims) ] c2_p_max = [ cub2[dim] if cub2[dim] > point[dim] else point[dim] for dim in range(n_dims) ] domains = domains_from_point(c1_p_max) core = Core([ Cuboid(c1_p_min, c1_p_max, domains), Cuboid(c2_p_min, c2_p_max, domains) ], domains) if not learn_weights: dom_weights = space._def_dom_weights else: #dramatically improves performance, but seems unfair to compare to classes with meaningless weights dom_weights = {} for domain in domain_mapping: variance = np.average( [abs(meanpc[dim]) for dim in domain_mapping[domain]]) + 0.1 dom_weights[domain] = (1 / variance)**100 weights = Weights(dom_weights, space._def_dim_weights) concept = Concept(core, 1.0, C, weights) return concept