示例#1
0
	def evaluate_combination(self, target, feasible_set, t, r, logging=False):
		"""
			return expected information gain of target combination (target)
			for a specific degree-order pair

		"""
		if logging: print "\n### Evaluating combination: ", target
		collected_responses = []
		if self.codelength == 2: n_responses = self.codelength**2 + 1
		else: n_responses = self.codelength**2
		prob_of_response = np.zeros(n_responses) 
		
		'''
		compute feedback for each combination in the feasible set
		'''
		for combination in feasible_set:
			response = self.response(target, combination)
			probability = self.get_probability(combination)
			if response not in collected_responses: #add to responses
				collected_responses.append(response)
			idx = np.where(np.array(collected_responses)==response)[0]
			prob_of_response[idx] += probability
		prob_of_response = np.array((prob_of_response[:len(collected_responses)] 
			/ np.sum(prob_of_response)))
		collected_responses = np.array(collected_responses)
		
		'''
		compute prior entropy (before guess)
		'''
		self.getCurrentFS()
		fs, fs_prob, _ = self.currentFS
		prior_entropy = sharma_mittal.sm_entropy(fs_prob, t=t, r=r) 
		'''
		compute hypothetical feasible sets for all possible responses
		'''
		entropy_of_sets = []
		for response in collected_responses:
			f_rc = [] #construct hypothetical feasible set
			if logging:  print "\n -> when response is: ", response
			for combination, c_prob in zip(fs, fs_prob):
				if (self.response(combination, target) == response):
					f_rc.append(c_prob)
			f_rc /= np.sum(f_rc)
			if logging: print tmf_rcp 
			entropy_of_sets.append(sharma_mittal.sm_entropy(f_rc, t=t, r=r))
		entropy_of_sets = np.array(entropy_of_sets)
		exp_post_entropy = np.sum(np.multiply(entropy_of_sets, prob_of_response))
		return prior_entropy - exp_post_entropy
示例#2
0
	def evaluate_combination(self, target, feasible_set, t, r, logging=False):
		"""
			return expected information gain of target combination (target)
			for a specific degree-order pair

		"""
		if logging: print "\n### Evaluating combination: ", target
		collected_responses = []
		if self.codelength == 2: n_responses = self.codelength**2 + 1
		else: n_responses = self.codelength**2
		prob_of_response = np.zeros(n_responses) 
		
		'''
		compute feedback for each combination in the feasible set
		'''
		for combination in feasible_set:
			response = self.response(target, combination)
			probability = self.get_probability(combination)
			if response not in collected_responses: #add to responses
				collected_responses.append(response)
			idx = np.where(np.array(collected_responses)==response)[0]
			prob_of_response[idx] += probability
		prob_of_response = np.array((prob_of_response[:len(collected_responses)] 
			/ np.sum(prob_of_response)))
		collected_responses = np.array(collected_responses)
		
		'''
		compute prior entropy (before guess)
		'''
		self.getCurrentFS()
		fs, fs_prob, _ = self.currentFS
		prior_entropy = sharma_mittal.sm_entropy(fs_prob, t=t, r=r) 
		'''
		compute hypothetical feasible sets for all possible responses
		'''
		entropy_of_sets = []
		for response in collected_responses:
			f_rc = [] #construct hypothetical feasible set
			if logging:  print "\n -> when response is: ", response
			for combination, c_prob in zip(fs, fs_prob):
				if (self.response(combination, target) == response):
					f_rc.append(c_prob)
			f_rc /= np.sum(f_rc)
			if logging: print tmf_rcp 
			entropy_of_sets.append(sharma_mittal.sm_entropy(f_rc, t=t, r=r))
		entropy_of_sets = np.array(entropy_of_sets)
		exp_post_entropy = np.sum(np.multiply(entropy_of_sets, prob_of_response))
		return prior_entropy - exp_post_entropy
