UIMA FR
Communauté francophone autour d'UIMA
  • Accueil
  • Top 10
  • Statistiques
  • Inscription
  • Archives
  • Contact

Informations

BilboPlanet - An Open Source RSS feed aggregator written in PHP.
 

Abonnement

  • feed  Fil de tous les articles
  • feed  Fil des articles populaires

Membres

  • feed Fabien POULARD
  • feed Jérôme Rocheteau
  • feed Laurent Audibert
  • feed Matthieu Vernier
  • feed Nicolas Hernandez
  • feed Nicolas Hernandez

Participer

  • meta  Ajouter votre blog
  • meta  Administration

 

Filtrer les articles :     Articles du jour   -   Articles de la semaine   -   Articles du mois   -   Tous les articles

Accès rapide aux derniers articles de la page

  • 21/02/2010 : UIMA & Wikipédia (5) : Gestion du projet avec Maven
  • 14/02/2010 : UIMA & Wikipédia (4) : Analyse de la syntaxe MediaWiki
  • 12/02/2010 : UIMA & Wikipédia (3) : Filtrage des données à charger
  • 02/02/2010 : UIMA & Wikipédia (2) : Chargement d'un dump Wikipedia
  • 01/02/2010 : UIMA & Wikipédia (1) : Proposition de Type System
  • 29/01/2010 : Sortie d'Apache UIMA 2.3
  • 09/11/2009 : Construction de la communauté UIMA-Fr
  • 30/09/2009 : UIMA : Comment utiliser un type dont un attribut est un tableau de types ?
  • 23/09/2009 : Compilation de ressources autour d'Apache UIMA
  • 23/09/2009 : Nettoyage et améliorations du cpeGui
« Page précédente Page suivante »
 

UIMA & Wikipédia (5) : Gestion du projet avec Maven

0 vote
Par Fabien POULARD le 21/02/2010 à 17:56 Voir l'article

La création de composants UIMA permettant d'accéder et tirer parti de Wikipédia offrirait de nouvelles perspectives au traitement des langues en offrant un accès aisé à cette formidable ressource que représente l'encyclopédie libre. Je compte m'atteler à la création de tels composants et vais tâcher de publier plusieurs billets décrivant ma démarche en cours.

Voici le cinquième billet, plus orienté technique de développement, qui discute de la gestion du projet avec Maven, permettant notamment de gérer automatiquement les dépendances à MWDumper et à Wikimodel.

Qu'est-ce que Maven ?

Maven est une sorte de super-gestionnaire de projet qui peut se charger d'à peu près tout : dépendances, compilation, packaging, lancement des tests unitaires, ... L'outil est disponible sur la plupart des distribution, pour ma part sous Ubuntu :

$ sudo aptitude install maven2

L'objectif de ce billet est d'expliquer comment, à l'aide de notre génial ingénieur de recherche, j'ai pu utilisé maven pour gérer la construction du collection reader pour Wikipedia.

Récupérer les dépendances

La première complication lorsque l'on souhaite compiler le collection reader ce sont les dépendances, il y en a trois :

  • UIMA, mais ceux qui veulent utiliser le composant doivent d'ores et déjà avoir réglé ce problème ;
  • le projet mwdumper de MediaWiki ;
  • le sous-projet org.wikimodel.wem de WikiModel.

Par chance tous ces projets sont déjà gérés par maven ce qui va fortement nous faciliter la tâche. Les étapes à suivre sont les suivantes :

  1. Obtenir une version des sources de chacun des projets
  2. Les compiler avec maven
  3. Les installer dans le dépôt local de maven

Ainsi pour mwdumper :

$ svn co http://svn.wikimedia.org/svnroot/mediawiki/trunk/mwdumper
...
$ cd mwdumper
$ mvn compile
...
$ mvn install
...

Une fois ces étapes terminées, un nouveau dossier doit apparaître dans votre dépôt local : ~/.m2/repository/org/wikimedia/mwdumper/ ; il doit contenir un dossier correspondant à la version compilée (1.16 pour moi) et dans ce dossier les fichiers suivants :

  • mwdumper-1.16.jar
  • mwdumper-1.16.pom

Il faut procéder de la même manière pour WikiModel :

$ svn co http://wikimodel.googlecode.com/svn/trunk/org.wikimodel.wem
...
$ cd org.wikimodel.wem
$ mvn compile
...
$ mvn install
...

Vous devriez de la même manière voir apparaître dans votre dépôt local : ~/.m2/repository/org/wikimodel/org.wikimodel.wem/ ; il doit contenir une structure similaire.

Ces étapes sont nécessaires pour la suite car elles placent les dépendances dans le dépôt local de maven, là où il ira les chercher lors de la compilation.

Écriture du pom.xml

Revenons maintenant au composant UIMA. L'intelligence de Maven se configure dans un fichier à la racine du projet et nommé pom.xml.

Dans un premier temps, il faut définir le projet en lui donnant :

  • Un identifiant de groupe (dans le cas où le projet appartiendrait à un groupe de projets) : groupId
  • Un identifiant d'artefact, c-à-d de ce que le projet va produire : artifactId
  • Spécifier une version : version
  • Donner un nom et une description
  • Renseigner les informations concernant les licences
  • Spécifier le type de packaging que l'on souhaite obtenir
  1. <project
  2. xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"
  5. >
  6. <modelVersion>4.0.0</modelVersion>
  7. <groupId>uima.wikipedia</groupId>
  8. <artifactId>uima-mediawiki-loader</artifactId>
  9. <version>0.4</version>
  10. <packaging>jar</packaging>
  11. <name>MediaWiki UIMA Loader</name>
  12. <description>This is a UIMA Collection Reader for the MediaWiki dumps (Wikipedia &amp; co).</description>
  13. <licenses>
  14. <license>
  15. <name>Apache 2</name>
  16. <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
  17. </license>
  18. </licenses>
  19. ...
  20. </project>

Dans un second temps, nous définissons les dépendances nécessaires à la construction de notre composant. Comme nous l'avons vu précédemment, il y en a plusieurs :

  • UIMA, et plus précisément uimaj-core et uimaj-document-annotation
  • WikiModel, et plus précisément org.wikimodel.wem
  • MWdumper

