@register_metric('<STR_LIT>')<EOL>def squad_v2_f1(y_true: List[List[str]], y_predicted: List[str]) -> float:
f1_total = <NUM_LIT:0.0><EOL>for ground_truth, prediction in zip(y_true, y_predicted):<EOL><INDENT>prediction_tokens = normalize_answer(prediction).split()<EOL>f1s = []<EOL>for gt in ground_truth:<EOL><INDENT>gt_tokens = normalize_answer(gt).split()<EOL>if len(gt_tokens) == <NUM_LIT:0> or len(prediction_tokens) == <NUM_LIT:0>:<EOL><INDENT>f1s.append(float(gt_tokens == prediction_tokens))<EOL>continue<EOL><DEDENT>common = Counter(prediction_tokens) & Counter(gt_tokens)<EOL>num_same = sum(common.values())<EOL>if num_same == <NUM_LIT:0>:<EOL><INDENT>f1s.append(<NUM_LIT:0.0>)<EOL>continue<EOL><DEDENT>precision = <NUM_LIT:1.0> * num_same / len(prediction_tokens)<EOL>recall = <NUM_LIT:1.0> * num_same / len(gt_tokens)<EOL>f1 = (<NUM_LIT:2> * precision * recall) / (precision + recall)<EOL>f1s.append(f1)<EOL><DEDENT>f1_total += max(f1s)<EOL><DEDENT>return <NUM_LIT:100> * f1_total / len(y_true) if len(y_true) > <NUM_LIT:0> else <NUM_LIT:0><EOL>
Calculates F-1 score between y_true and y_predicted
        F-1 score uses the best matching y_true answer

    The same as in SQuAD-v2.0

    Args:
        y_true: list of correct answers (correct answers are represented by list of strings)
        y_predicted: list of predicted answers

    Returns:
        F-1 score : float