示例#3
0
 def sm_usefulness(self, d, degree, order, normalize=True):
     prior_entropy = sharma_mittal.sm_entropy(d.prior, degree, order)
     posterior_entropy = [
         np.sum([
             d.marginal[i][j] * sharma_mittal.sm_entropy(dd, degree, order)
             for j, dd in enumerate(posterior)
         ]) for i, posterior in enumerate(d.posterior)
     ]
     sm_relevance = prior_entropy - np.array(posterior_entropy)
     if not normalize: return sm_relevance
     oidx = np.where(self.orderSpace == order)[0][0]
     didx = np.where(self.degreeSpace == degree)[0][0]
     upperBound = self.bounds[0][oidx][didx]
     lowerBound = self.bounds[1][oidx][didx]
     if upperBound == lowerBound: return [0, 0]
     for i, uu in enumerate(
             sm_relevance):  #PREVENT u from being out of bounds!
         sm_relevance[i] = min(upperBound, sm_relevance[i])
         sm_relevance[i] = max(lowerBound, sm_relevance[i])
     return (sm_relevance - lowerBound) / (upperBound - lowerBound)
示例#4
0
    def global_utility(self, d, pure_ig=False):

        likelihood = np.empty((self.N, self.N, self.N_beta, self.n_trials + 1))
        posterior = np.empty((self.n_trials + 1, self.N, self.N, self.N_beta))

        for (t, r, b), p in np.ndenumerate(self.prior):
            likelihood[t][r][b] = self.model_likelihood(
                d, self.degreeSpace[t], self.orderSpace[r], self.betaSpace[b])
            for y in np.arange(self.n_trials + 1):
                posterior[y][t][r][b] = p * likelihood[t][r][b][y]
        unnorm_post = np.copy(posterior)
        for y in np.arange(self.n_trials + 1):  #normalize posteriors
            posterior[y] /= np.sum(posterior[y])

        self.prior_ent = sharma_mittal.sm_entropy(self.prior, r=1.0, t=1.0)

        margpost = [
            np.sum(unnorm_post[y]) for y in np.arange(self.n_trials + 1)
        ]
        post_ent = [
            sharma_mittal.sm_entropy(unnorm_post[y], r=1.0, t=1.0)
            for y in np.arange(self.n_trials + 1)
        ]
        exp_post_ent = np.dot(margpost, post_ent)
        global_utility = self.prior_ent - exp_post_ent

        # global_utility = 0
        # for (t,r,b), p in np.ndenumerate(self.prior):
        # 	for y in np.arange(self.n_trials+1):
        # 		global_utility += p * likelihood[t][r][b][y] * self.local_utility(
        # 			t,r,b,y,posterior[y][t][r][b])
        # print(global_utility)

        if pure_ig: return global_utility

        if self.l_flag: return global_utility * self.learnability(d)
        else: return global_utility
示例#5
0
    def viz_triplet(self, old_prior, d):
        f, axarr = plt.subplots(1, 3, figsize=(16, 5))
        prior_ent = sharma_mittal.sm_entropy(old_prior, r=1.0, t=1.0)
        post_ent = sharma_mittal.sm_entropy(self.prior, r=1.0, t=1.0)

        axarr[0] = self.viz_prior(
            old_prior,
            ax=axarr[0],
            title=r'Prior $\quad P(\Theta) \qquad ent^{SM_{(1,1)}}(P)=%.2f$' %
            prior_ent,
            annotate=self.step)
        axarr[1] = self.viz_prior(
            ax=axarr[1],
            title=
            r'Posterior $\quad P(\Theta|d=d^{*},y=%d) \qquad ent^{SM_{(1,1)}}(P)=%.2f$'
            % (self.results.responses[-1], post_ent),
            annotate=self.step + 1)
        # axarr[2] = ternary_plot.plot(d,
        # 	t=self.degreeSpace[int(self.guess_degree)],
        # 	r=self.orderSpace[int(self.guess_order)],
        # 	ax=axarr[2], title=r'Design $d^{*}$')
        axarr[2] = ternary_plot.plot(d,
                                     t=self.degreeSpace[int(self.true_degree)],
                                     r=self.orderSpace[int(self.true_order)],
                                     ax=axarr[2],
                                     title=r'"Optimal" Design $d^{*}$')
        y1, y2 = axarr[2].get_ylim()
        axarr[2].set_ylim([y1, y2 * 1.1])

        f.subplots_adjust(left=0.05,
                          bottom=0.10,
                          right=0.95,
                          top=0.90,
                          wspace=0.0,
                          hspace=0.0)
        return f