Les dépendances se déclarent entre les tags <dependencies>, en indiquant notamment la version nécessaire.

  1. ...
  2. <dependencies>
  3. <!-- Required to generate the Java classes -->
  4. <dependency>
  5. <groupId>org.apache.uima</groupId>
  6. <artifactId>uimaj-core</artifactId>
  7. <version>2.3.0-incubating</version>
  8. <scope>compile</scope>
  9. </dependency>
  10. <!-- DocumentAnnotation UIMA Type -->
  11. <dependency>
  12. <groupId>org.apache.uima</groupId>
  13. <artifactId>uimaj-document-annotation</artifactId>
  14. <version>2.3.0-incubating</version>
  15. <scope>compile</scope>
  16. </dependency>
  17. <!-- WikiModel -->
  18. <dependency>
  19. <groupId>org.wikimodel</groupId>
  20. <artifactId>org.wikimodel.wem</artifactId>
  21. <version>2.0.7-SNAPSHOT</version>
  22. </dependency>
  23. <!-- WikiMedia Dumper -->
  24. <dependency>
  25. <groupId>org.wikimedia</groupId>
  26. <artifactId>mwdumper</artifactId>
  27. <version>1.16</version>
  28. </dependency>
  29. </dependencies>
  30. ...

Comme vous l'avez certainement remarqué, on a précisé que le projet dépendait d'UIMA, mais contrairement aux dépendances sur MWDumper et WikiModel, nous n'avons pas installé ces dernières dans le dépôt maven local. En fait Maven va être capable d'aller chercher tout seul ces dépendances grâce au dépôt maven mis en ligne par Apache UIMA. Il suffit de préciser l'existence de ce dépôt :

  1. ...
  2. <repositories>
  3. <!-- Apache UIMA repository -->
  4. <repository>
  5. <id>apache</id>
  6. <name>Apache</name>
  7. <url>http://people.apache.org/repo/m2-incubating-repository</url>
  8. </repository>
  9. </repositories>
  10. ...

Finalement, on précise le processus de construction du composant entre les tags <build>. Dans nos cas cela revient tout simplement à préciser où aller chercher les sources, où placer les fichiers compilés et préciser ce qui doit être considérés comme des ressources et donc placé dans le Jar en plus des classes.

On utilisera de plus le plugin maven-compiler-plugin afin de préciser la version de Java que l'on souhaite pour la compilation.

  1. ...
  2. <build>
  3. <plugins>
  4. <!-- Java Compiler -->
  5. <plugin>
  6. <groupId>org.apache.maven.plugins</groupId>
  7. <artifactId>maven-compiler-plugin</artifactId>
  8. <version>2.0.2</version>
  9. <configuration>
  10. <source>1.5</source>
  11. <target>1.5</target>
  12. </configuration>
  13. </plugin>
  14. </plugins>
  15. <sourceDirectory>src</sourceDirectory>
  16. <outputDirectory>bin</outputDirectory>
  17. <resources>
  18. <resource>
  19. <directory>desc</directory>
  20. </resource>
  21. </resources>
  22. </build>
  23. ...

Le pom.xml est suffisant à cette étape pour permettre de lancer la compilation du projet et le packaging.

$ mvn compile
...

Vous devriez constater que le dossier bin s'est peuplé des classes compilées.

$ mvn package
...

Vous devriez maintenant constater l'apparition d'un dossier target dans lequel vous trouverez notamment un Jar nommé : uima-mediawiki-loader-0.4.jar. Et voilà, dans l'état il est possible d'obtenir un Jar du projet à partir des sources sans trop de problèmes. Toutefois la première étape de récupération des dépendances me paraît trop contraignantes. Il est possible, à l'instar d'Apache UIMA, de mettre en place un dépôt contenant des versions compilées des dépendances afin que maven aille directement les chercher.

Mettre en place un dépôt pour les dépendances

Un dépôt maven ce n'est ni plus ni moins qu'un système de fichiers respectant une certaine structure et accessible par http (par exemple).

J'ai créé un dossier sur mon serveur que j'ai rendu accessible par http à l'aide d'Apache, puis j'y ai collé l'arborescence concernant mwdumper et wikimodel quiu était présente dans mon dépôt local :

  • ~/.m2/repository//org/wikimedia/...
  • ~/.m2/repository//org/wikimodel/...

Il y a une petite nuance tout de même, lorsque le dépôt est distant, les fichiers doivent être accompagnés de leurs checksums afin de vérifier que le téléchargement s'est bien déroulé. Le plus simple pour générer ces fichiers de checksums est de réitérer l'installation dans le dépôt maven local avec une option supplémentaire :

$ mvn install -DcreateChecksum=true
...

Vous trouverez alors dans le dépôt local les fichiers en *.md5 et *.sha1 qu'il faut également transférer sur le serveur.

Une fois que le dépôt distant est mis en place, il suffit de le déclarer dans le pom.xml :

  1. ...
  2. <repository>
  3. <id>uima-fr.org</id>
  4. <name>UIMA Fr</name>
  5. <url>http://www.uima-fr.org/m2-repo/</url>
  6. </repository>
  7. ...

Il est maintenant possible de compiler le composant sans avoir à récupérer les dépendances en amont. Tout se fait automatiquement et de manière transparente pour l'utilisateur... c'est assez plaisant.

Comme je suis un fainéant, je trouve que ce serait cool de pouvoir déployer automatiquement mon composant sur mon dépôt, c'est tellement pratique les dépôts !

Déployer le composant sur le dépôt

J'ai choisi de pouvoir déployer mon composant sur le dépôt par ssh, pour des questions de sécurité. Mais il est également possible de le faire par ftp. Le déploiement par ssh nécessite tout d'abord de pouvoir se connecter automatiquement au serveur par ssh à l'aide d'un échange de clé, puis il suffit de renseigner dans le pom.xml l'adresse du dépôt et dans ~/.m2/settings.xml de préciser les modalités de connexion au dépôt.

Connexion automatique par ssh

Je ne vais pas détailler ici comment déployer un serveur ssh et faire tourner un ssh-agent en local, il y a tout un tas de tutoriels disponibles sur internet pour ça. Ce qu'il faut juste retenir, c'est que maven ne se connectera au serveur ssh si les deux conditions suivantes sont remplies :

  • Le serveur est connu de ssh (il est enregistré dans .ssh/know_hosts) ;
  • La connexion peut se faire par échange de clés (pas de mot de passe).

Le plus simple pour s'assurer de tout cela est de se connecter directement manuellement au serveur :

  • Si le serveur est inconnu, ssh demandera s'il doit être ajouté à la liste des hôtes connus : acceptez ;
  • Si le serveur vous demande un mot de passe c'est qu'il ne connaît pas votre clé, il suffit de lui donner.

