Bon, si vous êtes ici, vous avez sûrement lu la première partie … Si ce n’est pas le cas, je vous invite à la lire avant celle-ci, vous comprendrez un peu plus la réflexion sur le sujet.
ATTENTION: le code ci-dessous est largement améliorable selon vos besoins. Je vous laisse peaufiner à votre sauce, je ne vais pas vous donner tous mes trucs tout de même… quoique… on verra d’ici la fin de cette partie.
On en était donc resté à cette possibilité de générer des contenus lisibles et efficaces autant pour un moteur de recherche que pour un internaute.
C’est un challenge !
Alors pour développer la logique du truc, il faut penser à quelques trucs sur le contenu:
Un texte n’est qu’une suite logique de mots
Une phrase commence par une majuscule et se termine par un point. On apprend ça en primaire. Après on a des sujets, des verbes, des compléments d’objets, des adjectifs, etc…
Ces éléments sont la plupart du temps alignés dans le même sens.
Si on prends la phrase: « Je fais du référencement de site web«
On ne va pas trouver sur le web: « Fais je web du site référencement de«
On est d’accord ! (ok, yen a qui génèrent encore de la bouillie… c’est une autre histoire)
Le problème, c’est que notre petit ordinateur ne sait pas que si j’écris « Je fais » ensuite vient « du« . L’ordinateur comprend les chiffres et sait faire des calculs. Mais il ne comprendra pas un texte.
La première chose à réfléchir alors c’est d’avoir des mots classés avec le mot qui vient avant et celui qui vient après. A partir de là, on peut aller loin… en récupérant non pas le mot qui vient avant mais les 2 ou 3 mots avant. Et pourquoi pas les 10 mots ou la phrase entière depuis la majuscule. On fait pareil avec le ou les termes qui suivent.
Alors si on pense classement et tableau, on peut tester ces 2 phrases:
- Je fais du référencement web
- Je fais un gâteau pour le gouter
Je fais peut être suivi de « du référencement » ou « un gâteau«
Il y a donc déjà ici 2 possibilités de suite… ok ? Maintenant, si on choisit par exemple du référencement, on ne va pas mettre après « pour le goûter«
« Je fais du référencement pour le gouter » n’a pas de sens… mais en fait, ça passe déjà presque pour un moteur de recherche. Moins pour un internaute.
Maintenant qu’on sait ce qu’on peut faire et ce qu’on ne doit pas faire, c’est plus que du code.
On va mettre de côté pour le moment les termes qui précèdent. On parlera de contexte par la suite. Pour le moment, on va se contenter de prédire les termes qui suivent d’autres termes selon des probabilités.
Et pour avoir des probabilités, il nous faut de la data d’entrainement. Dans notre cas, un simple fichier texte rempli de contenu fera l’affaire (GPT-3 à mangé tout Wikipédia et quelques Gigas de données pour s’entrainer). Si vous savez scraper, libre à vous de récupérer ce que vous voulez (j’ai un fichier training_seo.txt de 36Mo par exemple qui contient les articles de quelques bons blogs seo que j’apprécie).
Sinon, commencez par vous faire la main avec un fichier du projet Gutenberg. Vous y trouverez pas mal de trucs sympas (au format txt) pour faire des tests amusants.
Une fois qu’on a notre contenu, il nous faut quelques bouts de codes qui vont permettre l’entrainement et la génération de texte.
On va donc commencer par séparer, dans un texte, tous les mots. On va les mettre dans un tableau pour jouer avec par la suite. Alors avec la langue Française, c’est assez complexe… comme les accents peuvent gêner pas mal, on ne peut pas trouver un truc facile qui capte tous les mots. On va donc se pencher sur les espaces entre ces mots. Tout ce qui est entre deux espaces est donc un terme. On ne va pas dire mot parce qu’une url dans un texte n’est pas un mot…
On va donc « tokenizer » notre texte:
La fonction ci-dessus fait 3 trucs:
- Elle divise le texte en phrases (/\n/gim) pour avoir plusieurs points de départ dans la génération par la suite.
- Pour chaque phrases, elle insère dans un tableau « tokens » un START qui va servir de repère.
- Enfin pour chaque phrase, elle sépare les mots (\S+ permet de splitter les espaces) et les ajoute dans les « tokens »
On obtient donc un tableau qui ressemble à ça:

On a donc nos tokens et nos STARTS… par la suite on demandera à une fonction de commencer par un START au hasard, ce qui fera un bon début de phrase.
Maintenant qu’on a un tableau, on peut s’amuser à regrouper les termes qui se suivent. On va alors parler de Ngrams. Ce sont justement ces regroupements de termes. Les plus connus sont les bigrams ( 2 termes )
Si on reprend notre image ci-dessus, on veut créer un autre tableau qui contiendra:
- START Quelle
- Quelle que
- que soit
- soit la
- la taille
- etc…
Le dernier mot d’une ligne de notre tableau est le premier de la ligne suivante. L’idée est de pouvoir le retrouver par la suite. Par exemple, si on cherche le terme qui suit « soit« , on va chercher soit dans le tableau et trouver la et ainsi de suite…
On en arrive donc à ce genre de chose:

On a donc un nouveau tableau composé de sous-tableaux de 2 valeurs. Alors pour les START on prend un seul terme. Pour la suite, on a de vrais bigrams (2 mots).
On peut donc commencer à générer des contenus avec ça. Si on demande « veille concurrentielle« , on sait qu’après c’est « est essentielle« . On a un truc cohérent.
Et comme en fin de phrase on ajoute un END, on peut relancer la machine par un START et regénérer d’autres phrases.
Je vous donne la fonction dans un instant… je veux revenir sur un truc avant !
Si on a dans un tableau les suites logiques d’autres mots, il y a rapidement des soucis qui se posent.
L’objectif est de générer des contenus uniques. Si ce n’est que pour copier un article, c’est naze, autant faire CTRL+C/CTRL+V et basta !
Parce que très logiquement, si vous partez d’un texte, que vous le découpez et que vous demandez derrière les suites logiques, tout ce que vous aurez en sortie, c’est votre article de départ.
Si vous entrainez votre code sur peu de contenu, c’est ce qui vous arrivera et vous aurez toujours le même article en sortie.
D’ailleurs, avant d’aller plus loin, le texte pour cette démo:

Si vous entrainez votre code sur plus de contenu en revanche, il va se passer d’autres choses… et on va se retrouvez avec notre cas vu plus haut… je fais peut être suivi par du référencement ou un gâteau.
L’image ci-dessus pour montre 2 possibilités aussi pour veille concurrentielle
Et dans un texte de plusieurs milliers de mots, vous allez commencer à récupérer plusieurs suites par terme.
C’est cool, parce qu’on veut justement des suites qui ne sont pas forcément celles du texte de départ.
En revanche, on va quand même faire gaffe à ne pas tomber sur notre gâteau pour un texte sur le SEO.
Il nous faut donc calculer des probabilités et classer un peu tout ça.
Le but étant d’obtenir ça:

Bon, pour le classement, c’est pas très parlant ici puisque j’ai en démo un contenu de moins de 200 mots.
Mis à part le START, il n’y a que « veille concurrentielle » qui a 2 possibilités de suites.
Voici ce que ça peut donner pour un START sur 36Mo de texte:

On a bien un tableau dont les probabilités de sorties sont classées du plus probable au moins probable. Dans mes 36Mo, les phrases commencent plus souvent par « Les sections » que par « Les entreprises » par exemple.
Ce qui devient sympa avec ces stats classées dans l’ordre, c’est qu’on va pouvoir choisir une suite parmis les 5 premières par exemple histoire d’avoir un truc cohérent.
Plus on va descendre dans le tableau, plus on va générer des suites bizarres… parfois poétiques tout de même.
Il n’y a que pour les START qu’on peut tirer n’importe quelle suite puisque que c’est un début de paragraphe ou phrase.
Vous commencez à voir le potentiel ?
On peut trier des probabilités des sorties logiques selon un texte d’entrainement. Et on peut affiner encore en travaillant sur des trigrams, quadrigrams, et plus.

En s’amusant a augmenter la taille des Ngrams, on augmente la cohérence des textes. Ils sont beaucoup plus lisibles. En revanche, forcément, il faut beaucoup plus de textes d’entrainement pour avoir beaucoup de possibilités cohérentes derrières. On va trouver facilement plus de suite pour « je suis » que pour « je suis derrière mon »… il faut jongler entre la lisibilité, le besoin et la qualité des données d’entrainement.
Pour faire une bouillie, on va prendre des bigrams sur peu de contenu… Pour un texte sympa, on va scraper des tas d’articles et demander des trigrams, quadri ou plus. Il faudra alors faire gaffe à ne pas pondre un article identique à celui qui se trouve dans votre fichier d’entrainement.
Vous le verrez, ce qui se passe souvent, c’est qu’un paragraphe commence comme le texte de base puis dévie au bout d’une dizaine de mots vers tout autre chose.
C’est assez amusant !
Alors le code qui fait ça… vous le voulez ?
RT bienvenus, partages etc… je fais ça rapidement, si c’est motivant 🙂
Merci pour l’article. Mais il n’est pas plus simple de demander à open ai de générer l’article + de mettre un prompt du type « Générer un article suivant le {titre} suivant avec les mots clés : {mot clé obtenus dans google : mots clé reliées ou mots clé exact -> en gros suggérer par google} » Ce qui nous donne un contexte.
Voila je commence à m’intéresser à open ai et je suis preneur de vos retours. Egalement vous écrivez en français dans le prompt ou en anglais ? (je me demande si différence de résultat).