示例#6
0
    def learnability(self, d, split=False, noH=False):
        """
		Function to compute learnability of a given environment d.

		Description:
		------------
		Learnability has two components: the posterior and the joint 
		distribution. The posterior is scored according to how dissimilar 
		its two largest values are. The joint component penalizes joint 
		feature combinations that are very small (and non-zero).

		Arguments:
		----------
		d (design object): the environment to be evaluated

		Returns:
		--------
		learnability: posterior and joint score (between 0 and 1)

		"""
        def transformPosterior(x, c=15, n=2):
            return 1 if x == 0 else (2 / (1 + np.exp(-c * abs(x - n))) - 1)

        def transformJoint(x, e=0.01, c=30):
            if x == 0: return 1
            return 0 if x <= e else (2 / (1 + np.exp(-c * (x - e))) - 1)

        postScore = []
        altProbabilities = np.zeros(self.N_categories)
        for idx, featureComb in enumerate(d.postComb):
            altProbabilities[np.argmax(featureComb)] += d.margComb[idx]
            n = np.max(featureComb)
            postScore.append([
                transformPosterior(f, n=n) for f in np.sort(featureComb)[:-1]
            ])
        postScore = np.prod(postScore)
        jointScore = np.prod([transformJoint(x) for x in d.margComb.flatten()])

        maxEnt = np.log(np.count_nonzero(altProbabilities))
        ent = sharma_mittal.sm_entropy(altProbabilities, 1.0, 1.0)
        hetScore = 0 if maxEnt == 0 else ent / maxEnt

        if noH: return postScore * jointScore
        if split: return [postScore, jointScore, hetScore]
        else: return postScore * jointScore * hetScore
示例#7
0
	def compute_console_statistics(self):
		"""
			Funciton to compute (position/color/feasible set) statistics
			used by the MMind_App. The statistics are displayed in the
			statistics widget
		"""

		self.getCurrentFS()

		#------ compute position statistics
		position_statistics = np.zeros(shape=(self.Ncolors, self.codelength))
		for p in np.arange(self.codelength):
			position_vector = self.currentFS[0][:,p]
			for c in np.arange(self.Ncolors):
				idx = np.where(position_vector==(c+1))
				position_statistics[c][p] += np.sum(self.currentFS[1][idx])
		
		#------ compute color statistics
		color_statistics = np.zeros(shape=(self.Ncolors, self.codelength+1))
		for code, p in zip(self.currentFS[0], self.currentFS[1]):
			count = np.bincount(code)[1:]
			count = np.pad(count, (0, self.Ncolors-len(count)),
				mode='constant', constant_values=0)
			for color, number in np.ndenumerate(count):
				color_statistics[color][number] += p

		#------ compute fs statistics
		fs_size = len(self.currentFS[0])
		fs_entropy = sharma_mittal.sm_entropy(
			self.currentFS[1], t=1.0, r=1.0)
		n = 5
		topIDX = [np.argsort(self.currentFS[1])][0][-n:]
		topC = self.currentFS[0][topIDX][::-1]
		topP = self.currentFS[1][topIDX][::-1]
		fs_stats = [fs_size, fs_entropy, topC, topP]

		return [position_statistics, color_statistics, fs_stats]
