Une simple comparaison de lexiques

Table des matières

1. Des réflexions en prétexte d'une introduction

Depuis un moment, je pense aux critères qui font que les oeuvres de certains écrivains français me semblent abordable, tandis que d'autres ne me le semblent pas. Victor Hugo me semble trop dur à lire, Amin Maalouf tout a fait plaisant. Il y a souvent plusieurs raisons qui peuvent expliquer cette différence de sentiment, dont la complexité et la longueur des phrases, le lexique, le contexte historique, le registre, ou bien l'objet lui-même du livre. Par rapport aux deux écrivains cités, le lexique d'Hugo est, a vista de naz, à la fois plus ancien (et donc moins en lien avec le français parlé au 21e siècle) et plus riche, et les phrases plus longues et tordues. C'est un français du 19e siècle, et donc le contexte historique est différent, et les sous-entendus évidents pour les lecteurs contemporains se cachent et sont difficilement appréhendés par nous aujourd'hui, et surtout ceux, comme moi, pour qui le français est une langue apprise. En revanche, un écrivain comme Amin Maalouf me parle comme un vieil ami, avec nos histoires partagées et sans trop de langage opaque. Maalouf écrit certes dans un style très littéraire, peut-être même démodé, avec des descriptions poétiques et des mots qui m'oblige de chercher dans le dictionnaire, mais j'arrive à le lire avec fluidité, sans trop ayant besoin de relire des passages (que je fais, il faut l'admettre, même avec des livres en anglais). Son lexique, bien que riche, me semble plus restreint, plus épuré. Et au delà des mots et des phrases, il y a ses origines au Moyen Orient. Puisque il est d'origine libanais, même s'il a une maîtrise plus-que-parfaite du français, il ne s'exprime pas comme les autres français, et son style le reflète. Peut-être aussi puisque j'ai des origines libanaises, sa façon de penser, et peut-être aussi de penser la langue française, est plus abordable pour moi qui partage un peu cette vue du monde émanant d'un centre de gravité situé au Levant. Et donc, en plus du fait que même les français nés et éduqués en France admettent une difficulté particulière chez Hugo, il y a le plus value d'une distance culturelle qui fait ensemble que je n'ai jamais osé essayer de lire un roman d'Hugo, tandis que j'en ai lu plusieurs de Maalouf. Je ne dis pas que le jour n'adviendra jamais, mais je m'y sens toujours assez loin.

Mais que je trouve Maalouf plus facile à lire qu'Hugo n'a rien de très surprenant; je paris que la plupart, sinon la majorité des français et des francophones diraient la même chose. En revanche, et c'est là l'objet de cet essai, j'ai depuis plus d'une décennie considéré que Voltaire est mon écrivain préféré, du moins en langue française. Et cette déclaration étonne parfois mes connaissances français, car il n'est pas généralement admis que ce soit un écrivain facile, et par conséquent encore moins pour un étranger. Pourtant, j'ai trouvé son style inégalé en sa clarté, sa transparence. Certes, il parle de sujets profonds parfois qui nécessitent souvent une longue réflexion par le lecteur, et des connaissances en histoire, politique et philosophie. Et certes, son contexte historique est encore plus ancien que celui d'Hugo, son langage d'autant plus démodé et donc, théoriquement, plus difficilement déchiffrable. Mais ses phrases sont d'une économie admirable, et il ne perd pas trop de temps sur des descriptions détaillée de ses personnages. Souvent, en lisant ces romans, et même de ses autres oeuvres, j'ai fait la réflexion qu'il est difficilement concevable de transmettre autant d'idées avec mois de paroles, et que ça ait du sens. Je le considère comme un modèle non seulement de bon français, mais de bonne écriture tout court. (J'admets ici qu'aujourd'hui je trouve Voltaire plus difficile à lire qu'avant, et donc peut-être est-il un effet de familiarité, et d'expérience. Mais je tient à mon constat d'un vocabulaire plus restreint.) Alors, c'est ce que je pensais. Mais est-ce que c'est vrai? Mis à part la subjectivité de mon appréciation pour son style en tant que tel, est-ce que son français est réellement plus simple? Plus économique? Plus facile à lire? Comment évaluer ces observations approximatives?

