code: def E_step(self):
  
          
  
          # on the first iteration of estimation, this will be called
          if not hasattr(self, 'type_prob'):
                  self.type_prob = np.empty((self.N, self.K))
  
          temp_probs = np.zeros((self.N, self.K))
  
          for i in range(self.N):
              for k in range(self.K):
                  temp_probs[i, k] = \
                      np.log(self.rho[k]) + np.dot(self.feature_counts[i, :],
                                                   np.log(self.mu[k, :]))
  
          temp_probsZ = temp_probs - np.max(temp_probs, axis=1)[:, np.newaxis]
          self.type_prob = np.exp(temp_probsZ) / \
              np.exp(temp_probsZ).sum(axis=1)[:, np.newaxis]
  
          return np.log(np.exp(temp_probsZ).sum(axis=1)).sum() + \
              np.max(temp_probs, axis=1).sum()
docs: compute type probabilities given current parameter estimates.