URL: https://linuxfr.org/news/compter-automatiquement-les-mots-prononces-sur-les-chaines-d-information-continue Title: Compter automatiquement les mots prononcés sur les chaînes d'information continue Authors: magsoft Benoît Sibaud, Xavier Teyssier, Pierre Jarillon et palm123 Date: 2021-12-30T11:08:23+01:00 License: CC By-SA Tags: Score: 5 Cette dépêche, [issue d'un journal](https://linuxfr.org/users/magsoft/journaux/compter-automatiquement-les-mots-prononces-sur-les-chaines-d-information-continue), traite d'un système d’acquisition, de reconnaissance vocale et une base de donnée des mots prononcés sur les chaînes d’information continue de la Télévision Numérique Terrestre française (TNT). Je présente aussi des résultats obtenus sur quelques candidats à l'élection présidentielle française et quelques thèmes d'actualité. Le code est disponible [ici](https://github.com/magwyz/mediaLexicometer/) sous licence AGPL. ---- [Journal à l’origine de la dépêche](https://linuxfr.org/users/magsoft/journaux/compter-automatiquement-les-mots-prononces-sur-les-chaines-d-information-continue) ---- Introduction ============ Ces dernières années en France, le traitement de l’information par les médias grand public a fait l’objet de virulents débats, notamment durant la crise des gilets jaunes. Il est souvent reproché aux médias d’être inféodés aux élites politiques ou économiques et de pousser leur propre agenda. En conséquence, une partie des citoyens se sont détournés de ces médias au profit des réseaux sociaux ou bien de médias alternatifs. Cependant, les chaînes d’information continue restent une des sources principales d’information d’une partie des français et la concurrence est rude entre elles. Cela les amène parfois à faire de la surenchère sur des sujets clivants pour générer du buzz et grignoter des parts de marché. Nous sommes actuellement en France en période de campagne pour l’élection du président de la république. C’est un moment d’effervescence médiatique car il s’agit, dans les institutions actuelles, de l’élection reine qui risque de donner la ligne politique des cinq prochaines années. J’ai pensé que cette période était une bonne occasion pour mener une petite expérience. Il s’agit de compter durant une période de 17 jours (du 6 décembre 2021 au 22 décembre 2021) automatiquement tous les mots et noms prononcés. L’objectif est de regarder si on peut distinguer des tendances sur leur traitement de l'information. Le système ========== ![Schéma global du système](http://magsoft.dinauz.org/images/mediaLexicometerImages/system.png) Capturer les chaînes -------------------- Pour pouvoir compter automatiquement les mots sur des chaînes de télévision, il faut déjà avoir un moyen d’acquérir le signal diffusé par ces chaînes. Celles qui nous intéressent sont disponibles sur la TNT (Télévision Numérique Terrestre) française. Elles sont sans doute aussi disponibles en streaming depuis leur site Web ou bien sur le réseau de mon FAI mais j’ai pensé que c’était potentiellement plus rigolo et fiable de passer par le signal hertzien. La TNT en France utilise la norme DVB-T (norme Digital Video Broadcasting version terrestre). Les chaînes sont diffusées sous format numérique à l’intérieur de multiplexes. Chaque multiplex est diffusé sur sa propre fréquence. Lorsque l’on souhaite regarder une chaîne, le tuner DVB-T se régle sur la fréquence du multiplex et commence à recevoir toutes ses données. Ces dernières sont ensuite démultiplexées pour sélectionner le ou les chaînes qui nous intéressent. Les flux vidéos sont encodés au format MPEG-4 AVC (H.264) tandis que les flux audios sont encodés en Dolby E-AC-3. Pour les chaînes qui nous concernent, CNEWS et BFM TV sont diffusées sur le même multiplex tandis que Franceinfo et LCI sont diffusées chacune sur un autre multiplexeba. Pour analyser ces quatre chaînes, nous avons donc besoin de 3 tuners DVB-T. Chose intéressante pour nous, il existe dans le commerce des cartes PCI express DVB-T 4 tuners. Ces cartes sont généralement bien supportées sous Linux par l’intermédiaire de [l’API Video for Linux (V4L)](https://linuxtv.org/) car elles ont beaucoup d’utilisations professionnelles. J’ai donc opté pour une Hauppauge WinTV-quadHD. Sans trop me poser de questions, j’ai installé son driver propriétaire ainsi qu’un firmware pour que ça tombe en marche. Pour contrôler les tuners de la carte DVB-T, j’ai choisi d’utiliser le programme dvbv5-zap du projet V4L. Son rôle est simple, par l’intermédiaire de l’API V4L du noyau, il va commander à chaque tuner de se régler sur une fréquence donnée, capturer tout le multiplex et le transmettre à FFMPEG par l’intermédiaire d’un pipe nommé (FIFO). FFMPEG va ensuite démultiplexer les données du multiplex empaquetées au format MPEG-TS pour sélectionner juste les pistes audio des chaînes qui nous intéressent. Il va aussi décompresser ces pistes audio et les transmettre dans un format PCM brut au module de reconnaissance vocale. Reconnaissance vocale --------------------- L’idée est ici de convertir nos données audio en mots pour pouvoir les stocker et les rechercher facilement dans une base de donnée. J’ai dans un premier temps testé le projet [DeepSpeech](https://github.com/mozilla/DeepSpeech) de Mozilla. Cette solution repose sur un réseau de neurone profond décrit dans le papier [DeepSpeech](https://arxiv.org/abs/1412.5567) de Baidu. Il est possible de trouver [un modèle entraîné pour reconnaître du Français](https://discourse.mozilla.org/t/modele-francais-0-6-pour-deepspeech-v0-7-v0-8-v0-9/71993). Cependant les performances sur mes flux audio de chaînes de télévision ne se sont pas révélées qualitativement satisfaisantes. J’ai donc testé dans un second temps le projet [Vosk](https://github.com/alphacep/vosk-api). Vosk repose sur le réseau de neurones nnet3 de [Kaldi](https://github.com/kaldi-asr/kaldi). Le projet Vosk distribue [un modèle assez récent](https://alphacephei.com/nsh/2020/10/21/french.html) (octobre 2020) pour le français adapté du projet français [LinTO](https://linto.ai/fr/) qui est distribué sous licence AGPL. À noter que LinTO est un projet issu du « Programme d’investissements d’avenir », donc financé (en partie ?) par des fonds de l’état français. Il est piloté par la société Linagora. Les résultats du modèle Vosk LinTO se sont révélés être de bien meilleure qualité. Le modèle est même assez fort pour reconnaître des noms propre de personnalités (ce que l'on va bien utiliser par la suite) et les ressortir avec la bonne orthographe. Je n’ai pas cherché mais je suppose qu’il a été au moins en partie entraîné avec des données d’actualités. Mais ces données d’entraînement ne doivent pas non plus être très récentes car il ne reconnaît pas du tout le mot "covid"... Lemmatisation ------------- La lemmatisation consiste à trouver pour un mot sa forme lexicale racine. Elle enlève toute conjugaison à un verbe ou bien les accords pour un adjectif. Par exemple le lemme de `jolis`, `jolies`, `jolie` ou `joli` sera `joli`. La lemmatisation est souvent utilisée en analyse de texte car elle permet de regrouper ensemble des mots qui ont le mêmes sens. Pour notre système, on pourra ainsi compter l’utilisation d’adjectifs ou de verbes sans se soucier de leurs accords ou conjugaisons. La bibliothèque [Spacy](https://spacy.io/) accompagnée d’[un modèle pour le français](https://github.com/explosion/spacy-models/releases/tag/fr_core_news_sm-3.1.0) permet de facilement faire cette opération. Les noms propres ne seront bien sûr pas lemmatiser. Stockage en base de donnée -------------------------- J’ai choisi d’utiliser le framework Python de développement Web Django comme ORM simplement parce-que c’est le seul que je connaisse. Derrière, j’ai connecté une base de donnée PostgreSQL. La structure de la base de donnée est très simple. Une table principale « Words » stocke pour chaque entrée le mot, son lemme, sa date et heure de prononciation ainsi que la chaîne de télévision sur laquelle il a été prononcé. Je me suis posé la question de savoir si un moteur de recherche comme Elasticsearch n’était pas plus adapté pour ce genre de tâches mais comme je ne connais pas bien... meh... flemme de chercher plus... Peut-être avez-vous une idée sur la question ? Requêtage --------- La recherche se fait ensuite par l’intermédiaire d’une page Web aussi servie par Django. Vous noterez le soin mis dans le design de la page... ![Interface de requêtage](http://magsoft.dinauz.org/images/mediaLexicometerImages/bonjour.png) L’interrogation de la base de donnée se fait aussi avec l’ORM de Django. La subtilité est que pour chercher des groupes de mots avec mon YOLO design de base de donnée, il faut faire des sous-requêtes par mots - chercher les mots X qui sont suivis juste après par le mot Y qui sont suivis juste après par le mot Z - avant d’agréger à la fin sous forme de comptes par dates et chaînes. Cependant, avec les bons indexes dans la base, ça fonctionne pour le moment avec des temps de réponse acceptables. Meh... On va dire que ça ira... Comme résultats, la page affiche des graphes générés avec la bibliothèque [Matplotlib](https://matplotlib.org/). Le code ------- Le code est disponible sur Github sous licence AGPL [ici](https://github.com/magwyz/mediaLexicometer/). Je m’excuse pour la faible quantité de documentation. Mais, comme ce projet repose sur pleins de superbes briques libres, il y a au final assez peu de code. Comment ça tourne ? ------------------- Ce bazar a tourné étonnamment sans trop de problèmes pendant 68 jours avec un load de 1.5 sur une station de travail Dell T3600 équipée d’un Xéon E5-1620 à 3.60GHz et de 32 Go de RAM qui tourne sous Ubuntu server 20.04. J’ai récupéré cette machine grâce à un célèbre site de vente d’occasions entre particuliers. Mais, comme je n'avais pas bien testé (bah oui YOLO programming...), je me suis rendu compte au moment de publier la première version de ce journal qu'il y avait un gros bug dans l'enregistrement de la date et l'heure des mots. Cela rendait les graphes générés faux même si les comptes totaux étaient justes. J'ai donc relancé une expérience d'acquisition. Cette dernière s'est interrompue toute seule un matin au bout de 17 jours par une série de messages se terminant par: ```EXT4-fs (sda2): I/O error while writing superblock``` J'imagine qu'il est possible de traduire ça en français par: ```Cher père Noël, pourrais-tu s'il te plaît me déposer une nouveau SSD sous le sapin ?``` Les données de la base semblant encore être lisibles (pour le moment), cela m'a permis tout de même de générer les graphes suivants. Les résultats sur quelques candidats à la présidentielle ======================================================== Le Conseil Supérieur de l'Audiovisuel (CSA) produit des [rapports](https://www.csa.fr/csapluralisme/tableau) sur les temps de parole de chaque intervenant politique. Cependant, ils ne semblent pas s'intéresser aux nombres de fois qu'ils sont mentionnés. Comme je l’évoquais plus haut, le modèle de reconnaissance est qualitativement performant même sur les noms propres. On peut donc tenter de compter le nombre de fois que les candidats à l’élection présidentielle sont mentionnés. **Je tiens tout de même à préciser ici que les résultats suivants ne sont que des estimations. Le modèle reconnaissance vocale n’est pas parfait. Les comptes reportés ne sont donc certainement pas exacts.** Vosk fourni [des chiffres d’évaluation du modèle](https://alphacephei.com/nsh/2020/10/21/french.html) mais je n’ai pas réalisé d’évaluation sur mes données. Cependant, pour ma défense, je dirais qu’il n’y a à priori pas non plus de raison que le modèle fonctionne plus mal sur une chaîne que sur une autre. Je pense donc que l’on peut assez sereinement faire des comparaisons de chiffres entre chaînes. Je vous propose donc de nous intéresser à 4 chaînes d'information continue de la TNT: - BFM TV chaîne privée du groupe Altice Média, - CNEWS chaîne privée du groupe Canal+, - France Info chaîne publique du groupe France Télévisions, - LCI chaîne privée du groupe TF1. Voici les résultats sur quelques candidats à l’élection présidentielle par ordre alphabétique. Ces chiffres sont ensuite repris dans un tableau récapitulatif. **Arthaud** ![Arthaud](http://magsoft.dinauz.org/images/mediaLexicometerImages/arthaud.png) **Hidalgo** ![Hidalgo](http://magsoft.dinauz.org/images/mediaLexicometerImages/hidalgo.png) **Jadot** ![Jadot](http://magsoft.dinauz.org/images/mediaLexicometerImages/jadot.png) **Le Pen** ![Le Pen](http://magsoft.dinauz.org/images/mediaLexicometerImages/le_pen.png) **Macron** ![Macron](http://magsoft.dinauz.org/images/mediaLexicometerImages/macron.png) **Mélenchon** ![Mélenchon](http://magsoft.dinauz.org/images/mediaLexicometerImages/melenchon.png) **Montebourg** ![Montebourg](http://magsoft.dinauz.org/images/mediaLexicometerImages/montebourg.png) **Pécresse** ![Pécresse](http://magsoft.dinauz.org/images/mediaLexicometerImages/pecresse.png) **Poutou** ![Poutou](http://magsoft.dinauz.org/images/mediaLexicometerImages/poutou.png) **Roussel** ![Roussel](http://magsoft.dinauz.org/images/mediaLexicometerImages/roussel.png) **Zemmour** ![Zemmour](http://magsoft.dinauz.org/images/mediaLexicometerImages/zemmour.png) **Récapitulatif** On peut aussi mettre tous ces chiffres dans un tableau pour tenter d’avoir une vision plus globale. | | Orientation | BFMTV | CNEWS | franceinfo | LCI | Total | | ---------- | ----------- | ------ | ----- | ---------- | --------- | ----- | | Macron | CD | 3408 | 3737 | 3144 | **6296** | 16585 | | Zemmour | D | 2952 | 4724 | 2229 | **4826** | 14731 | | Pécresse | D | 2249 | 2514 | 1763 | **4794** | 11320 | | Le Pen | D | 832 | 1127 | 746 | **1659** | 4364 | | Hidalgo | G | 972 | 754 | 942 | **1231** | 3899 | | Mélenchon | G | 894 | 701 | 811 | **1084** | 3490 | | Jadot | G | 686 | 204 | 544 | **898** | 2332 | | Montebourg | G | 382 | 269 | 255 | **293** | 1199 | | Roussel | G | 104 | 76 | **190** | 97 | 467 | | Poutou | G | **74** | 14 | 10 | 30 | 128 | | Arthaud | G | 4 | 8 | 7 | **14** | 33 | | Total | | 12557 | 14128 | 10641 | **21222** | 58548 | La première chose que semble nous indiquer ce tableau, est que LCI accorde plus d’importance que les autres chaînes aux candidats de l’élection présidentielle. À l’opposé, c’est France Info qui semble le moins en parler. Ensuite, si l’on fait des groupes de candidats (gauche, centre droit et droite), et que l'on fait les comptes par groupe, on obtient le résultat suivant: | Gauche | Centre droit | Droite | | ------ | ------------ | ------ | | 11548 | 16585 | 30415 | Même si l'on inclut pas le président en exercice, la balance semble pencher amplement du côté droit. Ce déséquilibre était aussi visible au travers des résultats de ma première expérience de 68 jours sur une période précédente ; celle à moitié plantée par mon bug. Les résultats sur quelques thèmes d'actualité ============================================= Il est aussi de possible de tester des thèmes de d'actualité. Voici quelques exemples que j'ai jugé indicatifs: ![Nucléaire](http://magsoft.dinauz.org/images/mediaLexicometerImages/nucleaire.png) ![Immigration](http://magsoft.dinauz.org/images/mediaLexicometerImages/immigration.png) ![Islam](http://magsoft.dinauz.org/images/mediaLexicometerImages/islam.png) ![Ukraine](http://magsoft.dinauz.org/images/mediaLexicometerImages/ukraine.png) Et la suite ? ============= Pour la continuer cette étude, il pourrait être intéressant de s'intéresser aux cooccurrences de termes. Par exemple, combien de fois sur une chaîne le mot `immigration` est prononcé proche du mot `sécurité`. Le système pourrait aussi être étendu à d’autres chaînes de télévision et de radio, et pourquoi pas même aux sites Web d’information. Il devrait aussi être possible de rendre accessible à tous l’interface de recherche pour que chacun puisse faire ses analyses. Et vous, qu’est-ce que cela vous inspire ? P.S. : Si vous souhaitez que je teste une requête sur une personnalité, un mot ou une expression particulière, je pourrai mettre le résultat dans les commentaires si mon SSD veut bien encore un peu coopérer... # Divers NdM: quelques commentaires sous sur le journal résumés ici : - les candidats déclarés le sont en attendant l'[officialisation](https://fr.wikipedia.org/wiki/Pr%C3%A9sentation_des_candidats_%C3%A0_l'%C3%A9lection_pr%C3%A9sidentielle_fran%C3%A7aise) et les 500 signatures de parrainages requises - une suggestion : _classer les occurrences par heure, pour voir ceux qui trichent en accordant plus de temps à certaines personnes en pleine journée, et à d'autres à 3h du mat'_ ([exemple](https://www.csa.fr/Reguler/Espace-juridique/Les-textes-adoptes-par-le-CSA/Les-decisions-du-CSA/Respect-des-regles-du-pluralisme-politique-intervention-aupres-de-CNews)) - taille de la base de données PostgreSQL : ~11 Go pour 17 jours, soit ~30 Mo / heure pour les 4 chaînes (`SELECT pg_size_pretty( pg_database_size('lexicometer_db') );`) - une autre suggestion : utiliser aussi le sous-titrage, [lorsque disponible](https://www.csa.fr/Proteger/Garantie-des-droits-et-libertes/Les-droits-des-personnes-handicapees/Le-sous-titrage) - une troisième suggestion : ajouter le canal R4 pour France2 + France5 + Arte - le choix d'AGPL vient du fait du [modèle de reconnaissance vocale pour le français de Vosk](https://alphacephei.com/nsh/2020/10/21/french.html) ...