Je suis en train de lire un livre de Jules Verne, un plus jeune contemporain d'Hugo, mais que j'estime être plus facile à lire. Pourtant, je ne trouve tout de même pas que ce soit une lecture aisé, et j'ai eu recours au dictionnaire beaucoup plus que je ne l'aurais aimé. J'ai pu m'en passer la plupart du temps, laissant le contexte me guider, mais ça reste assez frustrant, comme si un voile est tendu sur le texte. Il est, à priori, dans ma pensée du moins, un écrivain d'une époque où la belle phrase circumlocutée est privilégiée sur la clarté de l'exposition, et la description de la scène, avec toutes ses couleurs, tous ses parfums et tous ses bruits, est d'une importance centrale dans la narration et qui la sert. Le style repose donc sur beaucoup de noms et d'adjectives rarement présents dans le français de tous les jours, même de l'époque.

C'est à contraster avec la tendance chez Voltaire de mettre l'idée avant tout, où la narration sert à véhiculer l'idée. Voltaire n'est pas unique dans cet égard, et beaucoup de ses contemporains écrivaient de la même manière—je pense, par exemple, aux Lettres persanes de Montesquieu. C'est normal, ce sont des philosophes avant d'être des romanciers, mais leur style est aussi une conséquence du temps dans lequel ils vivaientt et écrivaient.

2. Ma question

Mais finissons avec cette prétendue analyse, car je ne suis pas formé en littérature, ni en français ni en anglais, et passons au vif du sujet: est-ce qu'il y a un moyen de quantifier ces propriétés des écritures voltairienne et vernienne? Les outils modernes de traitement de langues naturelles pourraient nous aider à les explorer.

J'ai une question très simple pour commencer: est-ce qu'on peut comparer les lexiques de Voltaire et de Verne pour voir si mon hypothèse tient? Je vais utiliser la librairie Spacy avec Python pour chercher une réponse approximative. Forcément approximative, car tout ça est loin de mon expertise, mais ça permet au moins d'approcher une sorte de réponse, pour au moins voir si mes observations intuitives des deux écrivains, formées à des moments bien séparés dans le temps car je ne lisais pas les deux en même temps, sont raisonnables. C'est aussi un moyen de me familiariser avec les outils pour lesquels j'ai d'autres dessins dans le proche avenir.

3. Construisons une routine pour fournir la réponse

Commençons cependant en cherchant les textes: le Project Gutenberg héberge bon nombre de vieux textes ayant dépassé les droits d'auteur. Je veux comparer uniquement des textes que j'ai lus—ce qui limite les données d'entrée, mais c'est une bonne chose. Pour Jules Verne, j'ai choisi Le tour du monde en 80 jours, mais puisque les romans de Voltaire sont plus courts j'ai dû en choisir plusieurs: Micromegas, Candide, Jeannot et Colin, Le monde comme il va, et Zadig. (Pour être très honnête, je ne pense pas avoir tout lu de Zadig, ni de Jeannot et Colin.) En total, après avoir effacé les introductions, mentions légales etc., j'ai pour chaque écrivain un échantillon d'autour de 450 ko de texte.

Il faut d'abord importer ces textes dans Spacy pour les traiter. Le traitement comporte plusieurs étapes, la première étant d'affecter des étiquettes à chaque unité lexique—c'est à dire, pour faire simple, à chaque mot. Ceci est fait en deux lignes, en ayant assuré qu'on a bien téléchargé le bon modèle pour le français.

nlp = spacy.load('fr_core_news_lg')
booktext = nlp(booktext_raw)

Ici booktext_raw est le texte en format ASCII, et booktext est le texte étiqueté avec plusieurs étiquettes, comme la partie du discours, ou si c'est un nom propre ou de la ponctuation. On va se servir de ces étiquettes pour filtrer le texte. Mais avant de mettre des étiquettes, j'ai trouvé plus commode d'éliminer de façon explicite certains symboles qui ne sont pas considéré comme étant de la ponctuation régulière, comme le tiret de 8 (utilisé par Project Gutenberg pour indiquer une police en italiques) et des chaînes de tirets ou d'espaces. Ensuite, il y a les notes de bas de page qui sont indiqué dans les textes de Voltaire par un chiffre encadré par des crochets (par ex. [2]) qu'on peut éliminer, ainsi que des symboles d'espaces blanches qui vont sinon apparaître dans le lexique, comme la tabulation (\t) et la fin de ligne (\n). J'ai procédé ainsi,

for num in range(0, 100):
    string = "["+str(num)+"]"
    booktext_mod = booktext_raw.replace(string,"")

booktext_mod = booktext_mod.replace("_","").replace("[","").replace("]","").replace("\n"," ").replace("\t"," ")

# Don't remove hyphens, only two or more in a row
for num in range(20, 1, -1):
    string = "-"*num
    booktext_mod = booktext_mod.replace(string," ")

for num in range(10, 0, -1):
    string = " "*num
    booktext_mod = booktext_mod.replace(string," ")