示例#8
0
	def compute_console_statistics(self):
		"""
			Funciton to compute (position/color/feasible set) statistics
			used by the MMind_App. The statistics are displayed in the
			statistics widget
		"""

		self.getCurrentFS()

		#------ compute position statistics
		position_statistics = np.zeros(shape=(self.Ncolors, self.codelength))
		for p in np.arange(self.codelength):
			position_vector = self.currentFS[0][:,p]
			for c in np.arange(self.Ncolors):
				idx = np.where(position_vector==(c+1))
				position_statistics[c][p] += np.sum(self.currentFS[1][idx])
		
		#------ compute color statistics
		color_statistics = np.zeros(shape=(self.Ncolors, self.codelength+1))
		for code, p in zip(self.currentFS[0], self.currentFS[1]):
			count = np.bincount(code)[1:]
			count = np.pad(count, (0, self.Ncolors-len(count)),
				mode='constant', constant_values=0)
			for color, number in np.ndenumerate(count):
				color_statistics[color][number] += p

		#------ compute fs statistics
		fs_size = len(self.currentFS[0])
		fs_entropy = sharma_mittal.sm_entropy(
			self.currentFS[1], t=1.0, r=1.0)
		n = 5
		topIDX = [np.argsort(self.currentFS[1])][0][-n:]
		topC = self.currentFS[0][topIDX][::-1]
		topP = self.currentFS[1][topIDX][::-1]
		fs_stats = [fs_size, fs_entropy, topC, topP]

		return [position_statistics, color_statistics, fs_stats]
示例#9
0
	def fs_entropy(self, fs, t, r):
		""" returns Sharma-Mittal entropy of feasible """

		probs = self.fs_probability(fs)
		return sharma_mittal.sm_entropy(probs, t=t, r=r)
示例#10
0
 def entropy(p):
     return sharma_mittal.sm_entropy(p, t, r)
示例#11
0
	def fs_entropy(self, fs, t, r):
		""" returns Sharma-Mittal entropy of feasible """

		probs = self.fs_probability(fs)
		return sharma_mittal.sm_entropy(probs, t=t, r=r)
