def estimate(self, xs, max_iterations=10000): self.n = len(xs) self.s2 = invgamma.rvs(self.alpha, scale=self.beta) self.means = [] response_sums = [] self.counts = [] assignments = [] assignments.append(0) response_sums.append(xs[0]) self.counts.append(1) self.means.append(self.sample_posterior_mean(response_sums[0], 1, self.s2, self.m0, self.s20)) for i in range(1, len(xs)): weights = self.__create_weight_vector(xs[i], self.means, self.counts, self.s2, self.m0, self.s20, self.m) # Sample an assignment for each item and update statistics assignment = multinomial_sampling.sample(weights) if assignment < len(self.means): response_sums[assignment] += xs[i] self.counts[assignment] += 1 # Create a new component elif assignment == len(self.means): response_sums.append(xs[i]) self.counts.append(1) self.means.append(self.sample_posterior_mean(xs[i], 1, self.s2, self.m0, self.s20)) else: print("WWWWW Should never get here. WWWWWW") assignments.append(assignment) for i in xrange(max_iterations): # First sample an assignment for each data item for j in xrange(len(xs)): old_assignment = assignments[j] response_sums[old_assignment] -= xs[j] self.counts[old_assignment] -= 1 if self.counts[old_assignment] == 0: self.__fix_hole(assignments, response_sums, self.means, self.counts, old_assignment) weights = self.__create_weight_vector(xs[j], self.means, self.counts, self.s2, self.m0, self.s20, self.m) new_assignment = multinomial_sampling.sample(weights) # Create a new component if new_assignment < len(self.means): response_sums[new_assignment] += xs[j] self.counts[new_assignment] += 1 elif new_assignment == len(self.means): response_sums.append(xs[j]) self.counts.append(1) self.means.append(self.sample_posterior_mean(xs[j], 1, self.s2, self.m0, self.s20)) else: print("EEEEEEE This should never happenEEEEEEEEEE") assignments[j] = new_assignment # Sample new values for the means for j in xrange(len(self.means)): self.means[j] = self.sample_posterior_mean(response_sums[j], self.counts[j], self.s2, self.m0, self.s20) # Sample new value for the component variance res_sum_squares = self.calculate_res_sum_squares(xs, assignments, self.means) self.s2 = self.sample_posterior_var(self.n, res_sum_squares, self.alpha, self.beta) return self
def __rv(self, weights): s = multinomial_sampling.sample(weights) if s < len(self.means): # Draw from a component return norm.rvs(self. means[s], scale=sqrt(self.s2)) else: # Draw from the marginal return norm.rvs(self.m0, scale=sqrt(self.s20 + self.s2))