Rechercher dans ce blog

dimanche 11 janvier 2015

Le Trameur

Bonjour !

Voici donc l'avant-dernière étape de notre projet pour ce semestre (la dernière étant la création du site web) : l'utilisation du logiciel Le Trameur. Pour cela, nous avons besoin des fichiers Contextes Globaux.

Le trameur est un outil à la croisée des statistiques et de la linguistique. Il a été développé notamment par M. Serge FLEURY (laboratoire CLA²T/SYLED). Cet outil permet le calcul des cooccurrents dans un texte donné. 

Les deux notions fondamentales du Trameur sont la trame et le cadre. La trame correspond au découpage en unités et le cadre au partitionnement du texte. Le Trameur va donc travailler sur un vecteur de positions d'unités dans le texte. On va pouvoir agréger des annotations sur chaque unité segmentée. Il n'y a aucune restriction dans le nombre d'annotations greffées sur les unités segmentées. 

Il existe deux moyens d'entrer dans le logiciel :
  • lui donner un texte que l'on a construit = création d'une nouvelle base
  • importer une base textométrique existante qui contient une trame et un cadre avec une ribambelle d'annotations (micro et macro-syntaxe, prosodie...)
La carte des sections est un outil textométrique permettant de donner une représentation graphique d'un texte sous forme de sections. Sur cette représentation, nous voyons une succession de petits carrés qui correspondent chacun à une section précise du texte. En passant la souris sur chaque carré, on voit le contenu de la section.
Dans le Trameur, tous les calculs peuvent être faits sur n'importe quel niveau d'annotation.
La carte des sections est un bon outil pour rendre compte de l'alignement (ex : traduction, etc.). 

Le résultat du calcul des cooccurrents pour un pôle est donné sous forme de réseau. La couleur de l'arc traduit le degré d'attraction entre le candidat cooccurrent et le pôle choisi. L'épaisseur de l'arc traduit le nombre de contextes communs entre le pôle et son candidat. Le label de l'arc indique la fréquence, la spécificité et le nombre de contextes.  

Voici nos résultats en images (les couleurs et les labels ne sont malheureusement pas très visibles) :

Réseau de cooccurrents pour l'anglais

Réseau de cooccurrents pour l'espagnol

Réseau de cooccurrents pour le français

Réseau de cooccurrents pour le tchèque

Et voilà, c'est terminé pour cette fois ! Il ne nous reste plus qu'à donner les dernières touches à notre site web pour que le projet soit vraiment fini...

A bientôt !

jeudi 8 janvier 2015

Nuage de mots

Bonjour !

Tout d'abord comme il s'agit du premier article de l'année 2015, nous vous souhaitons une excellente année avec beaucoup de bonnes et jolies choses !

Malheureusement, cette année commence bien mal avec l'attentat horrible qui a eu lieu hier à Charlie Hebdo, ayant fait 12 morts. Nous sommes très peinés de cette tragédie et pensons très fort aux victimes et à leurs familles... 

-------------------------------------------------------------------------------------------------

Nous attaquons la dernière partie du projet (pour ce semestre mais on continue l'aventure pour la seconde partie de l'année !) avec aujourd'hui la présentation de notre nuage de mots. 

Pour cela, nous avons utilisé Wordle, un logiciel en ligne, très simple d'utilisation. Il permet de construire des nuages de mots en supprimant les mots trop communs comme les déterminants, etc. (= mots grammaticaux).
Plus le mot est fréquent, plus sa police d'affichage est grande. La seule chose sur laquelle cet outil s'appuie est donc la fréquence des mots.

Nous avons construit un nuage de mots par langue, en ne gardant que 100 mots pour avoir de la consistance tout en conservant une bonne visibilité pour chaque mot qui doit rester distinct de tous les autres. Pour les nuages,  nous avons utilisé les fichiers DUMP globaux. Voici en images ce que cela donne :

Nuage de mots pour l'anglais

Nuage de mots pour l'espagnol
Nuage de mots pour le français
Nuage de mots pour le tchèque


A bientôt !

mercredi 31 décembre 2014

Tableau HTML final

Bonjour ! 

Et voici déjà le dernier article de l'année 2014 (pas du blog ;)) !

Nous venons vous présenter notre tableau HTML composé de toutes ses colonnes (il reste cependant des choses à faire, comme la création du nuage de mots ou l'utilisation de l'outil Le Trameur...). 