示例#12
0
    def run(self, func):
        """ 
			Recursive function that is at the heart of ADO.
		"""

        #stopping criterion
        if self.step >= self.max_steps: return True
        else: self.step += 1

        #specify filename for save file
        if self.save_results:
            if not self.filename:
                fileName = 'hado_' + str(datetime.datetime.now().strftime(
                    "%Y-%m-%d_%H-%M-%S")) + '_id_' + str(
                        self.fileID) + '_step_' + str(self.step)
            else:
                fileName = self.filename
            fileName = 'data/' + fileName

        #start iteration
        self.tic()
        self.log("\n### STEP %s ###" % self.step)

        #using pre-specified design
        if self.method == 'pre':
            self.log("\t### using pre-specified design ... ###")
            d, u = self.step_design, self.global_utility(self.step_design)
            self.toc()
        #design optimization step
        else:
            self.log("\t### executing optimization method ... ###")
            d, u = func.optimize(self, **self.m_args)
            self.log("\t### ... done! ###")
            self.toc()
            self.log("\t### time per design eval = %.12f" %
                     (self.trial_time / (self.m_args['n_designs'] * 1.0)))

        #save results
        self.results.lscores.append(self.learnability(d))
        self.results.dobject.append(d)
        self.results.designs.append(d.oneLine())
        self.results.utilities.append(u)
        self.results.pure_utilities.append(self.global_utility(d,
                                                               pure_ig=True))
        self.log("\t### U(d) = %2.4f ###" %
                 self.global_utility(d, pure_ig=True))
        lj, jp, lh = self.learnability(d, split=True)
        self.log("\t### L(d) = %2.8f (post), %2.8f (joint) ###" % (lj, jp))
        self.log("\t### Heterogeneity (0-1) = %1.5f ###" % lh)
        self.log("\t### U(.)*L(.)  = %2.4f ###" % u)

        #factor learnability into beta
        if self.l_flag:
            beta_star = self.betaSpace[self.true_beta] * self.learnability(
                d, noH=True)
        else:
            beta_star = self.betaSpace[self.true_beta]
        self.log("\t### effective beta = %.5f" % beta_star)

        if self.set_response != -1:
            response = self.set_response
            self.log("\t### pre-specified response: %s" % response)
        else:
            #simulate experiment
            response_distribution = self.model_likelihood(
                d, self.degreeSpace[self.true_degree],
                self.orderSpace[self.true_order], beta_star)
            # response = sp.choice(self.n_trials+1, p=response_distribution)[0] #hack for numpy v. < 1.6
            response = np.random.choice(self.n_trials + 1,
                                        p=response_distribution)
            self.log("\t### simulated response: %s" % response)

        self.results.responses.append(response)
        self.marginals = self.marginal_response_probability(
            d)  #probability of response under model(s)

        #update posterior
        old_prior = np.copy(self.prior)
        posterior_response_0 = np.copy(self.prior)
        posterior_response_1 = np.copy(self.prior)

        def update_prior(prior, response):
            for (t, r, b), p in np.ndenumerate(prior):
                prior[t][r][b] = self.model_likelihood(
                    d, self.degreeSpace[t], self.orderSpace[r],
                    self.betaSpace[b])[response] * p
            prior /= np.sum(prior)
            return prior

        posterior_response_0 = update_prior(posterior_response_0, 0)
        posterior_response_1 = update_prior(posterior_response_1, 1)

        #actual experiment:
        self.prior = update_prior(self.prior, response)
        self.prior_ent = sharma_mittal.sm_entropy(self.prior, r=1.0, t=1.0)

        #compute and store results
        self.results.time_array.append(self.trial_time)
        self.compute_results()
        self.log("\t### execution time (s): %s ###" % self.trial_time)

        # def pround(a, decimals=4):
        # 	a = np.round_(a, decimals=decimals)
        # 	midx = np.argmax(a)
        # 	e = 1 - np.sum(a)
        # 	a[midx] += e
        # 	return a

        if self.plotting or self.save_results:
            f = self.viz_full(d, old_prior)
            if self.save_results:
                fileName += '_stage_' + str(self.step).zfill(3)
                f.savefig(fileName + '_figures.pdf',
                          dpi=150,
                          bbox_inches='tight')
                with open(fileName + '_design.txt', 'w') as text_file:
                    strtofile = 'Prior\n' + \
                     np.array_str(self.results.dobject[-1].prior) + \
                     '\n\nLikelihoods\n' + \
                     np.array_str(self.results.dobject[-1].marginal) + \
                     '\n\nFeature marginals\n' + \
                     np.array_str(self.results.dobject[-1].likelihoods) + \
                     '\n\nFeature Posteriors\n' + \
                     np.array_str(self.results.dobject[-1].posterior) + \
                     '\n\nMarginals (combined)\n' + \
                     np.array_str(self.results.dobject[-1].margComb) + \
                     '\n\nPosteriors (combined)\n' + \
                     np.array_str(self.results.dobject[-1].postComb) + \
                     '\n\nJoint probabilities\n' + \
                     np.array_str(self.results.dobject[-1].joint) + \
                     '\n\n!!! Use flattened joint probabilities array (from top left to bottom right) for experience-based learning experiment !!!'
                    self.log("\n\nResults successfully SAVED as %s!!" %
                             fileName)
                    strtofile = strtofile + '\n\n' + self.log_string
                    text_file.write("Environment:\n%s" % strtofile)

                # save design
                np.save(fileName + '_design.npy',
                        d.asNumpy(),
                        allow_pickle=False)
                # save prior
                np.save(fileName + '_prior.npy', old_prior, allow_pickle=False)
                # save posterior(s)
                np.save(fileName + '_posterior_0.npy',
                        posterior_response_1,
                        allow_pickle=False)
                np.save(fileName + '_posterior_1.npy',
                        posterior_response_0,
                        allow_pickle=False)
        '''	
		if self.plotting or self.save_results:
			f = self.viz_triplet(old_prior, d)
			self.viz_like(d, annotate=True, ax=None)
			# if self.plotting: plt.show()
			if self.save_results: f.savefig(
				'plots/'+datetime.datetime.now().strftime("%Y-%m-%d_%H-%M-%S")+'.pdf', 
				dpi=150, bbox_inches='tight')
		'''
        return self.run(func)
