def score_documents(user_obs, doc_obs, no_click_mass=1.0, is_mnl=False, min_normalizer=-1.0): """Computes unnormalized scores given both user and document observations. Similar to score_documents_tf but works on NumPy objects. Args: user_obs: An instance of AbstractUserState. doc_obs: A numpy array that represents the observation of all documents in the candidate set. no_click_mass: a float indicating the mass given to a no click option is_mnl: whether to use a multinomial logit model instead of a multinomial proportional model. min_normalizer: A float (<= 0) used to offset the scores to be positive when using multinomial proportional model. Returns: A float array that stores unnormalzied scores of documents and a float number that represents the score for the action of picking no document. """ scores = np.array([]) for doc in doc_obs: scores = np.append(scores, np.dot(user_obs, doc)) all_scores = np.append(scores, no_click_mass) if is_mnl: all_scores = choice_model.softmax(all_scores) else: all_scores = all_scores - min_normalizer assert not all_scores[ all_scores < 0.0], 'Normalized scores have non-positive elements.' return all_scores[:-1], all_scores[-1]
def test_softmax_negative_floats(self): self.assertAllClose( choice_model.softmax(-1.0 * np.log(np.arange(1, 5))), np.array([0.48, 0.24, 0.16, 0.12]))
def test_softmax_equal_ints(self): self.assertAllClose(choice_model.softmax(np.ones(4)), np.array([0.25, 0.25, 0.25, 0.25]))
def test_softmax_positive_floats(self): self.assertAllClose(choice_model.softmax(np.log(np.arange(1, 5))), np.array([0.1, 0.2, 0.3, 0.4]))
def test_softmax_single_int(self): self.assertAllClose(choice_model.softmax([0]), [1.0])