"""Metrics to assess performance on sequence labeling task given prediction
Functions named as ``*_score`` return a scalar value to maximize: the higher
the better
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function


def get_entities(seq):
    """Gets entities from sequence.

    Args:
        seq (list): sequence of labels.

    Returns:
        list: list of (chunk_type, chunk_start, chunk_end).

    Example:
        >>> seq = ['B-PER', 'I-PER', 'O', 'B-LOC']
        >>> get_entities(seq)
        [('PER', 0, 2), ('LOC', 3, 4)]
    """
    i = 0
    chunks = []
    seq = seq + ['O']  # add sentinel
    types = [tag.split('-')[-1] for tag in seq]
    while i < len(seq):
        if seq[i].startswith('B'):
            for j in range(i+1, len(seq)):
                if seq[j].startswith('I') and types[j] == types[i]:
                    continue
                break
            chunks.append((types[i], i, j))
            i = j
        else:
            i += 1
    return chunks


def f1_score(y_true, y_pred, average='micro', format='iob'):
    """Compute the F1 score.

    The F1 score can be interpreted as a weighted average of the precision and
    recall, where an F1 score reaches its best value at 1 and worst score at 0.
    The relative contribution of precision and recall to the F1 score are
    equal. The formula for the F1 score is::

        F1 = 2 * (precision * recall) / (precision + recall)

    Args:
        y_true : 1d array. Ground truth (correct) target values.
        y_pred : 1d array. Estimated targets as returned by a tagger.

    Returns:
        score : float.

    Example:
        >>> from seqeval.metrics import f1_score
        >>> y_true = ['O', 'O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'O', 'B-PER', 'I-PER']
        >>> y_pred = ['O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'I-MISC', 'O', 'B-PER', 'I-PER']
        >>> f1_score(y_true, y_pred)
        0.50
    """

    correct_preds, total_correct, total_preds = 0., 0., 0.

    true_entities = set(get_entities(y_true))
    pred_entities = set(get_entities(y_pred))

    correct_preds += len(true_entities & pred_entities)
    total_preds += len(pred_entities)
    total_correct += len(true_entities)

    p = correct_preds / total_preds if correct_preds > 0 else 0
    r = correct_preds / total_correct if correct_preds > 0 else 0
    score = 2 * p * r / (p + r) if correct_preds > 0 else 0

    return score


def accuracy_score(y_true, y_pred, format='iob'):
    """Accuracy classification score.

    In multilabel classification, this function computes subset accuracy:
    the set of labels predicted for a sample must *exactly* match the
    corresponding set of labels in y_true.

    Args:
        y_true : 1d array. Ground truth (correct) target values.
        y_pred : 1d array. Estimated targets as returned by a tagger.

    Returns:
        score : float.

    Example:
        >>> from seqeval.metrics import accuracy_score
        >>> y_true = ['O', 'O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'O', 'B-PER', 'I-PER']
        >>> y_pred = ['O', 'O', 'B-MISC', 'I-MISC', 'I-MISC', 'I-MISC', 'O', 'B-PER', 'I-PER']
        >>> accuracy_score(y_true, y_pred)
        0.50
    """
    true_entities = set(get_entities(y_true))
    pred_entities = set(get_entities(y_pred))

    nb_correct = len(true_entities & pred_entities)
    nb_samples = len(true_entities)

    score = nb_correct / nb_samples

    return score


def classification_report(y_true, y_pred, format='iob'):
    pass

@@ -1971,69 +1971,8 @@
 %22%22%22%0A
-%0A    correct_preds, total_correct, total_preds = 0., 0., 0.%0A%0A
     
@@ -2068,23 +2068,19 @@
     
+nb_
 correct
-_preds +
+ 
 = le
@@ -2120,21 +2120,16 @@
     
-total
+nb
 _pred
-s +
+ 
 = le
@@ -2153,23 +2153,16 @@
     
-total_correct +
+nb_true 
 = le
@@ -2191,52 +2191,39 @@
 p = 
+nb_
 correct
-_preds / total
+ / nb
 _pred
-s
  if 
-correct
+nb
 _pred
-s
  %3E 0
@@ -2242,54 +2242,39 @@
 r = 
+nb_
 correct
-_preds / total_correct if correct_preds
+ / nb_true if nb_true
  %3E 0
@@ -2320,21 +2320,13 @@
  if 
-correct_preds
+p + r
  %3E 0
@@ -3282,23 +3282,20 @@
 %0A    nb_
-samples
+true
  = len(t
@@ -3341,15 +3341,12 @@
  nb_
-samples
+true
 %0A%0A  

Update variable name