Analytics

Calculer les scores de lisibilité pour le contenu

Il existe de nombreuses formules de lisibilité différentes, qui cherchent à fournir un indice sur la façon dont lisible n’importe quel extrait de texte l’est. En règle générale, ces formules génèrent un score de niveau scolairequi indique, grosso modo, le niveau d’études requis pour lire l’extrait de texte avec aisance.

Tout « indice de qualité » qui cherche à réduire la complexité de quelque chose d’aussi multiforme que la lecture doit faire l’objet d’un examen minutieux. C’est vrai pour le taux de rebond, c’est vrai pour le temps sur la page, et c’est vrai pour un score de lisibilité.

Score de lisibilité dans Google Analytics

Cependant, je pense qu’il est intéressant de collecter des métadonnées pour votre contenu. Qui sait, vous trouverez peut-être des corrélations entre la difficulté de lire n’importe quel morceau de texte et le degré d’engagement que le contenu engendre.

Dans cet article, je vais vous montrer comment créer un Variable JavaScript personnalisée dans Google Tag Manager qui crée une fonction utilitaire. Cette fonction peut être appelée avec n’importe quel morceau de texte (par exemple, le contenu textuel de votre élément DOM de contenu principal), et elle renverra un objet avec une variété de scores basés sur différentes formules de lisibilité, ainsi qu’un niveau de note médian calculé à partir de ces scores.

Vous pouvez utiliser ces informations pour annoter vos visites de pages vues avec des dimensions personnalisées (avec une mise en garde concernant ses déclencheurs) lors de l’envoi des données à Google Analytics.

Vous pouvez également envoyer les données à une propriété Google Analytics : Application + Web prête pour cette exportation de données BigQuery juteuse.

Je vais vous montrer comment faire les deux dans ce guide.

Grâce à Munaz Anjum pour m’avoir donné envie d’écrire cet article !

La variable JavaScript personnalisée

Dans ce chapitre, nous passerons en revue la variable JavaScript personnalisée que vous devrez créer pour que cela fonctionne.

« Pourquoi une variable JavaScript personnalisée ? Pourquoi pas un modèle personnalisé ? » Je vous entends demander. Je sais! Ce serait parfait pour un modèle personnalisé. Hélas, les modèles ne prennent pas encore en charge toute l’étendue des expressions régulières, et ils sont absolument vitaux pour les algorithmes requis par les formules dans la variable.

Ce que vous obtiendrez

La variable JavaScript personnalisée renvoie un une fonctionque vous pouvez ensuite appeler avec une chaîne dans une autre variable JavaScript personnalisée ou une balise HTML personnalisée.

Lorsque vous appelez la fonction avec une chaîne, par exemple :

var readabilityFunction = {{readabilityFunction}};  var text = 'At the heart of this paper lies the elusive concept of \ variation: how speakers can simultaneously share a common knowledge \ of a unified language system and develop it in idiosyncratic and unique \ ways. Studies of variation do not come without their fair share of \ controversy. Since they necessarily incorporate the attention to detail \ that a descriptivist approach demands together with a level of abstraction \ that is likewise required by all studies of linguistic phenomena, the \ results are often as debatable as they are revelatory. It is thus the \ researcher’s job to describe the phenomenon as lucidly as possible, \ without drawing conclusions that extend beyond the scope of the data at hand.'  console.log(readabilityFunction(text));  // Outputs // { //   automatedReadabilityIndex: 15.48, //   colemanLiauIndex: 13.12, //   fleschKincaidGrade: 16.41, //   fleschReadingEase: 28.17, //   linsearWriteFormula: 18.25, //   medianGrade: 17, //   readingTime: 27.34, //   rix: 9.5, //   smogIndex: 17.41 // } 

Cet extrait particulier (de ma thèse de maîtrise) a une note de lisibilité médiane de 17 ce qui signifie, vaguement traduit, qu’il faut environ 17 ans de éducation pour lire un texte comme celui-ci avec facilité. Les temps de lecture est d’environ 27 secondes.

L’objet pour l’article que vous lisez ressemble à ça (aïe !) :

