


import numpy as np
from nltk.translate import meteor_score

import datasets
from datasets.config import importlib_metadata, version


__lowerCAmelCase		       =							version.parse(importlib_metadata.version('''nltk'''))
if NLTK_VERSION >= version.Version('''3.6.4'''):
 from nltk import word_tokenize


__lowerCAmelCase		       =							'''\
@inproceedings{banarjee2005,
  title     = {{METEOR}: An Automatic Metric for {MT} Evaluation with Improved Correlation with Human Judgments},
  author    = {Banerjee, Satanjeev  and Lavie, Alon},
  booktitle = {Proceedings of the {ACL} Workshop on Intrinsic and Extrinsic Evaluation Measures for Machine Translation and/or Summarization},
  month     = jun,
  year      = {2005},
  address   = {Ann Arbor, Michigan},
  publisher = {Association for Computational Linguistics},
  url       = {https://www.aclweb.org/anthology/W05-0909},
  pages     = {65--72},
}
'''

__lowerCAmelCase		       =							'''\
METEOR, an automatic metric for machine translation evaluation
that is based on a generalized concept of unigram matching between the
machine-produced translation and human-produced reference translations.
Unigrams can be matched based on their surface forms, stemmed forms,
and meanings; furthermore, METEOR can be easily extended to include more
advanced matching strategies. Once all generalized unigram matches
between the two strings have been found, METEOR computes a score for
this matching using a combination of unigram-precision, unigram-recall, and
a measure of fragmentation that is designed to directly capture how
well-ordered the matched words in the machine translation are in relation
to the reference.

METEOR gets an R correlation value of 0.347 with human evaluation on the Arabic
data and 0.331 on the Chinese data. This is shown to be an improvement on
using simply unigram-precision, unigram-recall and their harmonic F1
combination.
'''

__lowerCAmelCase		       =							'''
Computes METEOR score of translated segments against one or more references.
Args:
    predictions: list of predictions to score. Each prediction
        should be a string with tokens separated by spaces.
    references: list of reference for each prediction. Each
        reference should be a string with tokens separated by spaces.
    alpha: Parameter for controlling relative weights of precision and recall. default: 0.9
    beta: Parameter for controlling shape of penalty as a function of fragmentation. default: 3
    gamma: Relative weight assigned to fragmentation penalty. default: 0.5
Returns:
    \'meteor\': meteor score.
Examples:

    >>> meteor = datasets.load_metric(\'meteor\')
    >>> predictions = ["It is a guide to action which ensures that the military always obeys the commands of the party"]
    >>> references = ["It is a guide to action that ensures that the military will forever heed Party commands"]
    >>> results = meteor.compute(predictions=predictions, references=references)
    >>> print(round(results["meteor"], 4))
    0.6944
'''





@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION       ,       _KWARGS_DESCRIPTION      )
class   __a			(    datasets.Metric      ):
 def 		SCREAMING_SNAKE_CASE__   (   self )					->				List[Any]:




        '''simple docstring'''
        return datasets.MetricInfo(
            description=_DESCRIPTION				, citation=_CITATION				, inputs_description=_KWARGS_DESCRIPTION				, features=datasets.Features(
                {
                    'predictions': datasets.Value('string'				, id='sequence' ),
                    'references': datasets.Value('string'				, id='sequence' ),
                } )				, codebase_urls=['https://github.com/nltk/nltk/blob/develop/nltk/translate/meteor_score.py']				, reference_urls=[
                'https://www.nltk.org/api/nltk.translate.html#module-nltk.translate.meteor_score',
                'https://en.wikipedia.org/wiki/METEOR',
            ]				, )
 def 		SCREAMING_SNAKE_CASE__   (   self				, lowerCAmelCase__ )					->				Tuple:




        '''simple docstring'''
        import nltk

        nltk.download('wordnet' )
        if NLTK_VERSION >= version.Version('3.6.5' ):
               nltk.download('punkt' )
        if NLTK_VERSION >= version.Version('3.6.6' ):
               nltk.download('omw-1.4' )
 def 		SCREAMING_SNAKE_CASE__   (   self				, lowerCAmelCase__				, lowerCAmelCase__				, lowerCAmelCase__=0.9				, lowerCAmelCase__=3				, lowerCAmelCase__=0.5 )					->				Optional[Any]:




        '''simple docstring'''
        if NLTK_VERSION >= version.Version('3.6.5' ):
               lowercase__:   Optional[Any]  			=   [
                   meteor_score.single_meteor_score(
                       word_tokenize(lowerCAmelCase__ )				, word_tokenize(lowerCAmelCase__ )				, alpha=lowerCAmelCase__				, beta=lowerCAmelCase__				, gamma=lowerCAmelCase__ )
                   for ref, pred in zip(lowerCAmelCase__				, lowerCAmelCase__ )
               ]
        else:
               lowercase__:   str  			=   [
                   meteor_score.single_meteor_score(lowerCAmelCase__				, lowerCAmelCase__				, alpha=lowerCAmelCase__				, beta=lowerCAmelCase__				, gamma=lowerCAmelCase__ )
                   for ref, pred in zip(lowerCAmelCase__				, lowerCAmelCase__ )
               ]

        return {"meteor": np.mean(lowerCAmelCase__ )}






