def prior_and_posterior_for_category(self, category_to_primitives):
category_to_prior = {}
category_to_posterior = {}
# We want to take the logs of the lengh prior, but some elements
# will be zero; entries in the result being -inf is okay, but we want
# to avoid a potentially alarming warning message
M = np.zeros(self.length_prior.shape)
M[self.length_prior > 0.] = np.log(self.length_prior[self.length_prior > 0.])
M[self.length_prior <= 0.] = -np.inf
lengths = np.arange(len(M))
for category, primitives in category_to_primitives.iteritems():
base_prior = 0.
for primitive in primitives:
base_prior += self.base_prior_by_primitive[primitive]
# Effectively we calculate the probability of never
# choosing this category in a rule with 0 primitives, 1
# primitive, etc, then add those up, scaling by the
# probability of having 0 primitives, 1 primitive, etc.;
# for speed and numerical behavior we do this in a
# vectorized way on a log scale:
inclusion_prior = -1.0*np.expm1(
logsumexp(M + (np.log1p(-1.0*base_prior) * lengths))
)
category_to_prior[category] = inclusion_prior
states_in_category = 0
for state in self.state_ensemble_primitives:
if state.intersection(primitives):
states_in_category += 1
category_to_posterior[category] = (
states_in_category / float(len(self.state_ensemble))
)
return category_to_prior, category_to_posterior
评论列表
文章目录