Copiez donc le contenu de votre clé publique que vous trouverez dans le fichier ~/.ssh/id_dsa.pub ou bien ~/.ssh/id_rsa.pub. Elle doit ressembler à quelque chose comme ceci :

ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzqedhFIi8hy743U7pEvLMQvCEeAo/CxmLjF4jF2WguguN+U/4GsJrONvgoWMYXRn0zVMoHNpCEXQ+BT80ZTnv+MILu5elgFsE18bFA+7qjd454LwuZpoIoJOsCNyJKyGjy7ER5cZGN/z8G6cmSJTGauc270W7WJQELqKM3rfqPJH4FXPF9+WDP4UK/o7k54g36/3hHeBmqW++mpyEwkm0eT+GlBRlmP4NjVJACMoyYwl2S1Ep/m85aYR+95m3neHFZpUPmEyN52/Sod7ak28AHZ0M5oE/nRoUr1AAc0LzJw7BM327fAO6o7iHcfoIdo7pix2KLoteqT8tQIRQUmzxQ== grdscarabe@grdscarabe-desktop

Attention, cette clé se trouve sur le poste client à partir duquel maven se connaîtra !

Copiez donc cette clé dans le fichier ~/.ssh/authorized_keys, si ce fichier n'existe pas créez-le. Faites bien attention à ce qu'il soit dans le répertoire personnel de l'utilisateur que maven utilisera pour se connecter (le votre très certainement).

Une fois cette opération effectuée, vous devriez pouvoir vous connecter au serveur sans que ce dernier ne vous demande de mot de passe. Il se peut que si vous ayez protégé votre clé privée par un mot de passe, le ssh-agent vous le demande. Dans ce cas vous êtes de mon point de vue suffisamment au courant du problème pour ne pas lire cette section. Sinon vous êtes bien malin d'avoir mis un mot de passe :)

Déclaration du dépôt dans le pom.xml

Il suffit de déclarer dans le dépôt dans le pom.xml, nous l'appellerons ici uimafr-repository. Il est également nécessaire de charger l'extension wagon-ssh-external qui permet à maven de déployer par ssh :

  1. ...
  2. <extensions>
  3. <!-- Enabling the use of SSH -->
  4. <extension>
  5. <groupId>org.apache.maven.wagon</groupId>
  6. <artifactId>wagon-ssh-external</artifactId>
  7. <version>1.0-beta-6</version>
  8. </extension>
  9. </extensions>
  10. <distributionManagement>
  11. <repository>
  12. <id>uimafr-repository</id>
  13. <url>scpexe://www.uima-fr.org//home/www-data/org_uima-fr_www/m2-repo</url>
  14. </repository>
  15. </distributionManagement>
  16. ...

Modalités de connexion au dépôt

Enfin, il faut localement configurer maven pour reconnaître le dépôt uimafr-repository. Cette configuration se fait par le fichier ~/.m2/settings.xml. S'il n'existe pas, créez-le puis copiez-collez y le contenu suivant :

  1. <settings>
  2. <servers>
  3. <server>
  4. <id>uimafr-repository</id>
  5. <configuration>
  6. <sshExecutable>ssh</sshExecutable>
  7. <scpExecutable>scp</scpExecutable>
  8. </configuration>
  9. </server>
  10. </servers>
  11. </settings>

En gros ce dernier permet de préciser quels sont les outils à utiliser pour la connexion ssh. Sous linux, nous utiliserons les outils ssh pour la connexion et scp pour le transfert de fichier.

Déploiement

Et voilà, maintenant pour déployer mon composant sur le dépôt, il me suffit de faire :

$ mvn deploy
...

Elle est pas belle la vie ?

Extensions possibles

Il y a bien des extensions possibles pour rendre maven encore plus pratique pour la gestion de ce projet. J'en vois notamment deux :

  • La génération automatique des classes de types UIMA à partir de JCasGen ;
  • L'empaquetage dans le même Jar du projet et des dépendances sur MWDumper et WikiModel.

Dans le premier cas, la solution au problème doit certainement se trouver du côté du ''exec-maven-plugin''. Dans le second cas, il faudrait aller voir du côté de ''maven-assembly-plugin''.

Nouvelle version du composant

Et je conclus ce looong billet en distribuant la nouvelle version, estampillée 0.4, du collection reader pour Wikipedia : par ici ! Vous trouverez les dépendances nécessaires à son fonctionnement dans le dépôt maven de uima-fr.

Vous pouvez tester le composant à l'aide du cpeGui :

$ UIMA_CLASSPATH=~/.m2/repository/uima/wikipedia/mwuima-loader/0.4/mwuima-loader-0.4.jar:~/.m2/repository/org/wikimedia/mwdumper/1.16/mwdumper-1.16.jar:~/.m2/repository/org/wikimodel/org.wikimodel.wem/2.0.7-SNAPSHOT/org.wikimodel.wem-2.0.7-SNAPSHOT.jar cpeGui

Bien sûr, si vous n'avez pas installé le composant avec maven, il faudra modifier en conséquence les chemins du UIMA_CLASSPATH.

Autres articles

  • UIMA & Wikipédia (1) : Proposition de Type System
  • UIMA & Wikipédia (2) : Chargement d'un dump Wikipedia
  • UIMA & Wikipédia (3) : Filtrage des données à charger
  • UIMA & Wikipédia (4) : Analyse de la syntaxe MediaWiki
Retour au sommaire
 

UIMA & Wikipédia (4) : Analyse de la syntaxe MediaWiki

0 vote
Par Fabien POULARD le 14/02/2010 à 14:35 Voir l'article

Wikipedia est une incroyable source d'information, de données et plus généralement d'actes langagiers (utilisation du langage). Ce dernier point est très important pour nous autres chercheurs en traitement automatique des langues. En effet, nous avons besoin d'observer de très nombreux exemples d'utilisation du langage, que ce soit de manière automatique ou manuelle. Pour ce faire, nous compilons de vastes exemples d'utilisation du langage sous forme de corpus.

La création de composants UIMA permettant d'accéder et tirer parti de Wikipédia offrirait de nouvelles perspectives au traitement des langues en offrant un accès aisé à cette formidable ressource que représente l'encyclopédie libre. Je compte m'atteler à la création de tels composants et vais tâcher de publier plusieurs billets décrivant ma démarche en cours.

Voici le quatrième billet qui discute de l'analyse syntaxique du contenu des pages wiki pour la suppression des balises Wiki.

Analyse syntaxique des pages MediaWiki

Il existe plusieurs initiatives de programmes permettant d'interpréter la syntaxe de MediaWiki. Il y a le code PHP utilisé par MediaWiki et qui sert de référence, mais également plusieurs autres initiatives notamment en Java.

La plupart des initiatives Java ont pour objectif de produire des version XHTML ou PDF des pages en syntaxe wiki et ne donnent pas accès à l'arbre syntaxique de la page. Un programme en C basé sur Flex/Bison et développé dans le cadre du projet MediaWiki offre cette possibilité.

Parmi les initiatives en Java qui semblent intéressantes pour le collection reader UIMA :

  • JAMWiki qui est plus ou moins une réécriture de MediaWiki en Java et dont l'analyseur syntaxique semble réutilisable ;
  • WikiModel supporte plusieurs langages Wiki ;
  • Bliki

