web-dev-qa-db-fra.com

NLTK: score bleu au niveau du corpus vs score BLEU au niveau de la phrase

J'ai importé nltk dans python pour calculer le score BLEU sur Ubuntu. Je comprends comment fonctionne le score BLEU au niveau de la phrase, mais je ne comprends pas comment fonctionne le score BLEU au niveau du corpus.

Voici mon code pour le score BLEU au niveau du corpus:

import nltk

hypothesis = ['This', 'is', 'cat'] 
reference = ['This', 'is', 'a', 'cat']
BLEUscore = nltk.translate.bleu_score.corpus_bleu([reference], [hypothesis], weights = [1])
print(BLEUscore)

Pour une raison quelconque, le score bleu est 0 pour le code ci-dessus. Je m'attendais à un score BLEU au niveau du corpus d'au moins 0,5.

Voici mon code pour le score BLEU au niveau de la phrase

import nltk

hypothesis = ['This', 'is', 'cat'] 
reference = ['This', 'is', 'a', 'cat']
BLEUscore = nltk.translate.bleu_score.sentence_bleu([reference], hypothesis, weights = [1])
print(BLEUscore)

Ici, le score BLEU au niveau de la phrase est de 0,71, ce à quoi je m'attends, compte tenu de la brièveté et du mot "a" manquant. Cependant, je ne comprends pas comment fonctionne le score BLEU au niveau du corpus.

Toute aide serait appréciée.

12
Long Le Minh

TL; DR :

>>> import nltk
>>> hypothesis = ['This', 'is', 'cat'] 
>>> reference = ['This', 'is', 'a', 'cat']
>>> references = [reference] # list of references for 1 sentence.
>>> list_of_references = [references] # list of references for all sentences in corpus.
>>> list_of_hypotheses = [hypothesis] # list of hypotheses that corresponds to list of references.
>>> nltk.translate.bleu_score.corpus_bleu(list_of_references, list_of_hypotheses)
0.6025286104785453
>>> nltk.translate.bleu_score.sentence_bleu(references, hypothesis)
0.6025286104785453

(Remarque: vous devez extraire la dernière version de NLTK sur la branche develop afin d'obtenir une version stable de l'implémentation du score BLEU)


En long :

En fait, s'il n'y a qu'une seule référence et une seule hypothèse dans tout votre corpus, corpus_bleu() et sentence_bleu() doivent renvoyer la même valeur que celle illustrée dans l'exemple ci-dessus.

Dans le code, nous voyons que sentence_bleu Est en fait un type de canard de corpus_bleu :

def sentence_bleu(references, hypothesis, weights=(0.25, 0.25, 0.25, 0.25),
                  smoothing_function=None):
    return corpus_bleu([references], [hypothesis], weights, smoothing_function)

Et si nous regardons les paramètres de sentence_bleu:

 def sentence_bleu(references, hypothesis, weights=(0.25, 0.25, 0.25, 0.25),
                      smoothing_function=None):
    """"
    :param references: reference sentences
    :type references: list(list(str))
    :param hypothesis: a hypothesis sentence
    :type hypothesis: list(str)
    :param weights: weights for unigrams, bigrams, trigrams and so on
    :type weights: list(float)
    :return: The sentence-level BLEU score.
    :rtype: float
    """

L'entrée pour les références de sentence_bleu Est une list(list(str)).

Donc, si vous avez une chaîne de phrases, par exemple "This is a cat", Vous devez le symboliser pour obtenir une liste de chaînes, ["This", "is", "a", "cat"] Et comme il autorise plusieurs références, il doit s'agir d'une liste de liste de chaînes, par ex. si vous avez une deuxième référence, "Ceci est un félin", votre entrée dans sentence_bleu() serait:

references = [ ["This", "is", "a", "cat"], ["This", "is", "a", "feline"] ]
hypothesis = ["This", "is", "cat"]
sentence_bleu(references, hypothesis)

En ce qui concerne le paramètre corpus_bleu() list_of_references, c'est essentiellement ne liste de tout ce que sentence_bleu() prend comme référence :

def corpus_bleu(list_of_references, hypotheses, weights=(0.25, 0.25, 0.25, 0.25),
                smoothing_function=None):
    """
    :param references: a corpus of lists of reference sentences, w.r.t. hypotheses
    :type references: list(list(list(str)))
    :param hypotheses: a list of hypothesis sentences
    :type hypotheses: list(list(str))
    :param weights: weights for unigrams, bigrams, trigrams and so on
    :type weights: list(float)
    :return: The corpus-level BLEU score.
    :rtype: float
    """

Autre que de regarder le doctorat dans le nltk/translate/bleu_score.py , vous pouvez également jeter un coup d'œil à l'unestest à nltk/test/unit/translate/test_bleu_score.py pour voir comment utiliser chacun des composants dans le bleu_score.py.

Soit dit en passant, puisque le sentence_bleu Est importé en tant que bleu dans le (nltk.translate.__init__.py] ( https://github.com/nltk/nltk/blob/ develop/nltk/translate/ init . py # L21 ), en utilisant

from nltk.translate import bleu 

serait le même que:

from nltk.translate.bleu_score import sentence_bleu

et en code:

>>> from nltk.translate import bleu
>>> from nltk.translate.bleu_score import sentence_bleu
>>> from nltk.translate.bleu_score import corpus_bleu
>>> bleu == sentence_bleu
True
>>> bleu == corpus_bleu
False
18
alvas

Nous allons jeter un coup d'oeil:

>>> help(nltk.translate.bleu_score.corpus_bleu)
Help on function corpus_bleu in module nltk.translate.bleu_score:

corpus_bleu(list_of_references, hypotheses, weights=(0.25, 0.25, 0.25, 0.25), smoothing_function=None)
    Calculate a single corpus-level BLEU score (aka. system-level BLEU) for all 
    the hypotheses and their respective references.  

    Instead of averaging the sentence level BLEU scores (i.e. marco-average 
    precision), the original BLEU metric (Papineni et al. 2002) accounts for 
    the micro-average precision (i.e. summing the numerators and denominators
    for each hypothesis-reference(s) pairs before the division).
    ...

Vous êtes mieux placé que moi pour comprendre la description de l'algorithme, je n'essaierai donc pas de "vous l'expliquer". Si la docstring n'éclaircit pas suffisamment les choses, jetez un œil à la source lui-même. Ou trouvez-le localement:

>>> nltk.translate.bleu_score.__file__
'.../lib/python3.4/site-packages/nltk/translate/bleu_score.py'
5
alexis