La limite supérieur de la fonction range dépend de ce qui est comporté dans le texte, ici seulement Le tour du monde comporte des chaînes de tirets. Notez bien que l'ordre dans les boucles est important ici.

Une fois ces symboles supprimés, et les étiquettes affectées, je voulais aussi éliminer les noms propres—principalement les noms de lieu et des personnages. Le traitement génère un index de noms "d'entités", et l'étiquetage les indique. Il suffit de les compiler pour créer le filtre, mais il faut les transformer en des chaînes de caractères d'abord, sinon ils seront toujours considérés comme étant des objets distincts selon où ils sont situés dans le texte, et dans la liste fournie par la fonction set il y restera des doublons, qui seraient autrement supprimés.

entities = []
for entity in booktext.ents:
    entities.append(entity.lemma_)
entities = set(entities)

On procédera à leur filtrage à la fin.

Maintenant, on peut supprimer la ponctuation et une autre liste de mots pré-compilée, les mots vides ou "stop words". Ce sont des mots qui sont tellement fréquent pour tous les locuteurs que leur présence ne nous dit pas grand chose—des mots comme avoir dans toutes ses formes, par exemple. Une boucle avec une condition suffit:

stopwords = nlp.Defaults.stop_words
reduced_text = []
for token in booktext:
    if (not token.is_stop) and (not token.is_punct):
        reduced_text.append(token)

Peut-être l'étape la plus importante est la lemmatisation, ou bien la réduction du mot à une forme simple qui représente le sens du mot sans l'encombrer d'inflexions qui risquent de multiplier le nombre de mots inutilement. Nous cherchons la forme canonique du mot, son lemme. Pour donner un exemple pertinent, les verbes en français peuvent se présenter dans une multitude de formes suivant la personne, nombre, temps, ou mode. Mais il nous suffit de savoir si un verbe existe, et non que le verbe soit utilisé à l'imparfait, au futur etc. Chercher la racine n'est pas forcément pertinent, car la racine pour un nom pourrait bien être la même pour un verbe, même si les mots n'apporte pas la même valeur linguistique. Et un verbe pourrait aussi avoir une racine trompeuses pour notre objectif. De fait, lorsque j'ai utilisé le lemmatiseur de défaut, le lemme pour certains verbes en -er est l'infinitif (comme attendu), mais pour d'autres une forme réduite, qui peut être aussi un nom. J'ai trouvé ça avec au moins deux exemples, aime, et cherche. Le premier pourrait être une unité de mesure d'autrefois, le second un nom apparenté en sens au verbe chercher. J'ai trouvé la solution avec la librairie spacy_lefff, une librairie basée sur le Lexique des formes fléchies du français (Sagot 2010). Il est décrit comme étant (Clément 2006)

un lexique des formes fléchies du français à large couverture, associant à chaque forme son lemme, ses traits morphologiques et d'autres champs récemment disponibles

et est intégré dans Spacy, bien qu'il faut quelques astuces pour s'en servir.

Pour enregistrer les fonctions de spacy_lefff il faut en effet les enregistrer avec le décorateur Language.factory et ensuite les rajouter au pipeline.

from spacy_lefff import LefffLemmatizer, POSTagger
from spacy.language import Language

@Language.factory('french_lemmatizer')
def create_french_lemmatizer(nlp, name):
    return LefffLemmatizer(after_melt=True, default=True)

@Language.factory('melt_tagger')  
def create_melt_tagger(nlp, name):
    return POSTagger()

nlp = spacy.load('fr_core_news_lg')
nlp.add_pipe('melt_tagger', after='parser')
nlp.add_pipe('french_lemmatizer', after='melt_tagger')

Enfin on procède à la lemmatisation, qui est en réalité déjà effectuée lors du traitement initiale, et dont la sortie est contenue dans les attributs .lemma_ et ._.lefff_lemma. Il suffit donc de les extraire.

lemma_red = []
lemma_fff = []
# Parts of speech, plus explanation
for d in reduced_text:
    lemma_red.append(d.lemma_)
    lemma_fff.append(d._.lefff_lemma)

Si la présence d'un attribut _ vous interroge, vous n'êtes pas les seuls, je me suis posé la même question et voici la réponse dans la documentation:

It represents the user space for adding custom attribute extensions.

Rien de très étonnant, et on a accès à la lemmatiseur de défaut en même temps que celui du Lefff, ce qui nous permet de faire des comparaisons rapides.

Pour terminer, on prend la différence entre les listes des mots contenus dans les textes, et les noms propres ainsi:

lemma_red = set(lemma_red)
lemma_fff = set(lemma_fff)
# Remove entities so we only consider vocabulary, not proper nouns
lemma_red_noent = lemma_red.difference(entities)
lemma_fff_noent = lemma_fff.difference(entities)

