Découvrons les étapes de l’augmentation des données pour le NLP avec CamemBERT
Il existe une excellente référence expliquant le fonctionnement de l’augmentation des données . Cependant, au lieu d’utiliser une bibliothèque toute faite, il est plus intéressant de tout développer à partir de zéro. De plus, le fait que vous ayez implémenté l’algorithme vous-même vous permet de l’ajuster en fonction de votre contexte spécifique.
En bref, les techniques d’augmentation de données comprennent :
- Traduction arrière
- Remplacement de synonyme
- Insertion aléatoire
- Suppression aléatoire
- Mélanger les phrases, transformer, etc.
Il existe également un package python qui vous permet d’effectuer des augmentations de base et avancées, appelé NLPAug. NLPAug propose trois types d’augmentation :
- Augmentation au niveau du personnage
- Augmentation au niveau des mots
- Augmentation au niveau de la phrase
Selon Jakub Czakon, l’auteur de la référence discutée :
» D’après mon expérience, la technique la plus couramment utilisée et la plus efficace est le remplacement de synonymes via des incorporations de mots. «
Semble raisonnable. Mais comme mentionné dans l’introduction, nous allons essayer de mettre en œuvre toutes ces étapes nous-mêmes.
Étape 0 : Importations
Étape 1 : Incorporations contextuelles de mots
Pour cela nous allons utiliser le CamemBERT, une extension française du BERT. Une courte citation du site officiel :
CamemBERT est un modèle linguistique de pointe pour français basé sur l’architecture RoBERT, et a été pré-formé et évalué sur le sous-corps français du corpus multilingue OSCAR nouvellement disponible. Nous évaluerons CamemBERT dans quatre tâches différentes en aval pour le français : le balisage des parties du discours (POS), l’analyse des dépendances, la reconnaissance des entités nommées (NER) et l’inférence du langage naturel (NLI) ; améliorer l’état de l’art pour la plupart des tâches par rapport aux approches monolingues et multilingues précédentes, ce qui confirme l’efficacité des grands modèles linguistiques pré-entraînés pour le français. CamemBERT a été formé et évalué par Louis Martin, Benjamin Muller, Pedro Javier Ortiz Suárez, Yoann Dupont, Laurent Romary, Éric Villemonte de la Clergerie, Djamé Seddah et Benoît Sagot.
Donc, la première chose à faire est de télécharger le modèle et d’initialiser l’objet camembert.
camembert = torch.hub.load(‘pytorch/fairseq’, ‘camembert’)
camembert.eval()
N.B. il y a des dépendances supplémentaires comme hydra-core ou omegaconf à installer. Important : ne pas confondre avec le package hydra, sinon, vous devrez tout désinstaller.
Étape 2 : Masquer un mot aléatoire et générer des textes synthétiques
Cette étape est assez simple, il suffit de masquer un mot au hasard et d’envoyer cette ligne masquée au camembert pour laisser le modèle de langage deviner le mot masqué. Ces mots devinés sont classés par leurs probabilités en ordre décroissant.
Masquer un mot aléatoire dans une ligne
def mask_random_word(text_line):
text_array = text_line.split()
masked_token_index = random.randint(0, len(text_array)-1)
text_array[masked_token_index] = « <mask> »
output_text = » « .join(text_array)
return output_text
Générer du texte synthétique pour une ligne de texte
def generate_synthetic_texts(text, number_of_examples):
output = []
for i in range(number_of_examples):
masked_line = mask_random_word(text)
top_unmasked = camembert.fill_mask(masked_line, topk=1)
output.append(top_unmasked[0][0])
return output
Étape 3 : Obtenez la classe majoritaire et exécutez
Nous avons presque terminé. Il ne reste plus qu’à détecter la classe majoritaire et créer N items par classe minoritaire en fonction de la taille de la classe majoritaire.
Lire l’ensemble de données texte
myModel = pd.read_csv(‘model.csv’, sep=’;’)
Obtenez la classe majoritaire
counter = Counter(myModel[‘Result’])
max_intent = »
max_intent_count = 0
for intent in set(myModel[‘Result’]):
if max_intent_count < counter[intent]:
max_intent = intent
max_intent_count = counter[intent]
Calculer le nombre d’items à générer par classe minoritaire
threshold = floor(max_intent_count/2)
minority_intents = set(myModel[‘Result’])-set([max_intent])
for intent in minority_intents:
print (intent, « started »)
intent_examples = myModel[myModel[‘Result’]==intent]
intent_count = intent_examples.shape[0]
examples_to_generate = max_intent_count – intent_count
if examples_to_generate > threshold:
body_examples = intent_examples[‘Body’]
number_of_synthetic_per_example = ceil(examples_to_generate/intent_count)
else:
body_examples = intent_examples[‘Body’][:examples_to_generate]
number_of_synthetic_per_example = 1
print (intent_count,examples_to_generate, number_of_synthetic_per_example)
syntetic_bodies = []
for body in body_examples:
syntetic_bodies.append(generate_synthetic_texts(body, number_of_synthetic_per_example))
# flatten arrays
syntetic_bodies = [item for sublist in syntetic_bodies for item in sublist]
augmented_df = pd.DataFrame()
augmented_df[‘Body’]=syntetic_subjects
augmented_df[‘Result’]=intent
myModel = alexModel.append(augmented_df)
print (intent, « processed »)
N.B. le seuil est nécessaire pour définir si nous générons des éléments synthétiques pour chaque élément de la classe minoritaire, ou uniquement sur le sous-tableau sélectionné. Par exemple, si notre classe majoritaire est composée de 500 éléments et que notre classe minoritaire en a 350, le moyen le plus logique est de sélectionner un sous-tableau de 15 éléments et de générer 1 exemple synthétique pour chacun.
Discussion
L’exécution prend un certain temps (40 minutes pour un ensemble de données de quelques milliers de lignes), il peut donc être intéressant d’essayer de paralléliser l’exécution (peut-être en utilisant Spark sur Azure Databricks). J’essaierai de publier un article à ce sujet dans l’un des prochains tutoriels.
Ecrit par Alibek Jakupov, Data scientist et Microsoft MVP Artifical Intelligence.