def get_match_result(true_seqs, pred_seqs, do_stem=True, type='exact'): ''' :param true_seqs: :param pred_seqs: :param do_stem: :param topn: :param type: 'exact' or 'partial' :return: ''' micro_metrics = [] micro_matches = [] # do processing to baseline predictions match_score = np.asarray([0.0] * len(pred_seqs), dtype='float32') target_number = len(true_seqs) predicted_number = len(pred_seqs) metric_dict = {'target_number': target_number, 'prediction_number': predicted_number, 'correct_number': match_score} # convert target index into string if do_stem: true_seqs = [stem_word_list(seq) for seq in true_seqs] pred_seqs = [stem_word_list(seq) for seq in pred_seqs] for pred_id, pred_seq in enumerate(pred_seqs): if type == 'exact': match_score[pred_id] = 0 for true_id, true_seq in enumerate(true_seqs): match = True if len(pred_seq) != len(true_seq): continue for pred_w, true_w in zip(pred_seq, true_seq): # if one two words are not same, match fails if pred_w != true_w: match = False break # if every word in pred_seq matches one true_seq exactly, match succeeds if match: match_score[pred_id] = 1 break elif type == 'partial': max_similarity = 0. pred_seq_set = set(pred_seq) # use the jaccard coefficient as the degree of partial match for true_id, true_seq in enumerate(true_seqs): true_seq_set = set(true_seq) jaccard = len(set.intersection(*[set(true_seq_set), set(pred_seq_set)])) / float(len(set.union(*[set(true_seq_set), set(pred_seq_set)]))) if jaccard > max_similarity: max_similarity = jaccard match_score[pred_id] = max_similarity elif type == 'bleu': # account for the match of subsequences, like n-gram-based (BLEU) or LCS-based match_score[pred_id] = bleu(pred_seq, true_seqs, [0.1, 0.3, 0.6]) return match_score