J'ai tout d'abord essayé Bliki pour traiter la syntaxe de MediaWiki. Ce dernier s'est toutefois avéré assez complexe, notamment au niveau de son architecture, de telle façon que je n'ai pas réussi à obtenir ce que je voulais. Je me suis alors tourné vers WikiModel qui offre un analyseur syntaxique (Wiki Event Model (WEM)) au fonctionnement proche de SAX.

WikiModel pour MediaWiki

Le gros avantage de WikModel est qu'il offre directement un parseur pour MediaWiki : org.wikimodel.wem.mediawiki.MediaWikiParser. Le parseur analyse du code Wiki brute et, comme un parseur SAX classique, lance des évènements à une instance implémentant l'interface org.wikimodel.wem.IWemListener. J'ai choisi de créer une classe MediawikiCasConverter implémentant cette interface et gérant elle même le lancement du parseur sur les textes brutes extraits des révisions.

  1. import org.wikimodel.wem.mediawiki.MediaWikiParser
  2. import org.wikimodel.wem.IWemListener;
  3. ...
  4. public class MediawikiCasConverter implements IWemListener {
  5.  
  6. public MediawikiCasConverter() {
  7. theParser = new MediaWikiParser();
  8. }
  9.  
  10. public void runParser(String rawWikiText) throws WikiParserException {
  11. // We use a string reader to parse the raw wiki texte
  12. StringReader reader = new StringReader(rawWikiText);
  13. // Parsing
  14. theParser.parse(reader, this);
  15. }
  16.  
  17. // IWemListener methods below
  18. ...
  19. }

Les méthodes du IWemListener sont de deux types. Les premières sont des méthodes one shot, ie elles sont appelées une seule fois lorsqu'un élément est rencontré. Ce sont notamment celles qui concernent le texte et leur mise en forme :

  • onEscape(String str)
  • onSpace(String str)
  • onSpecialSymbol(String str)
  • onWord(String str)
  • onReference(String str)

Les secondes sont des méthodes à la SAX en deux temps : begin et end. Ce sont notamment celles qui concernent la structuration du texte :

  • beginHeader(int headerLevel, WikiParameters params)
  • endHeader(int headerLevel, WikiParameters params)
  • beginSection(int docLevel, int headerLevel, WikiParameters params)
  • endSection(int docLevel, int headerLevel, WikiParameters params)
  • beginParagraph(WikiParameters params)
  • endParagraph(WikiParameters params)
  • beginList(WikiParameters params, boolean ordered)
  • endList(WikiParameters params, boolean ordered)

La plupart de ces méthodes ne font que des appels à une fonction de plus haut niveau qui collecte les données textuelles de la page et qui maintient l'index du CAS : addToContent. C'est notamment le cas pour la méthode onWord qui est appelée lorsque le parseur rencontre un nouveau mot :

  1. /**
  2.  * This method adds the string in parameter into the collected content
  3.  * and then increment the offset by the size of this string.
  4.  *
  5.  * @param str the string to be added to the content
  6.  */
  7. protected void addToContent(String str) {
  8. if ( str != null ) {
  9. theTextContent.append(str);
  10. theOffset += str.length();
  11. }
  12. }
  13. ...
  14. /** Called when a word is encountered */
  15. public void onWord(String str) {
  16. addToContent(str);
  17. }

J'ai choisi de transposer une partie des informations contenues dans les pages de Wikipedia sous la forme d'annotations. J'ai ainsi ajouté les types :

  • Header pour les titres qui possède un attribut Level indiquant le niveau de titre ;
  • Paragraph pour différencier les paragraphes ;
  • Section pour repérer les sections même si je ne suis pas certain d'avoir bien compris le principe de section dans MediaWiki. Ce type possède les attributs Level pour le niveau de section (cf. niveau de titre), Parent pointant sur la section parente et Title pointant sur le Header correspondant à ladite section ;
  • Link pour les liens divers et variés qui possède des attributs Label et Link pour respectivement l'étiquette du lien et son adresse.

En ce qui concerne les liens, j'ai choisi pour le moment d'ignorer les images qui me semblent apporter plus de bruit qu'autre chose.

La mise en place de ces annotations se fait assez facilement :

  1. Lors d'un appel à begin..., l'annotation est créée est stockée dans une liste, la plupart des informations excepté son index de fin est renseigné à ce moment ;
  2. Lors de l'appel correspondant à end..., la dernière annotation de la liste est récupérée et on fixe son index de fin (setEnd) ;
  3. Lorsque l'analyse est terminée, toutes les annotations sont accessibles par la méthode getAnnotations afin de les ajouter à l'index du CAS.

Cette approche permet de dédier toute la partie analyse à une classe. Si jamais l'on veut ignorer certaines annotations (ou toutes), il suffit de les filtrer au moment de leur récupérer par getAnnotations. L'extrait de code ci-dessous illustre ce fonctionnement pour les titres :

  1. /**
  2.  * When we encounter a new header, we create an annotation for it.
  3.  */
  4. public void beginHeader(int headerLevel, WikiParameters params) {
  5. // Jump a line
  6. addToContent(" ");
  7. // Create the annotation
  8. Header header = new Header(theCas);
  9. header.setLevel(headerLevel);
  10. header.setBegin( theOffset );
  11. // Add it to the list
  12. theHeadersAnnotations.add( header );
  13. // Add it as header of the last unclosed section
  14. if ( theUnclosedSections.size() > 0 ) {
  15. Section section = theUnclosedSections.get( theUnclosedSections.size()-1 );
  16. section.setTitle(header);
  17. }
  18. }
  19.  
  20. /**
  21.  * Add the ending value of the last started header.
  22.  */
  23. public void endHeader(int headerLevel, WikiParameters params) {
  24. // Retrieve the last header
  25. Header header = theHeadersAnnotations.get( theHeadersAnnotations.size()-1 );
  26. // Update its ending value
  27. header.setEnd( theOffset );
  28. // Jump a line
  29. addToContent(" ");
  30. }

Je me suis rendu compte que le parseur posait des problèmes (heap overflow) sur des pages de certains espaces de noms. J'ai donc choisi de n'appliquer l'analyse syntaxique qu'aux pages de l'espace de nom 0 (espace de nom principal). Ceci est toutefois facilement modifiable dans la méthode uima.wikipedia.mwdumper.ThreadedMWDumper.writeStartPage.

Il reste pas mal d'améliorations possibles : prendre en compte toutes les mises en formes/structurations, prendre en charge les macros, rendre l'analyse syntaxique configurable. Toutefois, le composant est dans l'état actuel aussi complet et performant que je le souhaitais à l'origine. Il ne reste plus qu'à le tester de manière intensive. J'ai d'ailleurs deux trois cobayes en tête pour ça.

