def m_step(self):
        '''Perform the M-step. This step updates
        self.mixture_weights
        self.component_distributions
        '''

        # test if the sum of the summed expected_component_counts is roughly equal to the total amount of observations
        sum_obs_counts = log_add_list(self.expected_component_counts.values())
        print("Sum of expected component counts: {}".format(exp(sum_obs_counts)))
    def m_step(self):
        '''Perform the M-step. This step updates
        self.mixture_weights
        self.component_distributions
        '''

        # test if the sum of the summed expected_component_counts is roughly equal to the total amount of observations
        sum_obs_counts = log_add_list(self.expected_component_counts.values())
        print("Sum of expected component counts: {}".format(exp(sum_obs_counts)))
    def m_step(self):
        '''Perform the M-step. This step updates
        self.mixture_weights
        self.component_distributions
        '''

        sum_obs_counts = log_add_list(self.expected_component_counts.values())

        for i in range(self.num_components):
            self.mixture_weights[i] = self.expected_component_counts[i] - sum_obs_counts
            self.component_distributions[i] = GeometricDistribution(exp(self.expected_component_counts[i] - (log_add(self.expected_component_counts[i], self.expected_observation_counts[i]))))

            self.expected_component_counts[i] = -float("inf")
            self.expected_observation_counts[i] = -float("inf")
예제 #4
0
    def m_step(self):
        '''Perform the M-step. This step updates
        self.mixture_weights
        self.component_distributions
        '''

        # test if the sum of the summed expected_component_counts is roughly equal to the total amount of observations
        sum_obs_counts = log_add_list(self.expected_component_counts.values())
        print("Sum of expected component counts: {}".format(exp(sum_obs_counts)))

        for i in range(self.num_components):
            self.mixture_weights[i] = self.expected_component_counts[i] - sum_obs_counts
            self.component_distributions[i] = GeometricDistribution(exp(self.expected_component_counts[i] - (log_add(self.expected_component_counts[i], self.expected_observation_counts[i]))))

            self.expected_component_counts[i] = -float("inf")
            self.expected_observation_counts[i] = -float("inf")
예제 #5
0
    def e_step(self, observation):
        '''Perform the E-step on a single obervation. That is, compute the posterior of mixture components
        and add the expected occurrence of each component to the running totals
        self.log_likelihood ,
        self.expected_component_counts , and
        self.expected_observation_counts

        :param observation: The observation
        '''
        
        # Compute the joint probabilities p(x, c)
        joint_logprobs = list()
        for component in range(self.num_components):
            comp_dist = self.component_distributions[component]
            logprob = self.mixture_weights[component] + comp_dist.log_prob(observation)
            joint_logprobs.append(logprob)

        # Marginal probability p(x) = p(x, c_1) + ... + p(x, c_n)
        marginal_logprob = log_add_list(joint_logprobs)

        # Update log likelihood: log p(x_1, x_2, ...) = log p(x_1) + log p(x_2) + ...
        self.log_likelihood += marginal_logprob

        # Responsibilities are the posteriors p(c | x) = p(x, c) / p(x)
        # So log p(c | x) = log p(x, c) - log p(x)
        logresponsibilities = list()
        for component in range(self.num_components):
            dist = self.component_distributions[component]
            logresp = joint_logprobs[component] - marginal_logprob
            logresponsibilities.append(logresp)

        # Update the expected component count and expected observation counts
        for component in range(self.num_components):

            # log( expected observation counts )
            logresp = logresponsibilities[component]
            self.expected_component_counts[component] = log_add(self.expected_component_counts[component], logresp)

            # Compute the log( expected observation counts)
            # log (exp obs count) 
            #   = log( exp_obs_count + val * exp(logresp))
            #   = log( exp_obs_count + exp( log(val) + logresp ) )
            #   = log_add( log(exp_obs_count),  log(val) + logresp )
            if observation > 0:
                exp_obs = self.expected_observation_counts[component]
                self.expected_observation_counts[component] = log_add(exp_obs, log(observation) + logresp)
예제 #6
0
    def m_step(self):
        '''Perform the M-step. This step updates
        self.mixture_weights
        self.component_distributions
        '''

        # test if the sum of the summed expected_component_counts is roughly equal to the total amount of observations
        sum_obs_counts = log_add_list(self.expected_component_counts.values())
        print("Sum of expected component counts: {}".format(exp(sum_obs_counts)))


        # TODO: Implement this.
        # TODO: Make sure to reset the data structures you use for counting after you have
        # TODO: updated all parameters, namely self.expected_component_counts and self.expected_observation_counts

        for component in range(self.num_components):

            # log_new_weight 
            #    = log( exp( log_exp_count ) / exp( sum_obs_counts ) ) )
            #    = log( exp( log_exp_count )) - log( exp(sum_obs_counts) )
            #    = log_exp_count - sum_obs_counts
            log_exp_count = self.expected_component_counts[component]
            self.mixture_weights[component] = log_exp_count - sum_obs_counts
            
            # log_new_param
            #    = log( exp( log_exp_count) / (exp(log_exp_count) + exp(log_exp_sum)))
            #    = log_exp_count - (log( exp(log_exp_count) + exp(log_exp_sum) )
            #    = log_exp_count - log_add( log_exp_count + log_exp_sum )
            log_exp_sum = self.expected_observation_counts[component]
            logparam = log_exp_count - log_add(log_exp_count, log_exp_sum)
            self.component_distributions[component] = GeometricDistribution(exp(logparam))

        # Reset
        for component in range(self.num_components):
            self.expected_component_counts[component] = -float("inf")
            self.expected_observation_counts[component] = -float("inf")