def create_production_svg_rect(data, show_stimuli=True, offset_x=0, offset_y=0): import rectlang rectlang_space = rectlang.Space( (8, 8), solutions_file='../data/8x8_solutions.json') svg = '<g id="partition">\n\n' for cat_i in np.unique(data): color = colors.categories[cat_i] cat_rects = rectlang_space.compress_concept(data == cat_i)[1] for (y, x), _, _, _, (h, w) in cat_rects: box_x = offset_x + (x * 500) box_y = offset_y + (y * 500) box_w = w * 500 box_h = h * 500 svg += "\t\t\t<rect x='%s' y='%s' width='%s' height='%s' style='fill:%s; stroke-width:0.1; stroke:%s' />\n" % ( str(box_x), str(box_y), str(box_w), str(box_h), color, color) if show_stimuli: for stim_i, (y, x) in enumerate(np.ndindex(data.shape)): radius, angle = radiuses[x], angles[y] loc_x, loc_y = x * 500 + 250 + offset_x, (y + 1) * 500 - 250 + offset_y box_x, box_y = x * 500 + offset_x, y * 500 + offset_y line_x, line_y = radius * np.cos(angle) + loc_x, radius * np.sin( angle) + loc_y svg += '\t<g id="stimulus-%i">\n' % stim_i svg += '\t\t<circle cx="%i" cy="%i" r="%i" style="stroke:black; stroke-width:10; fill:none;" />\n' % ( loc_x, loc_y, radius) svg += '\t\t<line x1="%i" y1="%i" x2="%f" y2="%f" style="stroke: black; stroke-width:10;" />\n' % ( loc_x, loc_y, line_x, line_y) svg += '\t</g>\n\n' svg += '</g>\n\n' return svg
def simulate(axis, shape, nsims, maxcats, xlim, ylim): c_space = commcost.Space(shape) r_space = rectlang.Space(shape) for n_cats in range(2, maxcats + 1): color = str(((maxcats + 2) - (n_cats - 1)) / (maxcats + 2)) X, Y = [], [] for i in range(nsims): _, part = commcost.random_partition(shape, n_cats, True) comp = r_space.complexity(part) cost = c_space.cost(part) if comp < xlim[1] and cost > ylim[0]: X.append(comp) Y.append(cost) _, part = commcost.random_partition(shape, n_cats, False) comp = r_space.complexity(part) cost = c_space.cost(part) if comp < xlim[1] and cost > ylim[0]: X.append(comp) Y.append(cost) axis.scatter(X, Y, color=color) return X, Y
def transform_paper3_data(): r_space = rectlang.Space((6, 8)) c_space = commcost.Space((6, 8)) old_new = { 0: (1, 3), 1: (0, 2), 2: (0, 6), 3: (2, 5), 4: (5, 1), 5: (3, 7), 6: (0, 5), 7: (5, 7), 8: (4, 2), 9: (5, 2), 10: (4, 0), 11: (0, 0), 12: (5, 6), 13: (4, 3), 14: (1, 4), 15: (4, 4), 16: (1, 1), 17: (4, 1), 18: (2, 4), 19: (5, 4), 20: (4, 5), 21: (3, 0), 22: (5, 5), 23: (3, 3), 24: (2, 6), 25: (3, 5), 26: (0, 4), 27: (0, 7), 28: (2, 1), 29: (3, 1), 30: (3, 4), 31: (3, 2), 32: (4, 6), 33: (1, 2), 34: (0, 1), 35: (3, 6), 36: (1, 7), 37: (1, 0), 38: (4, 7), 39: (2, 2), 40: (2, 7), 41: (2, 0), 42: (1, 5), 43: (1, 6), 44: (5, 0), 45: (5, 3), 46: (2, 3), 47: (0, 3) } data = {'chains': []} for chain in ['I', 'J', 'K', 'L']: chain_data = {'chain_id': chain, 'generations': []} for generation in range(11): lang = np.full((6, 8), -1, dtype=int) words = {} with open('/Users/jon/Code/flatlanders/data/experiment_3/%s/%is' % (chain, generation)) as file: for i, line in enumerate(file): word = line.split('\t')[0] if word in words: words[word].append(i) else: words[word] = [i] for cat, (key, values) in enumerate(words.items(), 0): for value in values: coord = old_new[value] lang[coord] = cat comp = r_space.complexity(lang) cost = c_space.cost(lang) chain_data['generations'].append({ 'prod_cost': cost, 'prod_complexity': comp }) data['chains'].append(chain_data) print(data)
Code for simulating the complexity and cost of randomly generated languages. This was not included in the paper; refer to my thesis instead. ''' import pickle import numpy as np import matplotlib.pyplot as plt import commcost import rectlang import tools import colors plt.rcParams['svg.fonttype'] = 'none' rectlang_space = rectlang.Space((8,8)) commcost_space = commcost.Space((8,8)) commcost_space_discrete = commcost.Space((8,8), gamma=99999) def save_results(array, filename): with open(filename, mode='wb') as file: pickle.dump(array, file) def restore_results(filename): with open(filename, mode='rb') as file: array = pickle.load(file) return array def sim_all_cats(n_sims, shape, convex=False): complexy_results = np.zeros((64, n_sims), dtype=float) commcost_results = np.zeros((64, n_sims), dtype=float)
''' Converts the raw results from chains.json into the same JSON format used by the model. Produces similar output to model_process.py ''' import json import numpy as np import rectlang import commcost import varofinf import tools shape = (8,8) rectlang_space = rectlang.Space(shape, solutions_file='../data/8x8_solutions.json') commcost_space = commcost.Space(shape) def raw_model_results_to_json_files(input_file, output_file): results = {'bottleneck':2, 'exposures':4, 'chains':[]} data = tools.read_json_lines(input_file) for chain in data: chain_data = {'chain_id':chain['chain_id'], 'first_fixation':chain['first_fixation'], 'generations':[]} for gen_i, generation in enumerate(chain['generations']): generation_data = {'generation_number':gen_i, 'productions':generation['partition'], 'data_out':[]} productions = np.array(generation['partition'], dtype=int).reshape((8,8)) for stim_i in generation['training_out']: meaning = (stim_i // shape[0], stim_i % shape[1]) signal = int(productions[meaning]) generation_data['data_out'].append((meaning, signal)) generation_data['prod_expressivity'] = len(np.unique(productions)) generation_data['prod_cost'] = commcost_space.cost(productions)
''' from os import path, remove import numpy as np import rectlang import colors import tools radiuses = [25, 50, 75, 100, 125, 150, 175, 200] angles = [2.5656, 3.0144, 3.4632, 3.912, 4.3608, 4.8096, 5.2583, 5.7072] letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' scale_factor = 16 figure_width = 5.5 #inches rectlang_space = rectlang.Space((4, 4)) def draw_language(language, offset_x, offset_y, chain, generation, show_stimuli=False, rect_compress=True, accepted=True): if rect_compress: return draw_language_rects(language, offset_x, offset_y, chain, generation, show_stimuli, accepted) return draw_language_cells(language, offset_x, offset_y, chain, generation, show_stimuli, accepted)
def __init__(self, shape=(8, 8), maxcats=4, prior='simplicity', weight=1.0, noise=0.05, exposures=4, mcmc_iterations=5000): if not isinstance(shape, tuple) or len(shape) != 2: raise ValueError( 'shape should be a tuple containing the height and width') if not isinstance(shape[0], int) or shape[0] < 1: raise ValueError('height must be positive integer') if not isinstance(shape[1], int) or shape[1] < 1: raise ValueError('width must be postive integer') self._shape = shape self._size = np.product(shape) self._cells, self._rects = self._generate_cells_and_rects() if not isinstance(maxcats, int) or maxcats < 1 or maxcats > self._size: raise ValueError( 'Invalid maxcats: Should be int between 1 and %i' % self._size) self._maxcats = maxcats if prior == 'simplicity': self._prior_grid = rectlang.Space(self._shape, rotational_invariance, max_exhaustive_size, max_beam_width) self._prior_func = self._prior_grid.complexity elif prior == 'informativeness': self._prior_grid = commcost.Space(self._shape, gamma=gamma, mu=mu) self._prior_func = self._prior_grid.cost elif not callable(prior): raise ValueError( 'Invalid prior: Use \'simplicity\' or \'informativeness\', or pass a callable function' ) else: self._prior_func = prior if not isinstance(weight, (float, int)): raise ValueError('Invalid weight: Should be float or int') self._weight = weight if not isinstance(noise, float) or noise < 0 or noise > 1: raise ValueError('Invalid noise: Should be float between 0 and 1') self._noise = noise if not isinstance(exposures, int) or exposures < 1: raise ValueError('Invalid exposures: Should be int greater than 0') self._exposures = exposures if not isinstance(mcmc_iterations, int) or mcmc_iterations < 1000: raise ValueError( 'Invalid mcmc_iterations: Should be int greater than or equal to 1000' ) self._mcmc_iterations = mcmc_iterations self._prob_correct = np.log2(1.0 - self._noise) self._prob_incorrect = np.log2(self._noise / (self._maxcats - 1)) self.language = None
def __init__(self, generations=10, shape=(8, 8), mincats=1, maxcats=4, prior='simplicity', weight=1.0, noise=0.05, bottleneck=2, exposures=4, mcmc_iterations=5000): if not isinstance(generations, int) or generations < 1: raise ValueError( 'Invalid generations: Should be int greater than 0') self._generations = generations if not isinstance(shape, tuple) or len(shape) != 2: raise ValueError( 'shape should be a tuple containing the height and width') if not isinstance(shape[0], int) or shape[0] < 1: raise ValueError('height must be positive integer') if not isinstance(shape[1], int) or shape[1] < 1: raise ValueError('width must be postive integer') self._shape = shape self._size = np.product(shape) if not isinstance(mincats, int) or mincats < 1 or mincats > self._size: raise ValueError( 'Invalid mincats: Should be int between 1 and %i' % self._size) self._mincats = mincats if not isinstance( maxcats, int) or maxcats < self._mincats or maxcats > self._size: raise ValueError( 'Invalid maxcats: Should be int between %i and %i' % (self._mincats, self._size)) self._maxcats = maxcats self._rectlang_grid = rectlang.Space(self._shape, rotational_invariance, max_exhaustive_size, max_beam_width) self._commcost_grid = commcost.Space(self._shape, gamma=gamma, mu=mu) if prior == 'simplicity': self._prior_func = self._rectlang_grid.complexity elif prior == 'informativeness': self._prior_func = self._commcost_grid.cost elif not callable(prior): raise ValueError( 'Invalid prior: Use \'simplicity\' or \'informativeness\', or pass a callable function' ) else: self._prior_func = prior self._prior = str(prior) if not isinstance(weight, (float, int)): raise ValueError('Invalid weight: Must be float or int') self._weight = weight if not isinstance(noise, float) or noise < 0 or noise > 1: raise ValueError('Invalid noise: Must be float between 0 and 1') self._noise = noise if not isinstance(bottleneck, int) or bottleneck < 1 or bottleneck > 4: raise ValueError( 'Invalid bottleneck: Should be int between 1 and 4') self._bottleneck = bottleneck self._segments = self._segment_space() if not isinstance(exposures, int) or exposures < 1: raise ValueError('Invalid exposures: Must be int greater than 0') self._exposures = exposures if not isinstance(mcmc_iterations, int) or mcmc_iterations < 1000: raise ValueError( 'Invalid mcmc_iterations: Should be int greater than or equal to 1000' ) self._mcmc_iterations = mcmc_iterations self._model_parameters = { 'shape': self._shape, 'mincats': self._mincats, 'maxcats': self._maxcats, 'prior': self._prior, 'weight': self._weight, 'noise': self._noise, 'bottleneck': self._bottleneck, 'exposures': self._exposures, 'mcmc_iterations': self._mcmc_iterations } self.generations = []