import numpy as np
import torch
from torch.utils.data import Dataset

from utils import logger





class   __a			(    __UpperCamelCase      ):
 def __init__(   self				, lowerCAmelCase__				, lowerCAmelCase__ )					->				Any:




        '''simple docstring'''
        lowercase__:   Any  			=   params

        lowercase__:   List[Any]  			=   np.array(lowerCAmelCase__ )
        lowercase__:   Optional[Any]  			=   np.array([len(lowerCAmelCase__ ) for t in data] )

        self.check()
        self.remove_long_sequences()
        self.remove_empty_sequences()
        self.remove_unknown_sequences()
        self.check()
        self.print_statistics()
 def __getitem__(   self				, lowerCAmelCase__ )					->				List[Any]:




        '''simple docstring'''
        return (self.token_ids[index], self.lengths[index])
 def __len__(   self )					->				List[Any]:




        '''simple docstring'''
        return len(self.lengths )
 def 		SCREAMING_SNAKE_CASE__   (   self )					->				Tuple:




        '''simple docstring'''
        assert len(self.token_ids ) == len(self.lengths )
        assert all(self.lengths[i] == len(self.token_ids[i] ) for i in range(len(self.lengths ) ) )
 def 		SCREAMING_SNAKE_CASE__   (   self )					->				Union[str, Any]:




        '''simple docstring'''
        lowercase__:   Any  			=   self.params.max_model_input_size
        lowercase__:   Dict  			=   self.lengths > max_len
        logger.info(F'Splitting {sum(lowerCAmelCase__ )} too long sequences.' )

        def divide_chunks(lowerCAmelCase__				, lowerCAmelCase__ ):
               return [l[i : i + n] for i in range(0				, len(lowerCAmelCase__ )				, lowerCAmelCase__ )]

        lowercase__:   str  			=   []
        lowercase__:   List[str]  			=   []
        if self.params.mlm:
               lowercase__			,						lowercase__:   str  			=   self.params.special_tok_ids['cls_token'], self.params.special_tok_ids['sep_token']
        else:
               lowercase__			,						lowercase__:   int  			=   self.params.special_tok_ids['bos_token'], self.params.special_tok_ids['eos_token']

        for seq_, len_ in zip(self.token_ids				, self.lengths ):
               assert (seq_[0] == cls_id) and (seq_[-1] == sep_id), seq_
               if len_ <= max_len:
                      new_tok_ids.append(seq_ )
                      new_lengths.append(len_ )
               else:
                      lowercase__:   Optional[Any]  			=   []
                      for sub_s in divide_chunks(seq_				, max_len - 2 ):
                             if sub_s[0] != cls_id:
                                    lowercase__:   int  			=   np.insert(lowerCAmelCase__				, 0				, lowerCAmelCase__ )
                             if sub_s[-1] != sep_id:
                                    lowercase__:   Union[str, Any]  			=   np.insert(lowerCAmelCase__				, len(lowerCAmelCase__ )				, lowerCAmelCase__ )
                             assert len(lowerCAmelCase__ ) <= max_len
                             assert (sub_s[0] == cls_id) and (sub_s[-1] == sep_id), sub_s
                             sub_seqs.append(lowerCAmelCase__ )

                      new_tok_ids.extend(lowerCAmelCase__ )
                      new_lengths.extend([len(lowerCAmelCase__ ) for l in sub_seqs] )

        lowercase__:   Union[str, Any]  			=   np.array(lowerCAmelCase__ )
        lowercase__:   Union[str, Any]  			=   np.array(lowerCAmelCase__ )
 def 		SCREAMING_SNAKE_CASE__   (   self )					->				Tuple:




        '''simple docstring'''
        lowercase__:   Dict  			=   len(self )
        lowercase__:   Union[str, Any]  			=   self.lengths > 11
        lowercase__:   List[Any]  			=   self.token_ids[indices]
        lowercase__:   Optional[Any]  			=   self.lengths[indices]
        lowercase__:   List[str]  			=   len(self )
        logger.info(F'Remove {init_size - new_size} too short (<=11 tokens) sequences.' )
 def 		SCREAMING_SNAKE_CASE__   (   self )					->				int:




        '''simple docstring'''
        if "unk_token" not in self.params.special_tok_ids:
               return
        else:
               lowercase__:   List[str]  			=   self.params.special_tok_ids['unk_token']
        lowercase__:   str  			=   len(self )
        lowercase__:   Tuple  			=   np.array([np.count_nonzero(a == unk_token_id ) for a in self.token_ids] )
        lowercase__:   Any  			=   (unk_occs / self.lengths) < 0.5
        lowercase__:   Tuple  			=   self.token_ids[indices]
        lowercase__:   str  			=   self.lengths[indices]
        lowercase__:   Dict  			=   len(self )
        logger.info(F'Remove {init_size - new_size} sequences with a high level of unknown tokens (50%).' )
 def 		SCREAMING_SNAKE_CASE__   (   self )					->				str:




        '''simple docstring'''
        if not self.params.is_master:
               return
        logger.info(F'{len(self )} sequences' )
        # data_len = sum(self.lengths)
        # nb_unique_tokens = len(Counter(list(chain(*self.token_ids))))
        # logger.info(f'{data_len} tokens ({nb_unique_tokens} unique)')

        # unk_idx = self.params.special_tok_ids['unk_token']
        # nb_unknown = sum([(t==unk_idx).sum() for t in self.token_ids])
        # logger.info(f'{nb_unknown} unknown tokens (covering {100*nb_unknown/data_len:.2f}% of the data)')
 def 		SCREAMING_SNAKE_CASE__   (   self				, lowerCAmelCase__ )					->				int:




        '''simple docstring'''
        lowercase__:   Union[str, Any]  			=   [t[0] for t in batch]
        lowercase__:   Dict  			=   [t[1] for t in batch]
        assert len(lowerCAmelCase__ ) == len(lowerCAmelCase__ )

        # Max for paddings
        lowercase__:   List[Any]  			=   max(lowerCAmelCase__ )

        # Pad token ids
        if self.params.mlm:
               lowercase__:   Dict  			=   self.params.special_tok_ids['pad_token']
        else:
               lowercase__:   Optional[Any]  			=   self.params.special_tok_ids['unk_token']
        lowercase__:   int  			=   [list(t.astype(lowerCAmelCase__ ) ) + [pad_idx] * (max_seq_len_ - len(lowerCAmelCase__ )) for t in token_ids]
        assert len(tk_ ) == len(lowerCAmelCase__ )
        assert all(len(lowerCAmelCase__ ) == max_seq_len_ for t in tk_ )

        lowercase__:   Tuple  			=   torch.tensor(tk_ )  # (bs, max_seq_len_)
        lowercase__:   Optional[Any]  			=   torch.tensor(lowerCAmelCase__ )  # (bs)
        return tk_t, lg_t