Nouvelle version du composant

Pas de nouvelle version du composant pour l'instant. Étant donné que les dépendances se sont multipliées, et que le composant est désormais suffisamment fonctionnel pour se voir estampillé 1.0 ou quelque chose du genre, je vais travailler un peu plus son packaging.

Autres articles

  • UIMA & Wikipédia (1) : Proposition de Type System
  • UIMA & Wikipédia (2) : Chargement d'un dump Wikipedia
  • UIMA & Wikipédia (3) : Filtrage des données à charger
  • UIMA & Wikipédia (5) : Gestion du projet avec Maven
Retour au sommaire
 

UIMA & Wikipédia (3) : Filtrage des données à charger

0 vote
Par Fabien POULARD le 12/02/2010 à 14:56 Voir l'article

Wikipedia est une incroyable source d'information, de données et plus généralement d'actes langagiers (utilisation du langage). Ce dernier point est très important pour nous autres chercheurs en traitement automatique des langues. En effet, nous avons besoin d'observer de très nombreux exemples d'utilisation du langage, que ce soit de manière automatique ou manuelle. Pour ce faire, nous compilons de vastes exemples d'utilisation du langage sous forme de corpus.

La création de composants UIMA permettant d'accéder et tirer parti de Wikipédia offrirait de nouvelles perspectives au traitement des langues en offrant un accès aisé à cette formidable ressource que représente l'encyclopédie libre. Je compte m'atteler à la création de tels composants et vais tâcher de publier plusieurs billets décrivant ma démarche en cours.

Voici le troisième billet qui discute du filtrage des données à charger : articles, révision, ...

Filtres de MWDumper

L'outil mwdumper inclut un certain nombre de filtres commandables à partir de la ligne de commande :

  • LatestFilter permet de ne conserver que la dernière révision d'une page ;
  • NamespaceFilter permet de ne conserver que les articles qui appartiennent à un espace de nom particulier (passé en paramètre) ;
  • NotalkFilter permet d'ignorer les pages de discussion ;
  • TitleMatchFilter permet de ne conserver que les pages dont le titre valide une expression rationnelle donnée en paramètre ;
  • ListFilter permet de ne conserver que les pages dont le titre de la page de données ou de discussion est présent dans un fichier passé en paramètre (un nom de page par ligne) ;
  • ExactListFilter est identique au filtre précédent si ce n'est que son application est plus stricte car seul le titre de la page est considéré ;
  • RevisionListFilter reprend le principe des filtres précédents si ce n'est qu'il s'applique aux identifiants de révisions ;
  • BeforeTimeStampFilter ne conserve que les données produites avant une date passée en paramètre ;
  • AfterTimeStampFilter ne conserve que les données produites après une date passée en paramètre ;

Voir le billet Insérer plusieurs copies locales de Wikipedia dans une base PostgreSQL pour un cas d'utilisation de ces filtres. La combinaison de ces filtres permet de contrôler avec précision les données à charger, nous allons donc nous en contenter.

Paramétrage du composant

On peut classer les filtres en deux familles : ceux qui nécessitent des paramètres et ceux qui n'en nécessitent pas. J'ai donc choisi pour le moment d'utiliser des paramètres booléens pour les filtres sans paramètre, et des paramètres chaînes de caractères pour les autres.

L'activation des paramètres booléens suffit à activer les filtres correspondant : IgnoreTalks et LatestRevisionOnly.

Pour activer les autres filtres il suffit de les configurer en renseignant les champs dédiés. Si les champs restent non renseignés alors les filtres ne sont pas activés : ConfigNamespacesFilter, ConfigTitleMatch, ConfigListFilter, ConfigExactListFilter, ConfigRevisionListFilter, ConfigBeforeTimestampFilter, ConfigAfterTimestampFilter.

Nouvelle version

Voici une nouvelle version du collection reader pour Wikipédia, estampillée 0.2, qui ne prend toujours pas en compte la syntaxe, mais qui permet de filtrer le type de contenu à charger à partir du dump XML. Pour utiliser le composant, il est nécessaire d'avoir le jar de mwdumper dans le classpath.

Autres articles

  • UIMA & Wikipédia (1) : Proposition de Type System
  • UIMA & Wikipédia (2) : Chargement d'un dump Wikipedia
  • UIMA & Wikipédia (4) : Analyse de la syntaxe MediaWiki
  • UIMA & Wikipédia (5) : Gestion du projet avec Maven
Retour au sommaire
 

UIMA & Wikipédia (2) : Chargement d'un dump Wikipedia

0 vote
Par Fabien POULARD le 02/02/2010 à 14:05 Voir l'article

Wikipedia est une incroyable source d'information, de données et plus généralement d'actes langagiers (utilisation du langage). Ce dernier point est très important pour nous autres chercheurs en traitement automatique des langues. En effet, nous avons besoin d'observer de très nombreux exemples d'utilisation du langage, que ce soit de manière automatique ou manuelle. Pour ce faire, nous compilons de vastes exemples d'utilisation du langage sous forme de corpus.

La création de composants UIMA permettant d'accéder et tirer parti de Wikipédia offrirait de nouvelles perspectives au traitement des langues en offrant un accès aisé à cette formidable ressource que représente l'encyclopédie libre. Je compte m'atteler à la création de tels composants et vais tâcher de publier plusieurs billets décrivant ma démarche en cours.

Voici le second billet qui discute du chargement d'un dump XML de l'encyclopédie libre et la distribution du contenu sous forme de CAS.

Wikipédia, formats brutes

La base de données contenant toutes les pages de Wikipédia et autre sites de la fondation WikiMedia est automatiquement archivée très régulièrement. Les dumps de la base sont disponibles sur http://download.wikimedia.org/. Vous trouverez ainsi :

  • les archives de la Wikipédia française
  • les archives de WikiNews ou juste la partie en français
  • les archives de la Wikiversity ou juste la partie en français
  • les archives des WikiBooks

Il est également possible de télécharger l'intégralité de l'encyclopédie dépourvue des balises wiki : http://download.wikimedia.org/nowiki/.

Le billet Créer un miroir Wikipédia explique comment construire une copie locale de l'encyclopédie à partir de ces différents dumps. Nous nous donnons comme objectif d'exploiter ces dumps directement sans passer par une importation en base de données.

L'outil d'exportation et d'importation de MediaWiki : mwdump

MWDumper est un outil écrit en Java par les développeurs de MediaWiki qui permet d'importer/exporter une base MediaWiki à partir de/vers une base de données. Cet outil a l'avantage de travailler directement sur la version compressée du dump XML, réduisant ainsi le besoin en espace disque disponible. Cet outil s'utilise en ligne de commande et offre un certain nombre de paramètres permettant notamment de filtrer les articles à exporter ou bien le format SQL à prendre en charge.

