code: def exp4p(self):
          
          while True:
              # TODO probabilistic active learning algorithm
              # len(self.unlabeled_invert_id_idx) is the number of unlabeled data
              query = np.zeros((self.N, len(self.unlabeled_invert_id_idx)))
              if self.uniform_sampler:
                  query[-1, :] = 1. / len(self.unlabeled_invert_id_idx)
              for i, model in enumerate(self.query_strategies_):
                  query[i][self.unlabeled_invert_id_idx[model.make_query()]] = 1
  
              # choice vector, shape = (self.K, )
              W = np.sum(self.w)
              p = (1 - self.K * self.pmin) * self.w / W + self.pmin
  
              # query vector, shape= = (self.n_unlabeled, )
              query_vector = np.dot(p, query)
  
              reward, ask_id, _ = yield query_vector
              ask_idx = self.unlabeled_invert_id_idx[ask_id]
  
              rhat = reward * query[:, ask_idx] / query_vector[ask_idx]
  
              # The original advice vector in Exp4.P in ALBL is a identity matrix
              yhat = rhat
              vhat = 1 / p
              self.w = self.w * np.exp(
                  self.pmin / 2 * (
                      yhat + vhat * np.sqrt(
                          np.log(self.N / self.delta) / self.K / self.T
                      )
                  )
              )
  
          raise StopIteration
docs: The generator which implements the main part of Exp4.P.
  
          Parameters
          ----------
          reward: float
              The reward value calculated from ALBL.
  
          ask_id: integer
              The entry_id of the sample point ALBL asked.
  
          lbl: integer
              The answer received from asking the entry_id ask_id.
  
          Yields
          ------
          q: array-like, shape = [K]
              The query vector which tells ALBL what kind of distribution if
              should sample from the unlabeled pool.