示例#13
0
    def compute_results(self):
        """ 
		USE THIS FUNCTION TO SAVE RESULTS TO ADO.results AFTER EACH ITERATION

		"""
        #Mean Squared Error
        dist_prior = np.add.reduce(self.prior, axis=2)
        dist_prior /= np.sum(dist_prior)  #normalized prior

        #VARIANCE
        order_variance = 0
        degree_variance = 0
        beta_variance = 0
        for (t, r, b), p in np.ndenumerate(self.prior):
            degree_distance = abs(self.true_degree - t)**2
            degree_variance += degree_distance * p
            order_distance = abs(self.true_order - r)**2
            order_variance += order_distance * p
            beta_distance = abs(self.true_beta - b)**2
            beta_variance += beta_distance * p
            # all_distance = degree_distance + order_distance + beta_distance
            # all_variance += all_distance * p
        self.results.order_variance_array.append(np.sqrt(order_variance))
        self.results.degree_variance_array.append(np.sqrt(degree_variance))
        self.results.beta_variance_array.append(np.sqrt(beta_variance))
        self.results.total_variance_array.append(
            np.sqrt(order_variance) + np.sqrt(degree_variance) +
            np.sqrt(beta_variance))

        self.guess_order = np.sum([
            p * r
            for p, r in zip((np.sum(dist_prior, axis=0) /
                             np.sum(dist_prior)).flatten(), np.arange(self.N))
        ])
        self.results.order_guesses.append(self.guess_order)
        self.results.ent_order_array.append(
            sharma_mittal.sm_entropy(
                (np.sum(dist_prior, axis=0) / np.sum(dist_prior)).flatten(),
                r=1.0,
                t=1.0))

        self.guess_degree = np.sum([
            p * t
            for p, t in zip((np.sum(dist_prior, axis=1) /
                             np.sum(dist_prior)).flatten(), np.arange(self.N))
        ])
        self.results.degree_guesses.append(self.guess_degree)
        self.results.ent_degree_array.append(
            sharma_mittal.sm_entropy(
                (np.sum(dist_prior, axis=1) / np.sum(dist_prior)).flatten(),
                r=1.0,
                t=1.0))

        dist_beta = [
            np.sum(self.prior[:, :, i]) for i in np.arange(self.N_beta)
        ]
        dist_beta /= np.sum(dist_beta)
        self.guess_beta = np.sum(
            [p * b for p, b in zip(dist_beta, np.arange(self.N_beta))])
        self.results.beta_guesses.append(self.guess_beta)
        self.results.ent_beta_array.append(
            sharma_mittal.sm_entropy(dist_beta, r=1.0, t=1.0))

        self.mse_order = np.sqrt((self.true_order - self.guess_order)**2)
        self.mse_degree = np.sqrt((self.true_degree - self.guess_degree)**2)
        self.mse_beta = np.sqrt((self.true_beta - self.guess_beta)**2)

        #Shannon Entropy
        self.results.post_entropy_array.append(
            sharma_mittal.sm_entropy(self.prior, r=1.0, t=1.0))
        self.results.mse_order_array.append(self.mse_order)
        self.results.mse_degree_array.append(self.mse_degree)
        self.results.mse_beta_array.append(self.mse_beta)