Nous avons donc ajouté à notre tableau deux colonnes supplémentaires : une pour les fréquences sur un motif recherché parmi toutes nos URLs et l'autre pour les index (état quantitatif de l'ensemble des mots pour chaque URL, c'est un résultat statistique).
Les expressions régulières nous permettent de conserver la généricité du programme tout en pouvant rechercher plusieurs motifs qui nous intéressent. 
Le fichier motif est lui aussi encodé en UTF-8. Il ne comporte qu'une seule ligne : MOTIF = regexp. 

Nous avons également ajouté deux lignes en plus tout en bas du tableau car nous avons fait la concaténation des fichiers DUMP et des fichiers CONTEXTES. Nous avons donc un fichier DUMP global, un fichier CONTEXTES global ainsi que deux index correspondants. Nous aurons besoin de ces fichiers globaux pour Le Trameur. Cependant, nous avons tout de même gardé la trace, dans ces fichiers globaux, des différentes parties le constituant. 

Passons à présent aux résultats (le programme est désormais trop long pour être montré ici) :

Tableau final tchèque

Tchèque : contexte HTML

Tchèque : contexte UTF-8

Tableau final anglais

Anglais : contexte HTML

Anglais : contexte UTF-8

Dump et contextes globaux anglais

Espagnol : contexte HTML

Tableau final espagnol

Espagnol : contexte UTF-8

Tableau final français

Français : contexte HTML

Français : contexte UTF-8

A l'année prochaine pour d'autres articles ! ;)

samedi 6 décembre 2014

Tableau à 6 colonnes

Bonjour ! 

La dernière fois nous avons traité le cas des fichiers encodés en utf-8 mais qu'en est-il des fichiers qui sont encodés différemment
Pour répondre à cette question, nous allons d'abord utiliser iconv. Pour que cette solution fonctionne, il faut que la valeur de l'encodage de la page aspirée soit compatible avec les encodages connus d'iconv. Si la valeur est connue d'iconv, on fera un dump puis la conversion (transformer en utf-8). 
En revanche, si la valeur n'est pas connue, on aura un nouveau problème que l'on essaiera de résoudre en allant chercher le charset.

Il existe 2 options très utiles pour la commande iconv : -f et -t qui spécifient respectivement l'encodage de départ et l'encodage d'arrivée. Il est nécessaire de rediriger le résultat de la commande dans un fichier car iconv affiche à l'écran par défaut. 

Que faire si la valeur d'encodage n'est pas connue d'iconv ? 

Si la valeur n'est pas connue d'iconv, nous devons extraire le charset des pages aspirées. Pour cela, nous avons la commande egrep qui est une commande de filtrage de lignes dans un fichier. Son intérêt est de pouvoir travailler avec des expressions régulières. 
Syntaxe : egrep motif fichier
egrep prend 2 arguments : un motif de recherche et un fichier dans lequel on effectue cette recherche. Le motif peut s'exprimer sous la forme d'une expression régulière. Attention à la casse, si le motif recherché par egrep est connu d'iconv, cette valeur est affichée à l'écran. 
Quelques options d'egrep :
  • -c : compte le nombre de lignes qui contiennent le motif recherché
  • -v : affiche les lignes qui ne contiennent pas le motif
  • -vc : compte le nombre de lignes du fichier qui ne contiennent pas le motif
  • -n : affiche les lignes, précédées de leur numéro
  • -i : on cherche le motif en ne tenant pas compte de la casse
  • -o : affiche les chaînes de caractères reconnues par le motif
  • -uniq : filtre les doublons mais en les comptant
Voici donc où nous en sommes dans le programme et dans le tableau HTML (cliquez sur les images pour les agrandir) :

Programme partie 1
Programme partie 2
Programme partie 3
Programme partie 4
Programme partie 5
Tableau HTML Tchèque

Tableau HTML Anglais

Tableau HTML Espagnol (erreur)

Tableau HTML Espagnol

Tableau HTML Français