Une version compilée de l'outil est disponible sur download.wikipedia.org, mais il y a de forte chance qu'elle soit dépassée. Le plus sûr est de compiler l'outil depuis les sources.

Une partie du code de cet outil va nous faciliter la tâche pour la réalisation d'un collection reader pour UIMA, notamment les classes :

  • org.mediawiki.importer.XmlDumpReader
  • org.mediawiki.importer.DumpWriter
  • org.mediawiki.importer.Page
  • org.mediawiki.importer.Revision

Il nous faut toutefois noter que XmlDumpReader repose sur un analyseur SAX, ce qui n'est pas directement utilisable dans un Collection Reader d'UIMA. En effet, dans UIMA c'est le Collection Reader qui contrôle l'exécution, alors qu'à l'opposé l'analyseur SAX contrôle sa propre exécution. La seule interaction avec le parseur est l'emploi des hooks.

L'idée est de faire tourner l'analyseur SAX dans un thread différent de celui du collection reader. Ensuite à l'aide d'un mécanisme de sémaphore (ou de monitor en Java), on contrôle l'exécution du parseur pour produire les CAS. Cette méthode permet d'utiliser presque directement l'outil de MediaWiki, ainsi si la syntaxe évolue, l'outil de MediaWiki évoluera également certainement et ce sera donc normalement transparent pour le collection reader.

Une première version de collection reader pour Wikipedia

Voici une première version du collection reader pour Wikipédia qui ne prend pas du tout en compte la syntaxe, mais charge seulement le contenu des pages dans un CAS. Il y a encore beaucoup de travail pour obtenir quelque chose d'intéressant et d'utilisable, d'où l'estampillage 0.1. Pour utiliser le composant, il est nécessaire d'avoir le jar de mwdumper dans le classpath.

Il y a tout un tas d'améliorations que j'aimerais apporter (filtrage, analyse de la syntaxe wiki, ...) mais l'idée est dans un premier temps de fournir une version brute de fonderie qui fonctionne pour qu'elle puisse être testée. Le jar contient notamment le code Java, donc il ne faut pas hésiter à y jeter un oeil.

Le descripteur est dans le Jar distribué, il ne prend en paramètre que le chemin vers le dump XML à charger. Peu importe l'extension (.gz, .bz, ...), il devrait pouvoir s'en sortir. Si ce n'est pas le cas, laissez un commentaire ! Je n'ai fait que peu de tests pour le moment, je ne sais pas trop comment le composant tient la route sur des gros dumps, mais la première remarque est qu'il est nécessaire d'augmenter la taille du tas de la jvm (-Xmx=512m pour commencer). En effet, certaines pages sont assez imposantes de par leur grand nombre de révisions, et pour l'instant toutes les révisions sont chargées dans chaque CAS.

Autres billets

  • UIMA & Wikipédia (1) : Proposition de Type System
  • UIMA & Wikipédia (3) : Filtrage des données à charger
  • UIMA & Wikipédia (4) : Analyse de la syntaxe MediaWiki
  • UIMA & Wikipédia (5) : Gestion du projet avec Maven
Retour au sommaire
 

UIMA & Wikipédia (1) : Proposition de Type System

0 vote
Par Fabien POULARD le 01/02/2010 à 02:15 Voir l'article

Wikipedia est une incroyable source d'information, de données et plus généralement d'actes langagiers (utilisation du langage). Ce dernier point est très important pour nous autres chercheurs en traitement automatique des langues. En effet, nous avons besoin d'observer de très nombreux exemples d'utilisation du langage, que ce soit de manière automatique ou manuelle. Pour ce faire, nous compilons de vastes exemples d'utilisation du langage sous forme de corpus.

La création de composants UIMA permettant d'accéder et tirer parti de Wikipédia offrirait de nouvelles perspectives au traitement des langues en offrant un accès aisé à cette formidable ressource que représente l'encyclopédie libre. Je compte m'atteler à la création de tels composants et vais tâcher de publier plusieurs billets décrivant ma démarche en cours.

Voici le premier billet qui discute de la création d'un Type System approprié pour représenter les pages de Wikipedia.

Wikipédia, structuration des données

L'encyclopédie Wikipédia contient tout un tas d'informations mais je me concentrerai particulièrement sur le contenu même : les articles. Je propose de classer les informations concernant ces derniers en quatre grandes catégories :

  • Position de l'article dans l'encyclopédie (portail, catégories, ...)
  • Versions de l'article (révisions, ...)
  • Structuration de l'article (titre, sous-titre, ...)
  • Macros et mise en forme du texte (gras, italique, ...)

Position de l'article dans l'encyclopédie

On peut considérer la Wikipédia comme un ensemble de pages liées selon trois grandes relations :

  • Les catégories
  • Les liens interlangues
  • Les liens internes

Les catégories structurent l'encyclopédie à la manière d'une ontologie ou d'un thésaurus. Une page peut appartenir à une ou plusieurs catégories. De plus, les catégories sont hiérarchisées, l'appartenance à une catégorie implique l'appartenance à toutes les catégories parentes.

Les liens interlangues marquent les pages en relation de traduction avec la page courante.

Les liens internes permettent au sein d'une page de faire référence à d'autres pages de l'encyclopédie, il s'agit d'une structuration qui n'a qu'un impact local. La signification de ces références est très variable et difficilement identifiable.

Versions de l'article

Le principe de l'encyclopédie collaborative est que tout le monde peut modifier un article, ce qui amène à de multiples révisions de ces derniers. Lorsque vous cliquez sur l'onglet Historique d'un article, vous pouvez visionner ces différentes révisions, leur auteur, et éventuellement un commentaire précisant l'apport de la révision.

Structuration d'un article

Le contenu d'un article se structure à l'aide de titres, de paragraphes ainsi que de divers éléments de mise en forme : [tableaux], [formules], [listes], ...

Parmi les éléments de mise en forme, on peut également noter l'existence de plusieurs macros pour les [modèles], [dates], [liens interwiki], ...

Choix d'un Type System

Je ne crois personnellement pas à l'existence de Type Systems génériques pouvant être partagés par tous les composants. De mon point de vue, un Type System va être approprié au traitement d'une tâche particulière, chercher à en produire un suffisamment générique pour toutes les tâches seraient une perte de temps et mènerait certainement à un TS difficile à utiliser.

Personnellement, je vais utiliser Wikipedia dans le cadre de ma thèse sur la détection de dérivation de texte. Ce qui m'intéresse c'est donc de générer un CAS par article dans lequel on retrouvera les différentes révisions dudit article. Je m'intéresse donc :

  • à la notion d'article
  • aux notions de révision
  • à la structuration du contenu d'un article à l'aide des titres et des paragraphes
  • au texte