示例#14
0
    def viz_full(self, d, old_prior):
        f, axarr = plt.subplots(2, 4, figsize=(13, 7))
        prior_ent = sharma_mittal.sm_entropy(old_prior, r=1.0, t=1.0)

        cmap = sns.cubehelix_palette(12,
                                     start=0,
                                     rot=0.5,
                                     light=1,
                                     as_cmap=True,
                                     reverse=True,
                                     hue=0.0,
                                     dark=0.05)

        axarr[0,
              0] = self.viz_prior(old_prior,
                                  ax=axarr[0, 0],
                                  title=r'P(model), ent(P)=%.2f' % prior_ent,
                                  annotate=self.step)

        axarr[1, 0] = ternary_plot.plot_small(
            d,
            t=self.degreeSpace[int(self.true_degree)],
            r=self.orderSpace[int(self.true_order)],
            ax=axarr[1, 0],
            title=r'"Optimal" Design $d^{*}$')
        y1, y2 = axarr[1, 0].get_ylim()
        axarr[1, 0].set_ylim([y1, y2 * 1.1])

        #labeling
        vspac = 0.05
        ypos = 0.95
        xpos = -0.1
        fsize = 9
        axarr[1,
              0].text(xpos,
                      ypos,
                      r'info gain (d)=%.2f' % self.results.pure_utilities[-1],
                      fontsize=fsize,
                      ha='left',
                      va='center',
                      color='k',
                      transform=axarr[1, 0].transAxes)
        axarr[1, 0].text(xpos,
                         ypos - vspac,
                         r'learnability=%.2f' % self.results.lscores[-1],
                         fontsize=fsize,
                         ha='left',
                         va='center',
                         color='k',
                         transform=axarr[1, 0].transAxes)
        axarr[1, 0].text(xpos,
                         ypos - 2 * vspac,
                         r'goodness=%.2f' % self.results.utilities[-1],
                         fontsize=fsize,
                         ha='left',
                         va='center',
                         color='k',
                         transform=axarr[1, 0].transAxes)
        axarr[1, 0].text(xpos,
                         ypos - 3 * vspac,
                         r'choice=$Q_%d$' % (2 - self.results.responses[-1]),
                         fontsize=fsize,
                         ha='left',
                         va='center',
                         color='k',
                         transform=axarr[1, 0].transAxes)

        axarr[0, 1] = self.viz_relevance(
            d,
            q=0,
            annotate=False,
            ax=axarr[0, 1],
            title=r'info gain of $Q_1$ | model (norm.)',
            cmap=cmap)
        axarr[1, 1] = self.viz_relevance(
            d,
            q=1,
            annotate=False,
            ax=axarr[1, 1],
            title=r'info gain of $Q_2$ | model (norm.)',
            cmap=cmap)
        axarr[0, 2] = self.viz_choice_prob(
            d,
            ax=axarr[0, 2],
            title=r'P(choice = $Q_1$ | model), P($Q_1$)=%.2f' %
            self.marginals[1],
            annotate=self.step)
        axarr[1, 2] = self.viz_choice_prob(
            d,
            inv=True,
            ax=axarr[1, 2],
            title=r'P(choice = $Q_2$ | model), P($Q_2$)=%.2f' %
            self.marginals[0],
            annotate=self.step)

        #update posterior
        post_q1 = np.copy(old_prior)
        post_q2 = np.copy(old_prior)
        for (t, r, b), p in np.ndenumerate(old_prior):
            post_q1[t][r][b] = self.model_likelihood(d, self.degreeSpace[t],
                                                     self.orderSpace[r],
                                                     self.betaSpace[b])[1] * p
            post_q2[t][r][b] = self.model_likelihood(d, self.degreeSpace[t],
                                                     self.orderSpace[r],
                                                     self.betaSpace[b])[0] * p
        post_q1 /= np.sum(post_q1)
        post_q2 /= np.sum(post_q2)
        post_ent_q1 = sharma_mittal.sm_entropy(post_q1, r=1.0, t=1.0)
        post_ent_q2 = sharma_mittal.sm_entropy(post_q2, r=1.0, t=1.0)

        axarr[0, 3] = self.viz_prior(
            post_q1,
            ax=axarr[0, 3],
            title=r'P(model | choice=$Q_1$), ent(P)=%.2f' % post_ent_q1,
            annotate=self.step)
        axarr[1, 3] = self.viz_prior(
            post_q2,
            ax=axarr[1, 3],
            title=r'P(model | choice=$Q_2$), ent(P)=%.2f' % post_ent_q2,
            annotate=self.step)

        # TODO: rotate tick labels !!!
        for ax in axarr.flatten():
            _ = [
                tick.label.set_fontsize(7)
                for tick in ax.xaxis.get_major_ticks()
            ]
            _ = [
                tick.label.set_fontsize(7)
                for tick in ax.yaxis.get_major_ticks()
            ]

        f.suptitle('Results after ADO step %d' % self.step,
                   x=0.5,
                   y=0.95,
                   fontsize=14,
                   ha='center',
                   va='center')
        f.subplots_adjust(left=0.05,
                          bottom=0.10,
                          right=0.98,
                          top=0.90,
                          wspace=0.1,
                          hspace=0.3)
        return f