4. Résultat et discussion

On passe maintenant à la comparaison. On a juste besoin de compter les mots qui restent dans les set:

Écrivain Taille du lexique (défaut) Taille du lexique (Lefff)
Verne 5204 5336
Voltaire 4908 5018

Et le résultat interroge… d'un côté, mon hypothèse se confirme dans la mesure où le vocabulaire de Verne est plus important. En revanche, la différence n'est pas énorme, quelque 300 mots, à peu près. A supposer que ces mots soient repartis de manière équilibrée, et que je connaisse tous les mots utilisés par Voltaire, ça revient à un maximum d'un peu plus d'un mot inconnu par page. Peut-être que je connais tout de même plusieurs de ces mots présumés inconnus, et sans doute pas tous les mots chez voltaire, et la différence s'estompe un peu.

Il y a bien sûr bon nombre de raffinements auxquels on peut songer, par ex. éliminer les notes de bas de page dans les textes de Voltaire, qui risque d'augmenter le lexique sensiblement. Pour en avoir le coeur net, j'ai lancé l'expérience de nouveau après avoir effacé tous les notes de bas de page (seulement celles ajouté par l'éditeur, dont il n'y en avait pas dans Le tour du monde, non pas celles des écrivains eux-mêmes).

Écrivain Taille du lexique (défaut) Taille du lexique (Lefff)
Verne 5204 5336
Voltaire 4655 4765

Et là la différence creuse! On a diminué les textes de Voltaire par à peu près 16 ko, soit une diminution de trois pour cent, et on approche le double de la différence de lexique; plus précisément, on a exactement 253 plus de mots de différence, portant la différence à 549 avec le lemmatiseur de défaut, ou 571 avec celui du Lefff.

On peut aussi raffiner la détection des entités en les indiquant de manière explicite (parfois la détection plante). La liste des mots d'ordre peut être modifié bien sûr, et une compilation d'autres textes est envisageable. Au delà des mots d'ordre, ce serait intéressant de voir combien de mots sont communs entre Verne et Voltaire. Avec la méthode intersection d'un set en Python, on arrive au chiffre de 2358 mots commun avec le lematiseur du Lefff, et 2334 avec celui de défaut. C'est à dire, environ la moitié. Si on soustrait cette moitié, la différence de taille des lexiques et d'autant plus impressionnant, autour de 25 pour cent plus de mots chez Verne.

Et tout ça ne prend pas en compte la possibilité que les lexiques des deux écrivains ne soient pas de la même nature: peut-être que Voltaire se servait d'un lexique plus varié des mots courants, tandis que Verne privilégié des mots savants. Peut-être que c'est le contraire. Clairement on ne peut pas extrapoler de cette petite expérience sans un gros risque d'arriver à des conclusions fausses.

Mais il y a de quoi à réconforter: peut-être le constat le plus intéressant pour moi est que la différence entre deux textes de tailles similaires, malgré leurs temporalités, leur buts et leurs contextes différents, n'est à peine plus de 300 mots, si on garde les notes de bas de page qui sont, à priori, pour moi du moins, assez lisibles. Autrement dit, mis à part les expressions, si on maîtrise le vocabulaire d'un texte parfaitement, passer à un autre ne laisse qu'au grand maximum à peu près 300 nouveau mots à apprendre. Ce constat sera une motivation de plus pour l'autre projet sur lequel je suis en train de travailler qui exploite Spacy, dont je parlerai plus tard.

Je précise que cette expérience n'avait aucune prétention d'être rigoureuse, et d'ailleurs, pour rappelle, je ne suis pas un spécialiste du domaine. Mais je serai intéressé de la poursuivre pour voir quelles autres informations on peut extraire des textes, à commencer, peut-être, avec une analyse similaire d'Hugo lui-même.

5. Références

Clément, B. Lionel et Sagot. (2006). Lexique des formes fléchies du français. Retrieved from https://www.labri.fr/perso/clement/lefff/
Sagot, B. (2010). The Lefff, a freely available and large-coverage morphological and syntactic lexicon for French. In Proceedings of the 7th international conference on Language Resources and Evaluation (LREC 2010), Istanbul, Turkey.

Si vous avez des commentaires, des questions, des corrections (surtout du français, mais aussi de linguistique ou d'informatique)—ou même vous voulez juste dire bonjour pour signaler que vous vous êtes trouvés ici—tous seront bienvenus. Vous pouvez envoyer un mail à malektronica arobase icloud point com.

Auteur: maltron

Created: 2025-06-20 Fri 14:05

Validate