def M_step(self):

        """
        generate new parameter estimates given updated type distribution
        """

        for k in range(self.K):
            self.rho[k] = self.type_prob[:, k].sum() / self.N

        for k in range(self.K):
            for m in range(self.M):
                temp_prob = np.dot(self.type_prob[:, k],
                                   self.feature_counts[:, m])
                if temp_prob < 1e-99:
                    temp_prob = 1e-99
                self.mu[k, m] = temp_prob / np.dot(self.type_prob[:, k],
                                                   self.observations)
generate new parameter estimates given updated type distribution