示例#15
0
    def __init__(self, max_steps, n_trials, orderSpace, degreeSpace, betaSpace,
                 true_order, true_degree, true_beta, N_categories, N_features,
                 prior, g, method, m_args, logging, plotting, save_results,
                 l_flag, filename):
        self.logging = logging
        self.plotting = plotting
        self.save_results = save_results

        self.method = method
        self.m_args = m_args
        self.priorName = prior
        self.l_flag = l_flag
        self.log_string = ''
        self.fileID = np.random.randint(100000, 999999)

        self.max_steps = max_steps
        self.orderSpace = orderSpace
        self.degreeSpace = degreeSpace
        self.betaSpace = betaSpace
        # self.labels = [('%s' % Fraction(f)) for f in degreeSpace] #as fractions
        self.labels = ['%.1f' % f for f in degreeSpace]
        self.step = 0
        self.stepwise = False
        self.set_response = -1
        self.simulation = True
        self.filename = filename

        self.N = len(orderSpace)
        self.N_beta = len(betaSpace)
        self.N_categories = N_categories
        self.N_features = N_features
        self.n_trials = n_trials
        self.g = g

        self.bounds = np.array([
            np.fliplr(
                np.rot90(
                    np.loadtxt("hado/extrema/katVals%s_%s_numOpt_1e4-%s.csv" %
                               (N_categories, i, str(self.g)),
                               delimiter=',',
                               dtype=float),
                    k=3)) for i in ['best', 'worst']
        ])

        if prior == 'exp':
            self.prior = np.ones((self.N, self.N, self.N_beta))
            p_tmp = np.flipud(
                np.array(
                    np.loadtxt("hado/priors/hadoPriorsExperienceData-%s.csv" %
                               str(self.g),
                               delimiter=',',
                               dtype=float)))
            for i in np.arange(self.N_beta):
                self.prior[:, :, i] = p_tmp
        elif prior == 'rand':
            self.prior = np.random.rand(self.N, self.N, self.N_beta)
        else:
            self.prior = np.ones((self.N, self.N, self.N_beta))  #uniform
        self.prior = self.prior / self.prior.sum()

        prior_margin = np.add.reduce(
            self.prior, axis=2)  #marginal prior (sum across betas)
        prior_margin /= np.sum(prior_margin)
        if true_order == None:  #sample from prior if not defined
            order_sample = np.sum(prior_margin, axis=0) / np.sum(
                np.sum(prior_margin, axis=0))
            self.true_order = np.random.choice(self.N,
                                               1,
                                               replace=True,
                                               p=order_sample)[0]
        else:
            self.true_order = true_order
        if true_degree == None:  #sample from prior if not defined
            degree_sample = np.sum(prior_margin, axis=1) / np.sum(
                np.sum(prior_margin, axis=1))
            self.true_degree = np.random.choice(self.N,
                                                1,
                                                replace=True,
                                                p=degree_sample)[0]
        else:
            self.true_degree = true_degree
        if true_beta == None:  #sample from prior if not defined
            beta_sample = [
                np.sum(self.prior[:, :, i]) for i in np.arange(self.N_beta)
            ]
            self.true_beta = np.random.choice(self.N_beta,
                                              1,
                                              replace=True,
                                              p=beta_sample)[0]
        else:
            self.true_beta = true_beta

        self.marginals = np.zeros(self.n_trials + 1)
        self.expinfogain = 0
        self.prior_ent = sharma_mittal.sm_entropy(self.prior, r=1.0, t=1.0)

        #create separate 'results' object
        self.results = self.Results(self)
        self.results.post_entropy_array.append(  #initial entropy of prior beliefs
            sharma_mittal.sm_entropy(self.prior, r=1.0, t=1.0))