Après réflexion j'en suis donc arrivé à cette modélisation :

TS Wikipedia (png)

Cette modélisation ne correspond pas exactement aux besoins d'un TS UIMA. Ainsi, les relations de composition se manifestent par un phénomène de couverture des annotations, entraînant la disparition des attributs correspondant.

Vous trouverez le descripteurs correspondant à ce TS ici.

Autres billets

  • UIMA & Wikipédia (2) : Chargement d'un dump Wikipedia
  • UIMA & Wikipédia (3) : Filtrage des données à charger
  • UIMA & Wikipédia (4) : Analyse de la syntaxe MediaWiki
  • UIMA & Wikipédia (5) : Gestion du projet avec Maven
Retour au sommaire
 

Sortie d'Apache UIMA 2.3

0 vote
Par Fabien POULARD le 29/01/2010 à 10:48 Voir l'article

L'annonce est parue hier sur les listes concernées, la nouvelle version du framework Apache UIMA (Unstructured Information Management Architecture) est sortie, estampillée 2.3 !

Au programme de cette nouvelle version, beaucoup de corrections de bug come d'habitude, mais surtout l'intégration de UIMA-AS qui permet une meilleure distribution des calculs entre plusieurs serveurs et l'ajout de plusieurs addons :

  • Bean Scripting Framework qui va permettre d'écrire des annotateurs dans plusieurs langages de script ;
  • Lucas qui permet d'interfacer UIMA avec Apache Lucene
  • TikaAnnotator qui fait également parti du projet Apache Lucene et qui permet tout simplement de charger un grand nombre de formats de fichiers (html, xml, Microsoft Office, pdf, rtf ainsi que des formats audio et vidéo).

Cette nouvelle mouture d'UIMA tire désormais parti des génériques de Java 5, ce qui va permettre de limiter les casting aventureux pour récupérer les annotations, itérateurs, ... :) Cela signifie toutefois que la version 5 de Java est désormais le requis minimum pour utiliser UIMA.

Vous trouverez plus de détails sur cette version dans les notes de release :

  • UIMA Java
  • UIMA AS
  • UIMA C++
  • Addons
Retour au sommaire
 

Construction de la communauté UIMA-Fr

0 vote
Par Fabien POULARD le 09/11/2009 à 10:18 Voir l'article

Depuis le début de ma thèse, nous (un sous-ensemble dynamique de mon équipe de recherche) avons mis l'accent sur la nécessité de développer nos outils autour d'une plateforme unifiée afin que chacun tire parti du travail des autres. Nous avons alors proposé la solution du framework Apache UIMA, proposé des formations autour de ce dernier et entamé une migration des outils existant. L'initiative est aujourd'hui un succès: nous sommes monté en compétence sur UIMA et les nouveaux doctorants travaillent tous autour de cette plateforme !

Les bénéfices d'une plateforme unifiée au sein d'une équipe seraient à notre avis amplifiés si cette initiative était étendue à toute la communauté francophone ! Chacun pourrait alors profiter directement des développements et ressources développées par les autres équipes. C'est sur la base de cette hypothèse que nous prenons l'initiative d'initier la construction d'une communauté UIMA francophone.

Afin d'initier la construction d'une communauté UIMA francophone, nous avions en juillet dernier organisé un tutoriel ainsi qu'un workshop lors de la 10e édition des RMLL à Nantes. Les papiers présentés au workshop sont d'ailleurs disponibles sur le site des RMLL. L'environnement du tutoriel, accompagné des supports, a quand à lui été publié en ligne récemment.

Aujourd'hui nous sommes heureux d'annoncer le lancement du portail UIMA-FR ! Pour reprendre les mots de Nicolas dans le mail d'annonce sur la liste UIMA-Fr :

Ce portail a pour objectif d'encourager la construction d'une communauté francophone en fournissant des sercices aux utilisateurs et développeurs francophones, industriels ou académiques, pour pouvoir discuter et échanger de l'information autour de l'architecture UIMA.

Vous trouverez ainsi sur le portail :

  • Une liste de discussion afin que chacun puisse partager ses connaissances au reste de la communauté et trouver en contre-partie des éléments de réponse à ses problèmes ;
  • Un planet qui, à l'instar des différents planets de la communauté du Logiciel Libre (ici, là ou encore là), regroupera les billets des acteurs de la communauté qui le souhaiteront (pour y ajouter votre site, c'est par ici) ;
  • Un espace de partage des composants et ressources développés par la communauté.

Tout ceci est bien sûr soumis sous forme d'une proposition, à vous de participer à la construction de la communauté en proposant de nouveaux services, des évolutions ou en filant un coup de main pour l'administration...

Longue vie à la communauté UIMA-Fr !

Retour au sommaire
 

UIMA : Comment utiliser un type dont un attribut est un tableau de types ?

0 vote
Par Fabien POULARD le 30/09/2009 à 15:13 Voir l'article

L'un des avantages indéniable de UIMA est de pouvoir définir son propre TypeSystem, ie l'ensemble des éléments que l'on va manipuler. De plus, ce TypeSystem est un arbre d'objets, ce qui permet de construire des structures de données enchevêtrées complexes.

Cet article illustre la construction et l'utilisation d'un type dont un attribut est un tableau d'un autre type.

Définition du TypeSystem

La construction d'un TypeSystem a de particulier l'utilisation du super type FSArray.

Tout d'abord il est nécessaire de créer un nouveau type d'annotation, disons MyEmbeddedType, correspondant aux annotations stockées dans le tableau. Rien de particulier concernant ce type si ce n'est qu'il faut le créer avant le type contenant le tableau.

Il est ensuite possible de créer le type dérivant du super type FSArray, disons MyComplexType. C'est ce type qui contient un attribut regroupant des annotations MyEmbeddedType sous la forme d'un tableau. Rien de spécial concernant le type en lui-même, il faut lui ajouter un attribut ayant pour range type FSArray et element type MyEmbeddedType.

Rien de bien complexe donc concernant la création du TypeSystem, si ce n'est qu'il faut tout de même savoir comment ça fonctionne :)

Construction