{   automatedReadabilityIndex: 15.48,   colemanLiauIndex: 3.77,   fleschKincaidGrade: 16.96,   fleschReadingEase: 39.67,   linsearWriteFormula: 13.2,   medianGrade: 15,   readingTime: 1524.22,   rix: 7.11,   smogIndex: 15.85 } 

Je vais partager ce que signifient ces différents nombres et noms dans un instant.

Contenu variable

Le code est une réécriture JavaScript de la bibliothèque Python textstat.py. Je n’ai inclus aucune note de lisibilité qui repose sur une liste de mots en anglais (ainsi, toutes les formules qui nécessitent une définition de ce qu’est un mot « courant » ou « facile » en anglais sont ignorées).

Créer une nouvelle variable JavaScript personnaliséedonnez-lui un nom (ex. readabilityFunction), et copiez-collez le JavaScript suivant dans le corps.

function() {   return function(text) {      /* To speed the script up, you can set a sampling rate in words. For example, if you set      * sampleLimit to 1000, only the first 1000 words will be parsed from the input text.      * Set to 0 to never sample.      */          var sampleLimit = 1000;          // Manual rewrite of the textstat Python library (https://github.com/shivam5992/textstat/)          /*       * Regular expression to identify a sentence. No, it's not perfect.       * Fails e.g. with abbreviations and similar constructs mid-sentence.      */     var sentenceRegex = new RegExp('[.?!]\\s[^a-z]', 'g');          /*      * Regular expression to identify a syllable. No, it's not perfect either.      * It's based on English, so other languages with different vowel / consonant distributions      * and syllable definitions need a rewrite.      * Inspired by https://bit.ly/2VK9dz1      */     var syllableRegex = new RegExp('[aiouy]+e*|e(?!d$|ly).|[td]ed|le$', 'g');          // Baseline for FRE - English only     var freBase = {       base: 206.835,       sentenceLength: 1.015,       syllablesPerWord: 84.6,       syllableThreshold: 3     };          var cache = {};          var punctuation = ['!','"','#','$','%','&','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[',']','^','_','`','{','|','}','~'];          var legacyRound = function(number, precision) {       var k = Math.pow(10, (precision || 0));       return Math.floor((number * k) + 0.5 * Math.sign(number)) / k;     };          var charCount = function(text) {       if (cache.charCount) return cache.charCount;       if (sampleLimit > 0) text = text.split(' ').slice(0, sampleLimit).join(' ');       text = text.replace(/\s/g, '');       return cache.charCount = text.length;     };          var removePunctuation = function(text) {       return text.split('').filter(function(c) {         return punctuation.indexOf(c) === -1;       }).join('');     };          var letterCount = function(text) {       if (sampleLimit > 0) text = text.split(' ').slice(0, sampleLimit).join(' ');       text = text.replace(/\s/g, '');       return removePunctuation(text).length;     };          var lexiconCount = function(text, useCache, ignoreSample) {       if (useCache && cache.lexiconCount) return cache.lexiconCount;       if (ignoreSample !== true && sampleLimit > 0) text = text.split(' ').slice(0, sampleLimit).join(' ');       text = removePunctuation(text);       var lexicon = text.split(' ').length;       return useCache ? cache.lexiconCount = lexicon : lexicon;     };          var getWords = function(text, useCache) {       if (useCache && cache.getWords) return cache.getWords;       if (sampleLimit > 0) text = text.split(' ').slice(0, sampleLimit).join(' ');       text = text.toLowerCase();       text = removePunctuation(text);       var words = text.split(' ');       return useCache ? cache.getWords = words : words;     }          var syllableCount = function(text, useCache) {       if (useCache && cache.syllableCount) return cache.syllableCount;       var count = 0;       var syllables = getWords(text, useCache).reduce(function(a, c) {           return a + (c.match(syllableRegex) || [1]).length;       }, 0);       return useCache ? cache.syllableCount = syllables : syllables;     };          var polySyllableCount = function(text, useCache) {       var count = 0;       getWords(text, useCache).forEach(function(word) {         var syllables = syllableCount(word);         if (syllables >= 3) {           count += 1;         }       });       return count;     };          var sentenceCount = function(text, useCache) {       if (useCache && cache.sentenceCount) return cache.sentenceCount;       if (sampleLimit > 0) text = text.split(' ').slice(0, sampleLimit).join(' ');       var ignoreCount = 0;       var sentences = text.split(sentenceRegex);       sentences.forEach(function(s) {         if (lexiconCount(s, true, false) <= 2) { ignoreCount += 1; }       });       var count = Math.max(1, sentences.length - ignoreCount);       return useCache ? cache.sentenceCount = count : count;     };          var avgSentenceLength = function(text) {       var avg = lexiconCount(text, true) / sentenceCount(text, true);       return legacyRound(avg, 2);     };          var avgSyllablesPerWord = function(text) {       var avg = syllableCount(text, true) / lexiconCount(text, true);       return legacyRound(avg, 2);     };          var avgCharactersPerWord = function(text) {       var avg = charCount(text) / lexiconCount(text, true);       return legacyRound(avg, 2);     };          var avgLettersPerWord = function(text) {       var avg = letterCount(text, true) / lexiconCount(text, true);       return legacyRound(avg, 2);     };          var avgSentencesPerWord = function(text) {       var avg = sentenceCount(text, true) / lexiconCount(text, true);       return legacyRound(avg, 2);     };          var fleschReadingEase = function(text) {       var sentenceLength = avgSentenceLength(text);       var syllablesPerWord = avgSyllablesPerWord(text);       return legacyRound(         freBase.base -          freBase.sentenceLength * sentenceLength -          freBase.syllablesPerWord * syllablesPerWord,         2       );     };          var fleschKincaidGrade = function(text) {       var sentenceLength = avgSentenceLength(text);       var syllablesPerWord = avgSyllablesPerWord(text);       return legacyRound(         0.39 * sentenceLength +         11.8 * syllablesPerWord -         15.59,         2       );     };          var smogIndex = function(text) {       var sentences = sentenceCount(text, true);       if (sentences >= 3) {         var polySyllables = polySyllableCount(text, true);         var smog = 1.043 * (Math.pow(polySyllables * (30 / sentences), 0.5)) + 3.1291;         return legacyRound(smog, 2);       }       return 0.0;     };          var colemanLiauIndex = function(text) {       var letters = legacyRound(avgLettersPerWord(text) * 100, 2);       var sentences = legacyRound(avgSentencesPerWord(text) * 100, 2);       var coleman = 0.0588 * letters - 0.296 * sentences - 15.8;       return legacyRound(coleman, 2);     };          var automatedReadabilityIndex = function(text) {       var chars = charCount(text);       var words = lexiconCount(text, true);       var sentences = sentenceCount(text, true);       var a = chars / words;       var b = words / sentences;       var readability = (         4.71 * legacyRound(a, 2) +         0.5 * legacyRound(b, 2) -         21.43       );       return legacyRound(readability, 2);      };          var linsearWriteFormula = function(text) {       var easyWord = 0;       var difficultWord = 0;       var roughTextFirst100 = text.split(' ').slice(0,100).join(' ');       var plainTextListFirst100 = getWords(text, true).slice(0,100);       plainTextListFirst100.forEach(function(word) {         if (syllableCount(word) < 3) {           easyWord += 1;         } else {           difficultWord += 1;         }       });       var number = (easyWord + difficultWord * 3) / sentenceCount(roughTextFirst100);       if (number <= 20) {         number -= 2;       }       return legacyRound(number / 2, 2);     };          var rix = function(text) {       var words = getWords(text, true);       var longCount = words.filter(function(word) {         return word.length > 6;       }).length;       var sentencesCount = sentenceCount(text, true);       return legacyRound(longCount / sentencesCount, 2);     };          var readingTime = function(text) {       var wordsPerSecond = 4.17;       // To get full reading time, ignore cache and sample       return legacyRound(lexiconCount(text, false, true) / wordsPerSecond, 2);     };          // Build textStandard     var grade = [];     var obj = {};     (function() {              // FRE       var fre = obj.fleschReadingEase = fleschReadingEase(text);       if (fre < 100 && fre >= 90) {         grade.push(5);       } else if (fre < 90 && fre >= 80) {         grade.push(6);       } else if (fre < 80 && fre >= 70) {         grade.push(7);       } else if (fre < 70 && fre >= 60) {         grade.push(8);         grade.push(9);       } else if (fre < 60 && fre >= 50) {         grade.push(10);       } else if (fre < 50 && fre >= 40) {         grade.push(11);       } else if (fre < 40 && fre >= 30) {         grade.push(12);       } else {         grade.push(13);       }              // FK       var fk = obj.fleschKincaidGrade = fleschKincaidGrade(text);       grade.push(Math.floor(fk));       grade.push(Math.ceil(fk));              // SMOG       var smog = obj.smogIndex = smogIndex(text);       grade.push(Math.floor(smog));       grade.push(Math.ceil(smog));              // CL       var cl = obj.colemanLiauIndex = colemanLiauIndex(text);       grade.push(Math.floor(cl));       grade.push(Math.ceil(cl));              // ARI       var ari = obj.automatedReadabilityIndex = automatedReadabilityIndex(text);       grade.push(Math.floor(ari));       grade.push(Math.ceil(ari));              // LWF       var lwf = obj.linsearWriteFormula = linsearWriteFormula(text);       grade.push(Math.floor(lwf));       grade.push(Math.ceil(lwf));              // RIX       var rixScore = obj.rix = rix(text);       if (rixScore >= 7.2) {         grade.push(13);       } else if (rixScore < 7.2 && rixScore >= 6.2) {         grade.push(12);       } else if (rixScore < 6.2 && rixScore >= 5.3) {         grade.push(11);       } else if (rixScore < 5.3 && rixScore >= 4.5) {         grade.push(10);       } else if (rixScore < 4.5 && rixScore >= 3.7) {         grade.push(9);       } else if (rixScore < 3.7 && rixScore >= 3.0) {         grade.push(8);       } else if (rixScore < 3.0 && rixScore >= 2.4) {         grade.push(7);       } else if (rixScore < 2.4 && rixScore >= 1.8) {         grade.push(6);       } else if (rixScore < 1.8 && rixScore >= 1.3) {         grade.push(5);       } else if (rixScore < 1.3 && rixScore >= 0.8) {         grade.push(4);       } else if (rixScore < 0.8 && rixScore >= 0.5) {         grade.push(3);       } else if (rixScore < 0.5 && rixScore >= 0.2) {         grade.push(2);       } else {         grade.push(1);       }              // Find median grade       grade = grade.sort(function(a, b) { return a - b; });       var midPoint = Math.floor(grade.length / 2);       var medianGrade = legacyRound(         grade.length % 2 ?          grade[midPoint] :          (grade[midPoint-1] + grade[midPoint]) / 2.0       );       obj.medianGrade = medianGrade;            })();          obj.readingTime = readingTime(text);            return obj;   }; } 

C’est une bouchée, alors passons en revue chaque formule avec le code qui s’y rapporte.

Installer

Les deux premières étapes de la variable établissent une grande partie de ce qui suit.

var sampleLimit = 1000; 

L’exécution d’expressions régulières peut être lent. Si vous avez un article de 5000 mots, par exemple, compter les syllabes de chaque mot peut prendre un temps looooooong, et peut être dangereux s’il est exécuté au chargement de la page.

j’ai introduit le sampleLimit variable, qui établit essentiellement une taille d’échantillon maximale pour exécuter les calculs de lisibilité. Si sampleLimit est défini sur la valeur par défaut de 1000, le script échantillonnera les 1000 premiers mots de l’entrée. Le résultat final devrait être dans le terrain de balle d’un score calculé par rapport au texte intégral, mais cela dépend bien sûr du type de texte en question.

Si vous voulez éviter l’échantillonnage, réglez sampleLimit pour 0.

var sentenceRegex = new RegExp('[.?!]\\s[^a-z]', 'g'); var syllableRegex = new RegExp('[aiouy]+e*|e(?!d$|ly).|[td]ed|le$', 'g'); 

La première expression régulière est utilisée pour diviser un morceau de texte en Phrases. Non, ce n’est pas parfait.

Mais ce n’est pas grave – nous recherchons des abstractions et plus vous avez de texte, plus le score convergera vers une norme.

La deuxième expression régulière compte le nombre de syllabes dans un texte. Non, ce n’est pas parfait non plus. Il est basé sur l’anglais et peut-être sur d’autres langues germaniques, mais la syllabation peut changer d’une langue à l’autre. Par conséquent, si vous souhaitez analyser du contenu dans d’autres langues, vous devez modifier l’expression régulière.

Les autres étapes de configuration sont répertoriées ici.

Fonction / signature variable La description
freBase Les chiffres de base pour le calcul du score Flesch Reading-Ease en anglais.
cache Utilitaire qui met en cache la plupart des calculs, de sorte que les expressions régulières ne soient exécutées qu’une seule fois pour les éléments mis en cache.
punctuation Liste des symboles de ponctuation.
legacyRound() Fonction pour arrondir le nombre d’entrée à la précision donnée.
charCount() Comptez les caractères dans l’entrée.
removePunctuation() Supprimez toute ponctuation de l’entrée.
letterCount() Comptez les lettres dans l’entrée.
lexiconCount() Comptez les mots dans l’entrée.
getWords() Renvoie les mots dans l’entrée.
syllableCount() Comptez les syllabes dans l’entrée.
polySyllableCount() Comptez le nombre de mots de trois syllabes ou plus dans l’entrée.
sentenceCount() Comptez le nombre de phrases dans l’entrée.
avgSentenceLength() Comptez la longueur moyenne des phrases (nombre de mots) dans l’entrée.
avgSyllablesPerWord() Comptez le nombre moyen de syllabes par mot dans l’entrée.
avgCharactersPerWord() Comptez le nombre moyen de caractères par mot dans l’entrée.
avgLettersPerWord() Comptez le nombre moyen de lettres par mot dans l’entrée.
avgSentencesPerWord() Comptez le nombre moyen de phrases par mot dans l’entrée.

Ces utilitaires permettent de calculer les formules de lisibilité.

1. Flesch Reading-Facilité

Le test Flesch Reading-Ease est probablement l’un des tests de lisibilité les plus connus. Il est utilisé par exemple par Yoast et Grammarly pour calculer leurs scores de lisibilité.

Pour la langue anglaise, l’algorithme est :

206.835 - 1.015 x (words / sentences) - 84.6 x (syllables / words)

Cela génère un score compris entre 1 et 100, où plus le score est élevé, plus le texte est facile à lire.

Un score entre 70 et 80 serait considéré comme facile à lire pour un élève de 7e aux États-Unis.

Dans la variable Custom JavaScript, Flesch Reading-Ease est généré comme ceci :

var fleschReadingEase = function(text) {   var sentenceLength = avgSentenceLength(text);   var syllablesPerWord = avgSyllablesPerWord(text);   return legacyRound(     freBase.base -      freBase.sentenceLength * sentenceLength -      freBase.syllablesPerWord * syllablesPerWord,     2   ); }; 

2. Grade Flesch-Kincaid

Le score Flesch-Kincaid Grade Level produit un nombre qui correspond au niveau scolaire américain généralement requis pour comprendre le texte. Si le score renvoie un nombre supérieur à 10, il peut également être utilisé pour calculer le Années d’études nécessaire pour comprendre le texte.

L’algorithme est :

0.39 x (words / sentences) + 11.8 x (syllables / words) - 15.59

Dans la variable JavaScript personnalisé, cela se traduit par :

var fleschKincaidGrade = function(text) {   var sentenceLength = avgSentenceLength(text);   var syllablesPerWord = avgSyllablesPerWord(text);   return legacyRound(     0.39 * sentenceLength +     11.8 * syllablesPerWord -     15.59,     2   ); }; 

3. Niveau SMOG

Le grade SMOG, abréviation de Smettre en œuvre Mmesure oF gobbledygook, estime les années d’études nécessaires pour comprendre un texte donné. Il est particulièrement préféré (par rapport à Flesch-Kincaid) dans le secteur de la santé pour la conception de contenu.

L’algorithme est :

1.0430 x squareroot(polysyllables x (30 / sentences)) + 3.1291

Dans la variable, ce serait:

var smogIndex = function(text) {   var sentences = sentenceCount(text, true);   if (sentences >= 3) {     var polySyllables = polySyllableCount(text, true);     var smog = 1.043 * Math.pow(polySyllables * (30 / sentences), 0.5) + 3.1291;     return...
Source : www.simoahava.com

Articles similaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Bouton retour en haut de la page
Index