Dans les captures d'écran, vous pouvez voir que nous rencontrons essentiellement deux types d'erreurs : soit l'accès à une page est interdite (403 Forbidden), soit la page a été déplacée (307 Moved Permanently). Mais ce que l'on ne voit pas ici, c'est que nous avons aussi quelques soucis avec l'expression régulière utilisée dans notre programme pour extraire le charset car elle ne fonctionne pas sur toutes les pages aspirées (sans doute n'est-elle pas assez générale ?). Il nous faut également revoir l'aspiration de certaines pages car elle ne s'est pas toujours effectuée correctement (souci avec la commande curl). Nous allons essayer de faire quelques petits réglages dans les semaines qui viennent. 

A bientôt pour la suite !

mercredi 19 novembre 2014

Petit rappel sur les expressions régulières

Bonjour !

Avant de poursuivre la construction de notre tableau HTML dans le cadre du projet, voici un petit rappel sur ce que sont les expressions régulières et leur fonctionnement. En effet, il est essentiel de bien comprendre les expressions régulières dans le cadre de notre cursus et surtout pour plus tard, car nous en aurons besoin dans n'importe quel domaine du TAL.

Les expressions régulières permettent de chercher toutes les chaînes de caractères correspondant à un motif donné selon une syntaxe précise.

Il existe différents opérateurs tels :

Les opérateurs d'ensembles de caractères

  • [aeiouy] : ici, on demande à retrouver un caractère de cet ensemble, c'est-à-dire une voyelle.
  • [A-Z] : le tiret permet de décrire un intervalle de caractères (les caractères compris entre A et Z). Le tiret n'est pas reconnu comme un élément de cet ensemble.
  • [^A-Z] : le circonflexe permet de dire que l'on ne veut pas d'élément de cet ensemble (négation), a serait reconnu car ce caractère est en minuscule mais A en majuscule ne le serait pas. 
  • | : le pipe permet l'alternative, par exemple : clé | clef, on veut reconnaître les chaînes de caractères clé ou clef, mais pas é ou c car la concaténation est prioritaire sur l'optionnalité.
Les opérateurs de répétition 

  • ? : le point d'interrogation permet de dire que le caractère qui précède est soit présent soit absent. Par exemple, arbres? : on cherche soit arbre (au singulier) soit arbres (au pluriel). Autre exemple, abc(dy)? : cette fois, le ? concerne toute la parenthèse car cette dernière permet de regrouper des caractères. 
  • * : présence 0 fois ou autant que l'on veut du caractère qui précède. Exemple, lo*ng qui nous permet de trouver long, long, loong, looong, etc. 
  • + : 1 occurrence ou plusieurs du caractère qui précède. Exemple, lo+ng ce qui donne long, loong, looong mais pas lng. 
Les quantificateurs

  • {} : les accolades permettent de spécifier de manière plus précise le nombre des caractères recherchés. Exemple, arbre{1,3} : le e apparait au minimum 1 fois et au maximum 3 fois. Autre exemple, arbre{4,} : le e apparaît 4 fois minimum mais on n'a pas de borne supérieure. 
  • . : le point remplace n'importe quel caractère (sauf le retour à la ligne).
  • ^ : le circonflexe a une autre signification que précédemment, ici il désigne un caractère en début de chaîne.
  • $ : c'est l'inverse, soit un caractère en fin de chaîne. 
  • Pour chercher les lignes vides, on aura donc : ^$ (mais on n'aura rien en sortie).
  • \w : représente des caractères de mots.
  • \w+ : pour trouver tous les mots de l'anglais par exemple. Le français comporte des caractères accentués. Si on est dans un environnement en utf-8, cette regexp fonctionne aussi pour le français. Ce n'est pas forcément le cas dans tous les environnements. 
  • \b : frontière de mot. Par exemple, ing\b : recherche tous les mots se terminant par ing. 
  • \W : on recherche quelque chose qui n'est pas un caractère de mot.
  • \B : on recherche quelque chose qui n'est pas à la frontière d'un mot (donc à l'intérieur). 
Parenthésage et niveau de priorité (dans l'ordre du plus prioritaire au moins prioritaire)

fermeture > concaténation > union
Les parenthèses permettent de savoir comment sont regroupés les éléments de l'expression. 

Remarque : l'antislash va permettre de rendre leur statut de caractère aux opérateurs afin qu'ils soient traités comme des caractères normaux. 

Ces quelques éléments très utiles pour comprendre les expressions régulières ont été présentés en cours, mais ils ne représentent qu'une petite partie des opérateurs disponibles. Il n'est bien sûr pas possible d'en dresser la liste exhaustive ici mais nous les découvrirons au fur et à mesure de l'avancée du projet ainsi que dans les différents domaines de notre cursus.

A bientôt pour la suite du projet !





lundi 17 novembre 2014

Tableau HTML à 4 colonnes

Bonjour ! 

Aujourd'hui nous allons tout d'abord modifier le code écrit la semaine dernière car on y duplique les traitements sur tous les blocs d'URLs, ce qui n'est pas raisonnable d'un point de vue informatique. 
Ce que l'on attend, c'est que pour chacun des fichiers URL, on lance un et un seul traitement qui fonctionnera sur chaque ligne du fichier x.

On doit mettre en place un mécanisme qui prend en compte chacun des fichiers d'URLs qu'il va lire ligne par ligne. C'est donc deux boucles for imbriquées qui nous seront utiles ici.

Pseudo-code : pour chacun des fichiers (x)
                              pour chacune des lignes du fichier x
                              ...
Le script doit être modifié pour que le programme ne travaille plus sur des noms précis de fichier mais sur un ensemble de fichiers.

Attention toujours à la localisation dans l'arborescence, il faut savoir où l'on se trouve pour éviter les erreurs de "fichier introuvable" dans un programme.

On va donner au programme le chemin vers le répertoire qui contient les fichiers d'URLs et le chemin vers le fichier de sortie dans le fichier paramètres. 

Les deux boucles imbriquées se présentent ainsi dans le code, puisque pour chacun des fichiers on souhaite créer un tableau qui s'affichera sur la page HTML :
Pseudo-code : pour chacun (x) des fichiers du dossier URLS
                             x déclarer le début du tableau HTML (x)
                                 pour chacune des lignes du fichier x
                                       code écrit précédemment

Ensuite, on déplace les compteurs qui sont désormais mal situés. 
Le compteur de langue doit être incrémenté juste avant de commencer un nouveau tableau.
Le compteur de lignes : le bon endroit pour définir ce compteur est juste avant la deuxième boucle for, c'est-à-dire celle qui nous sert à lire chaque ligne d'un fichier x. 

Attention, cette étape est très importante car la fois prochaine le code aura triplé (voire quadruplé) au niveau du nombre de lignes. 

A présent, nous allons ajouter une nouvelle colonne au tableau : la colonne DUMP qui récupérera le contenu textuel des URLs, avec comme contrainte que l'encodage soit en utf-8. 
Ce qu'il faut faire concrètement :
Pseudo-code : si (URLi) est encodée en UTF-8
                              aucun problème
                       sinon
                              récupérer (URLi)
                              transcoder en UTF-8

La commande file est capable de détecter, pour un fichier dans l'arborescence, l'encodage de celui-ci par rapport aux caractères utilisés ; elle ne lit pas le charset. Le souci, c'est qu'elle ne fonctionne pas toujours bien, dans ce cas, il faudra aller directement chercher le charset. 

Comment ne récupérer que la valeur de l'encodage ?
On introduit une autre nouvelle commande : cut. Cette commande nous permet de travailler sur des fichiers généralement structurés en colonnes. On peut n'afficher que certaines colonnes spécifiques. Cut est une commande très sophistiquée qui considère par défaut que le délimiteur est la tabulation mais on peut lui donner un autre délimiteur, par exemple "=, ce qui va nous intéresser ici pour récupérer la valeur de l'encodage (pas d'ambiguité possible car il n'y a qu'un seul "=" dans la chaîne de caractères de l'encodage). 
On peut mémoriser le résultat de cette commande dans une variable pour ensuite par exemple l'afficher à l'écran grâce à la commande echo. 

Pour ajouter la colonne DUMP à notre tableau, nous allons nous servir de la commande lynx (ancêtre de Firefox). Lynx prend comme argument une URL, c'est un navigateur en ligne de commandes. On peut surfer mais de manière rustique. 
L'option -dump va permettre, associée à la commande lynx, de récupérer le contenu textuel de la page sur laquelle on travaille. 
L'option -nolist élimine les liens.
L'option -display_charset va permettre de spécifier l'encodage du fichier de sortie en conservant l'encodage du fichier initial. Attention cependant aux problèmes d'aspiration

On va essayer de modifier le programme pour ne mettre en place le traitement que sur des fichiers codés en utf-8. Pour le moment, on met en place une boucle de ce type :
if condition
   then ...
   else ...
Syntaxe en bash : if [[encodage=="utf-8" ]]

Dans la boucle, on n'exclut aucune URL mais pour celles en utf-8, le contenu textuel est récupéré alors que pour les autres, il n'y a que de l'affichage.

Voyons maintenant ce que tout cela donne en images (cliquez dessus pour les agrandir) :

Le nouveau fichier paramètres

Le début du script

La fin du script

Le début du tableau des URLs en tchèque

Le début du tableau des URLs en anglais

Le début du tableau des URLs en espagnol

Le début du tableau des URLs en français

Tout irait bien s'il n'y avait pas ces erreurs avec la commande curl...





Que faire pour éviter cela ? Nous allons y réfléchir et essayer de trouver une solution que nous vous donnerons sur ce blog...

A très vite pour la suite !

mardi 11 novembre 2014

Tableau HTML à 3 colonnes

Bonjour !

Aujourd'hui, nous allons ajouter 2 colonnes au tableau d'URLs que nous avons commencé à construire précédemment : une colonne pour numéroter les liens et une autre pour les pages aspirées correspondant à ces liens.

Concernant le code du script, nous nous sommes posés la question de savoir s'il était préférable d'utiliser for ou while pour la boucle. For permet de construire une "pseudo liste", ce qui implique une conservation en mémoire mais cette boucle est très simple à comprendre. While est plus efficace sur de gros programmes qui comportent des milliers de lignes, cependant cette boucle est moins intuitive. Ici, nous avons privilégié l'usage du for.  

A partir de maintenant, nous n'allons plus demander à l'utilisateur les chemins d'accès aux fichiers d'URLs et au fichier du tableau (surtout que nous devons prendre en compte les fichiers de liens pour chaque langue) mais nous allons créer un seul fichier de paramètres regroupant les paramètres d'entrée et les paramètres de sortie. Pour l'exécution du script, nous n'aurons plus qu'à appeler le programme et y associer le fichier en paramètres de la manière suivante :
appel du script < nom_fichier_paramètres
Puis on supprime les deux commandes "echo" du fichier de départ qui sont désormais inutiles. 
Dans le fichier paramètres, les chemins des fichiers d'URLs doivent être listés les uns sous les autres, le script lira les informations dans cet ordre. De plus, dans le fichier HTML de sortie, il vaut mieux faire apparaître un tableau par langue car nous aurons à effectuer des traitements séparés pour chaque fichier de liens. 

On veut faire en sorte que chaque URL pointe vers sa véritable adresse, c'est-à-dire qu'en cliquant dessus dans le fichier HTML, on soit redirigé vers le contenu de la page en question. 

Nous voulons rajouter à notre tableau une colonne qui numérote les URLs. Pour cela, il suffit d'utiliser la balise HTML :
<a href = "url vers laquelle on veut aller"> ce que l'on voit dans le navigateur </a>

Ensuite, pour numéroter les URLs : on introduit un compteur qui prend une valeur de départ et qui est incrémenté à chaque fois que l'on passe à une nouvelle URL. Attention à bien distinguer les compteurs, par exemple pour chaque fichier de langue, sinon nous n'aurons qu'un seul tableau (correspondant au dernier fichier d'URLs) dans la page HTML. 

Enfin, nous ajoutons une 3ème colonne au tableau. Elle va récupérer les pages aspirées, autrement dit, on met en place un mécanisme pour sauvegarder localement le contenu des pages Web. Pour ce faire, on utilise les commandes wget et curl. La syntaxe minimale est celle-ci : 
wget http://lien.com
wget n'écrase pas un fichier déjà existant bien que cette commande sauvegarde dans un fichier portant le même nom que le fichier d'origine. 

Dans notre script, nous avons utilisé la commande curl car wget n'est pas installée par défaut sous MacOS. 
curl transfère une URL (elle télécharge et sauvegarde le contenu de cette URL) et renvoie le fichier directement à l'écran donc il est nécessaire de faire une redirection. Par exemple : 
curl www.sncf.com>SNCF.html

Attention, pour que le shell comprenne les URLs, il faut les mettre entre guillemets (surtout lorsque l'on a des caractères spéciaux, signes de ponctuation, etc.). 
Les commandes wget et curl doivent positionner le fichier des pages aspirées dans le sous-dossier correspondant. 
Il vaut mieux privilégier les chemins relatifs aux chemins absolus car les chemins relatifs vont toujours être les mêmes quelque soit le système d'exploitation alors que les chemins absolus seront différents. 

Passons aux images (cliquez dessus pour les agrandir) :

Script Partie 1

Script Partie 2
Fichier Paramètres
Début du tableau URLs Anglais

Début du tableau URLs Espagnol

Début du tableau URLs Français

Début du tableau URLs Tchèque
C'est tout pour aujourd'hui !

A bientôt !