Pour comprendre le fonctionnement des types à tableaux de type, il faut bien comprendre que FSArray se comporte comme un Array statique en Java.

  1. // Préparation de la donnée tableau factice, c'est pour l'exemple
  2. ArrayList<MyEmbeddedType> lst = new ArrayList<MyEmbeddedType>();
  3. for(int i ; i<10 ; i++) {
  4. MyEmbeddedType mEType = new MyEmbeddedType(cas);
  5. // ... faire quelque chose avec mEType
  6. mEType.addToIndexes();
  7. lst.add(mEType);
  8. }
  9. // Transformation en tableau "statique"
  10. MyEmbeddedType[] mETypes = lst.toArray(new MyEmbeddedType[lst.size()]);
  11. // Création du FSArray
  12. FSArray mETypesFS = new FSArray(cas, mETypes.length);
  13. mETypesFS.copyFromArray(mETypes, 0, 0, mETypes.length);
  14. // Création d'une instance du type complexe et ajout du contenu
  15. MyComplexType mCType = new MyComplexType(cas);
  16. mCType.setMyComplexFeature( mETypesFS );

L'approche proposée ici est de construire un tableau au travers d'une ArrayList dans un premier temps, y ajouter les éléments voulus et faire toutes les opérations nécessaires jusqu'à ce que le contenu soit stabilisé. Il faut garder en tête que l'enregistrement en tant qu'annotation n'a d'intérêt que pour stocker la donnée dans le CAS, i.e. la transmettre aux autres composants de la chaîne.

Une fois le ArrayList construit, il faut le transformer en tableau statique et le copier dans une instance de FSArray à l'aide de la méthode copyFromArray(). Cette dernière prend en paramètre le tableau statique, l'index du tableau à partir duquel recopier le contenu, l'index dans le FSArray à partir duquel recopier les données et le nombre d'entrées à recopier. Dans le code ci-dessus, on recopie l'intégralité du tableau mETypes dès le début du FSArray.

Parcours

Une fois le tableau annoté dans le CAS, l'intérêt est de pouvoir y accéder par les autres composants de la chaîne. La récupération d'annotations de type FSArray n'est pas très différente d'un parcours classique.

  1. // On récupère l'index classique pour obtenir un itérateur
  2. AnnotationIndex arrIdx = (AnnotationIndex) jcas.getAnnotationIndex(MyComplexType.type);
  3. FSIterator arrIt = arrIdx.iterator();
  4. while( arrIt.hasNext() ) {
  5. // On récupère l'annotation complexe
  6. MyComplexType m = (MyComplexType) arrIt.next();
  7. // ... et surtout le FSArray qu'il contient
  8. FSArray marray = m.setMyComplexFeature();
  9. // Désormais il suffit de convertir l'annotation en Array java et l'utiliser telle quelle, par exemple :
  10. for(FeatureStructure elt: marray.toArray()) {
  11. MyEmbeddedType item = (MyEmbeddedType) elt;
  12. // amusez-vous avec ;)
  13. }
  14. }

Le parcours se fait donc plus ou moins de la même manière qu'une annotation classique, il faut toutefois penser à :

  1. Convertir le FSArray en un tableau Java classique
  2. Passer par l'intermédiaire d'instances de FeatureStructure lors du parcours du tableau si nécessaire avant de récupérer le type désiré (MyEmbeddedType dans le cas présent).
Retour au sommaire
 

Compilation de ressources autour d'Apache UIMA

0 vote
Par Fabien POULARD le 23/09/2009 à 02:09 Voir l'article

Un court billet qui compile différents pointeurs web concernant Apache UIMA.

Pointeurs "officiels"

  • Le site officiel d'Apache UIMA : http://incubator.apache.org/uima/
  • Archives de la liste de discussion destinée aux utilisateurs (inscription)
  • ... pour les développeurs (inscription)
  • La procédure de normalisation à l'OASIS

Documentation / Tutoriels

  • La documentation est plutôt exhaustive sur le site officiel
  • La programmation du colloque UIMA aux RMLL 2009 (les supports sont attachés aux articles, ainsi que les présentations du thème Libre en Sciences (pour lequel j'étais coordinateur :p) sur UIMA (ici et là)
  • Quelques tutoriels en français par L. Audibert

Communauté

  • La sandbox qui contient des composants UIMA stables et maintenus par la communauté
  • Dépôt de composants du Julie Lab et leur type system
  • Le dépôt de composants de l'Université de Carnegie Mellon
  • Le planet francophone
Retour au sommaire
 

Nettoyage et améliorations du cpeGui

0 vote
Par Fabien POULARD le 23/09/2009 à 01:53 Voir l'article

Depuis le temps que je peste après le manque d'ergonomie du cpeGui (org.apache.uima.tools.cpm.CpmFrame pour les intimes), j'ai voulu profiter d'un peu de temps durant une surveillance de TP pour jeter un coup d'œil au code et essayer d'obtenir quelque chose de plus intuitif. J'ai pu profiter des premiers pointeurs posés par mon collègue Matthieu pour m'introduire dans les méandre de la bête !

Au final j'ai à peu près tout cassé pour obtenir quelque chose d'assez proche de l'original en terme d'ergonomie... mais qui ne fonctionne plus !

Pour être un peu plus optimiste sur le travail accompli, j'ai éclaté le code du cpeGui en plusieurs composants ayant chacun un rôle particulier :

  • CpmPanel qui a pour unique objectif de charger les différents composer et créer une chaîne de traitement
  • RunnerPanel qui se charge de générer un ''CPE'' (''Collection Processing Engine'') et de contrôler son exécution. J'espère notamment pouvoir récupérer le contenu du Logger et obtenir une barre de progression plus précise.
  • ViewerPanel qui permet de visualiser la sortie de la chaîne de traitement. L'idée est de forcer l'exécution d'un XmiWriterCasConsumer dans un répertoire configurable et générer une fusion des Type System à partir des composants du CPE. En gros, pouvoir tout visualiser sans s'encombrer d'un paramétrage redondant.

L'explosion du code s'accompagne d'une migration du code vers un modèle MVC afin de pouvoir à la longue proposer des implémentation du GUI dans des bibliothèques un peu plus intéressantes que Swing :/ Ce serait notamment sympa d'avoir quelque chose qui s'intègre bien à un bureau Linux moderne (du GTK ou du Qt), surtout en ce qui concerne les boîtes de sélection des fichiers !

Les choix d'orientation sont les miens, mais je suis ouvert aux propositions ;)

En attendant voici un peu à quoi ça ressemble pour l'instant (attention les yeux !) :

uimaexplorergui-designer.jpg uimaexplorergui-runner.jpg uimaexplorergui-viewer.jpg

Pour l'instant il n'y a rien dans l'onglet Viewer et le Runner est très sommaire, mais ça devrait se compléter par la suite, le gros du code est présent, il ne reste plus qu'à tout interfacer :) En ce qui concerne la partie création de la chaîne, j'ai fait disparaître les CAS Consumers qui n'auront plus d'existence dans la prochaine release.

Retour au sommaire
« Page précédente Page suivante »
Produit par le BilboPlanet CSS - Xhtml valide Produit par le BilboPlanet Retour au début