def predict(
      self,
      claim, candidates,
      text_key = 'text'):
    """Scores claim against candidates and returns ordered candidates.

    Args:
      claim: The claim to match
      candidates: The candidates to rank
      text_key: Key in the candidate json that contains the text to score

    Returns:
      sorted candidates and a score for each.
    """
    if self._tfidf is None:
      raise ValueError('You must train or load a model before predicting')
    if not candidates:
      return []
    # make candidates indexable via numpy style indices
    candidates = np.array(candidates, dtype=object)
    # (1, vocab_size)
    claim_repr = self._tfidf.transform([claim])
    # (n_candidates, vocab_size)
    candidates_repr = self._tfidf.transform([c[text_key] for c in candidates])
    # (1, n_candidates)
    product = candidates_repr.dot(claim_repr.T).T.toarray()
    # Take the first row, since that is the only row and the one that
    # contains the scores against the claim
    preds = (-product).argsort(axis=1)[0]
    scores = -np.sort(-product, axis=1)[0]
    scores_and_candidates = []
    for match_score, candidate in zip(scores, candidates[preds]):
      scores_and_candidates.append((match_score, candidate))
    return scores_and_candidates
Scores claim against candidates and returns ordered candidates.

    Args:
      claim: The claim to match
      candidates: The candidates to rank
      text_key: Key in the candidate json that contains the text to score

    Returns:
      sorted candidates and a score for each.
    
language/serene/text_matcher.py