mercredi 21 novembre 2012

Accéder et gérer des ressources externes au sein d'un UIMA Analysis Engine

Ce post s'appuie notamment sur la section 1.5.4 du guide utilisateur [1] (Managing and accessing External Resources).
Des exemples de descripteurs et de code Java d'analysis engine mettant en oeuvre l'accès et la gestion à des ressources externes sont fournis dans l'exemple 6 du tutoriel de uima-examples.

De quoi parle-t-on ?

On exploite régulièrement des ressources au sein de composants (analysis engine) de traitement de la langue. Il peut s'agir par exemples de dictionnaires que l'on accède en lecture ou bien d'objets que l'on accède en écriture (et lecture) pour stocker des informations sur le sujet d'analyse du moment. 
Concernant ce deuxième cas, cela peut par exemple consister en le nombre de fois où un élément des données (une instance) avec un label x est classée avec un label y, ce qui permettra par la suite de construire une matrice de contingence pour évaluer les résultats d'un processus de classification. On peut imaginer plusieurs instances d'un même traitement qui comptent en parallèle différents documents... Un autre exemple peut consister en compter les occurrences de formes candidates (e.g. ngrams) en vue de calculer ultérieurement le tf.idf de ces formes pour un extracteur de termes par exemple. Dans ces deux exemples le calcul ultérieur peut être envisagé au sein de la méthode collectionProcessComplete()d'un analysis engine. 
Pour l'exemple sur le comptage de la classification des instances on peut imaginer qu'un objet ayant un attribut de type Map String to Integer pourrait parfaitement nous convenir. Les clés string seraient "truePositive", "trueNegative", "falsePositive" et "falseNegative". Remarquons qu'une Map String to String pourrait très bien convenir aussi pour un dictionnaire qui associe une forme lexicale avec son lemme.

Qu'entend-t-on par gestion et accès à une ressource ?

La gestion d'une ressource est souvent plus "facile" et plus "rapide" à mettre en oeuvre lorsque la définition de celle-ci est au sein même du composant que l'on développe.  Elle nécessite généralement que la connaissance de l'API du langage de programmation (Java) et du modèle de données de la ressource (induit du format du dictionnaire ou bien du phénomène que l'on observe) pour la manipuler. 
Externaliser les ressources de type dictionnaire et spécifier le chemin (e.g. sur le système de fichier ou sur le web) pour y accéder par la définition de paramètres des composants, sont un début de bonne pratique. Il en coûte quelques lignes de codes supplémentaires (gestion de fichiers et du parcours du format de stockage).  C'est un premier pas pour faciliter la maintenance et le partage de de ressources en lecture entre plusieurs composants.
Le chemin peut même désigner une ressource publique ou un chemin relatif plus facilement portable.
Néanmoins cette solution ne répond pas au problème de multiplication des instances de ressources en mémoire (une pour chaque instance de composant qui souhaite accéder à la ressource) ni au besoin d'accès concurrent en écriture sur la ressource. Pour cela il faut se plonger davantage dans la maîtrise du langage de programmation et écrire encore "quelques" lignes de codes supplémentaires.
Par ailleurs il est souvent intéressant de découpler l'API d'accès d'un objet de son implémentation afin de ne pas rendre dépendant le composant à l'implémentation.

UIMA met à disposition ce qu'il appelle un RessourceManager pour permettre de 
  • partager la même instance d'un objet entre plusieurs composants (soit des composant distincts soit plusieurs instances d'un même composant)
  • éventuellement initialiser au démarrage les objets à partir du contenu d'un fichier pointé par une URL (ou éventuellement un chemin sur le système de fichiers local)
  • d'externaliser l'implémentation de l'API de manipulation de l'objet en en fournissant une de base pour traiter l'objet comme un flux et en offrant la possibilité d'en spécifier de plus ad hoc et d'en fournir une implémentation

Comment déclarer l'identifiant utilisé dans le code du composant pour désigner la ressource externe (on parle aussi de clé) et comment spécifier l'interface qui déclare les manipulations que l'on peut réaliser sur l'objet ?  

Pour ce faire, on utilise le "component descriptor editor", onglet "Resources", section de gauche "Resource Dependencies" (correspond à externalResourceDependency dans le code source).

La valeur de la clé permet au code du composant d'identifier cette ressource. Elle est par conséquent unique au niveau de ce composant. Par contre d'autres composants peuvent utiliser cette valeur pour signifier d'autres ressources.

La spécification d'une interface est optionnelle. Pour rappel l'interface permet de dissocier l'implémentation de la manipulation de la ressource de son interface afin de pouvoir faire évoluer indépendamment le code du composant et celui de la gestion de la ressource. Sans nom d'interface spécifié, il sera possible d'accéder directement au contenu de la ressource par le biais d'une ImputStream (obtenu via une URL (éventuellement un chemin sur le système de fichiers local)). 
Cela signifie que le parsing de la ressource ne sera pas externalisé. Mais parfois si le format est simple, il n'est pas utile de définir une interface particulière.

Comment accède t on à la ressource au sein du code du composant ?

L'accès à la ressource ne peut que se faire si on a lié (binding) la clé que l'on a déclaré avec une définition de ressources externes, laquelle spécifiera l'URL pour accéder à la ressource. Cette opération sera vue ultérieurement.

Au sein du code on accède à la ressource à l'initialisation de l'analysis engine, c'est-à-dire que l'on accède à la ressource via le UimaContext fourni disponible au sein de la méthode initialize.

Lorsqu'aucune interface n'est définie lors de la déclaration de la clé désignant la ressource (onglet "Ressources" section "Resource Dependencies" ), on peut accéder à la ressource comme cela :
InputStream stream = getContext().getResourceAsStream("MaCleDesignantLaRessource");
ou bien comme cela si l'on souhaite déterminer la localisation du fichier ressource : 
URI uri = getContext().getResourceURI("MaCleDesignantLaRessource");

Lorsqu'une interface est définie on utilisera la méthode getResourceObject 
qui retourne un objet qui implémentera l'interface déclarée dans la section "Resource Dependencies" (onglet "Ressources" ) :
MyResourceTypeImpl mMyResourceTypeImpl = (MyResourceType)getContext().getResourceObject("MaCleDesignantLaRessource");

Comment définir une nouvelle ressource externe ?

Globalement une définition de ressource consiste à
  1. déclarer un nom de ressource pour l'identifier ultérieurement (afin de la lier avec des clés qui permettent aux composants d'identifier une ressource particulière au sein du code)
  2. indiquer une url pour trouver la ressource 
  3. et optionnellement spécifier une implémentation de l'interface pour accéder à la ressource lorsqu'une interface a été déclarée
La définition s'opère à l'aide du "component descriptor editor", onglet "Resources", section de gauche "Resources needs, Definition and Binding" (correspond à resourceManagerConfiguration dans le code source).

Indiquer dans le champ name (e.g. SharedResourceName) un nom servant à identifier cette définition de ressource. Lorsque vous lierait la ressource avec une clé utilisée par le code du composant, le nom sera automatiquement repris.

Indiquer dans le premier champ URL un chemin valide vers la ressource à charger. Si la ressource est locale indiquer un chemin relatif plutôt qu'un chemin absolu. Il n'y a pas de lieu de stockage spécifique requis pour une ressource. 
Personnellement je les place dans le répertoire resources de mon projet courant et j'ajoute le répertoire dans mon build path afin que les chemins relatifs soient accessibles dans celui-ci.

Dans le cas où votre ressource n'est pas de type dictionnaire et qu'il s'agit d'un objet partagé créé au fur et à mesure de l'analyse des documents traités, il faut tout de même spécifier un chemin vers une ressource existante. Créer par exemple un fichier vide defaultSharedResource.tmp dans un sous répertoire (external) (package) du répertoire resources du projet (n'oubliez pas d'ajouter ce répertoire dans le build path). Le chemin sera alors external/defaultSharedResource.tmp

Lorsqu'une interface a été spécifiée lors de la déclaration de clé ("Resource Dependencies" ), c'est sous cette section ("Resources needs, Definition and Binding") que l'on déclare la classe qui implémente l'interface.

If no implementation class is specified, then the getResource method returns a DataResource object, from which each annotator instance can obtain their own (non-shared) input stream; so threading is not an issue in this case.

Comment associer une clé à une définition d'une ressource externe ?

A l'aide du "component descriptor editor", onglet "Resources", 
  1. cliquer ensuite la clé que vous souhaitez dans la section de droite  ("Resource Dependencies" )
  2. cliquer sur la ressource définie que vous souhaitez dans la section de gauche ("Resources needs, Definition and Binding")
  3. puis cliquer sur "bind"

Lorsque l'on définit une interface d'accès à la ressource, que doit contenir la classe qui l'implémente ?

La classe qui implémenter l'interface de manipulation de la ressource doit implémenter aussi l'interface org.apache.uima.resource.SharedResourceObject. Concrètement cela signifie que l'on doit surcharger la méthode load(DataResource data) qui permet d'avoir accès à la ressource et qui va se charger de la parser pour initialiser l'instance de l'objet souhaité à retourner.
Cela doit globalement ressembler à cela
public class MyResourceTypeImpl implements MyResourceType_interface, SharedResourceObject {

public MyResourceTypeImpl() {
  super();
}

@Override
public void load(DataResource data) throws ResourceInitializationException {
}

}
Si il n'y a pas de ressources à charger, il suffit de laisser vide le code de la méthode.

Pour être instancié par le framework, l'implémentation doit être public et doit avoir un 0-argument constructor.

Comment partager une ressource entre plusieurs composants (ou comment bénéficier d'une seule définition de la ressource) ?


Les descripteurs de chaque composant doivent contenir la déclaration d'une dépendance pour la ressource partagée avec une valeur de clé qui leur est propre.
Seul l'un des composants spécifie une définition de la ressource (en donnant un nom et une URL pour accéder à la ressource). Ce composant là peut lier cette ressource à sa clé. 
Il n'est pas possible d'opérer le binding au sein des descripteurs des autres composants. Si la ressource est requise pour ces composants, ceux-ci ne pourront fonctionner normalement.

Pour partager la ressource il faut utiliser un descripteur aggregate qui va réunir les descripteurs de différents composants. Dans la section Resources, celui-ci spécifiera le binding entre la ressource souhaitée et les clefs affichés des composants.

Qu'en est il de la sûreté d'accès à la ressource quand celle-ci est partagée ?

La documentation indique que "If an implementation class is specified in the external resource, only one instance of that implementation class is created for a given binding, and is shared among all annotators. Because of this, the implementation of that shared instance must be written to be thread-safe - that is, to operate correctly when called at arbitrary times by multiple threads."

Le contrôle d'accès à des méthodes sensibles peut être une solution pour permettre un accès concurrentiel en écriture à la ressource.
public synchronized int increment() {
        return nextValue++;
    }

If no implementation class is specified, then the getResource method returns a DataResource object, from which each annotator instance can obtain their own (non-shared) input stream; so threading is not an issue in this case.

mardi 25 septembre 2012

Génération et correction automatique de QCM

Auto Multiple Choice est un ensemble d'utilitaires permettant de créer, gérer et corriger automatiquement des questionnaires à choix multiples (QCM). C'est un logiciel libre distribué sous la licence GPLv2+.


http://home.gna.org/auto-qcm/



Les sujets de QCM sont préparés par LaTeX, ce qui permet d'y écrire (éventuellement) toutes sortes de formules mathématiques.
AMC permet de changer de manière aléatoire l'ordre des réponses à l'intérieur de chaque question, ainsi que l'ordre des questions, de sorte que chaque sujet se présente différemment. Il est ainsi plus difficile pour les étudiants de copier sur leurs voisins...
À la suite de l'examen, les copies scannées peuvent être corrigées de manière automatique par AMC, grâce à une reconnaissance optique de marques (OMR). Si l'on ne dispose pas de scanner, ou pour les copies pour lesquelles la correction automatique aurait mal fonctionné, une correction manuelle assistée est aussi possible : il suffit de cliquer à la souris sur les cases cochées par chaque étudiant sur la reproduction du sujet affichée à l'écran.
Il est possible de choisir le barème par défaut, ou de fixer un barème de manière fine pour chaque question du QCM. AMC fabrique un fichier OpenDocument rassemblant les notes de tous les étudiants, directement utilisable par LibreOffice.org ou OpenOffice.org.

Logiciel de génération d'emplois du temps open source


FET is open source free software for automatically scheduling the timetable of a school, high-school or university. It uses a fast and efficient timetabling algorithm. It is licensed under GNU GPL.
Usually, FET is able to solve a complicated timetable in maximum 5-20 minutes. For simpler timetables, it may take a shorter time, under 5 minutes (in some cases, a matter of seconds). For extremely difficult timetables, it may take a longer time, a matter of hours.

http://lalescu.ro/liviu/fet/




vendredi 27 juillet 2012

Example uima-connectors CAS to CSV

Using uima-connectors to serialize some CAS annotations into CSV-formatted files.
  1. This is performed in two steps: First, create a text view formatted in CSV with the information you wish serialize. 
  2. Second, write the views on the file system. The second step is optional, you do whatever you want with your view.


The first step is performed by the CAS2CSVAE. Each line of the '_CSVView', created at the first step, will contain some feature values of n annotation whose type have been configured via parameter. Columns of the lines contain the values of the features of the annotation type. They are also configured via parameters. 
The second step is performed by the ViewWriterAE. This AE requires the presence of org.apache.uima.examples.SourceDocumentInformation annotations in each CAS which results from using the FileSystemCollectionReader or using any tools from the apache uima SDK (like the DocumentAnalyzer). This is used to name the exported views in the file system.


Requirement
uima-connectors library is available here http://code.google.com/p/uima-connectors.
It requires the uima-common lib http://code.google.com/p/uima-common/.


Example of use
In the example eclipse project you will see how to turn TokenAnnotations with coveredText, posTag, stem which result from apache uima  addons analysis, into CSV formatted files.
See the descriptor desc/xample-apacheAddons-uimaConnectors/example-apacheAddons-uimaConnectors-CAS2CSV-ViewWriter-AAE.xml
In particular have a look at the aggregate and the parameter settings tabs.
The example project assumes you have installed the apache-uima and apache-uima-addons binaries. Check the build path before using it.

mercredi 20 juin 2012

Extraire le texte de documents HTML en créant des annotations à la place des balises

Traiter du SGML (e.g. HTML) ou du XML (i.e. SGML davantage contraint) est une activité commune dans nos chaînes de traitement TAL (Traitement Automatique des Langues). Par ailleurs, souvent les traitements que nous souhaitons réaliser (segmentation en phrases, en mots, étiquetage morpho-syntaxique, reconnaissance d'entités nommées...) ne fonctionnent que sur du texte simple (plain text).

1. Tika MarkupAnnotator vs. uima-connectors XML2CAS

A ma connaissance, il y a au moins deux composants UIMA "librement" disponibles pour 
  1. extraire le texte d'un document SGML sans en modifier ses offsets 
  2. transformer les balises d'un document SGML en annotations UIMA au dessus des zones de texte couvertes.
Il s'agit du Tika MarkupAnnotator [1] et du uima-connectors XML2CAS [3]. 
  • Pour chacun d'eux l'on peut spécifier la vue à analyser et la vue dans laquelle il faut produire le texte.
  • Chacun d'eux produit des annotations correspondantes aux balises. Le système de types est évidement différent dans sa forme même si l'on retrouve globalement dans le fond la même information. 
  • XML2CAS travaille seulement avec de l'XML et vous autorise à spécifier les noms des éléments que vous voulez transformer en annotations afin de restreindre la taille du CAS
  • MarkupAnnotator offre la possibilité de traiter de l'XML mal formée (i.e. du SGML et en particulier HTML). Cela relativement simplement en ajoutant la bibliothèque du TagSoup parser dans le classpath [5].
Le premier est disponible dans les Annotator addons de Apache UIMA [2] et le second requiert de récupérer la bibliothèque uima-common pour fonctionner (au final [3] et [4]).


2. Quelques détails sur mon test
Personnellement j'ai testé les deux au sein d'un projet java Eclipse en déclarant les dépendances  suivantes dans mon classpath (en plus de celles de UIMA):
  • UIMA_HOME/addons/annotator/TikaAnnotator/lib/tika-core-0.7.jar
  • UIMA_HOME/addons/annotator/TikaAnnotator/lib/tika-parsers-0.7.jar
  • UIMA_HOME/addons/annotator/TikaAnnotator/lib/uima-an-tika.jar
  • chemin/vers/votre/lib/uima-common-v120111.jar
  • chemin/vers/votre/lib/uima-connectors-v111205.jar
  • chemin/vers/votre/lib/tagsoup-1.2.1.jar
J'ai ajouté la UIMA nature au projet et ajouté le répertoire desc aux build path pour me faciliter la tâche. J'ai créé un descripteur d'Analysis Engine que j'ai changé en aggregate afin de rajouter, les composants que je souhaitais tester, dans ma pipeline (section aggregate du descripteur) : 
MarkupAnnotator et connectors.xml.XML2CASAE.
J'ai surchagé les paramètres des deux composants (section parameter) et n'ai pas oublié de les configurer (section parameter settings). 
Puis j'ai déclaré les types en sortie (section capabilities).
Enfin j'ai lancé ma chaîne à l'aide du Document Analyser. Lorsque j'ai testé sur du HTML je n'avais pas retiré le composant XML2CAS de ma pipeline.



jeudi 12 avril 2012

Sujet de thèse en Traitement Automatique des Langues et Multilinguisme

English version below.

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

Sujet de thèse en Traitement Automatique des Langues et Multilinguisme

L'équipe du Traitement Automatique du Langage Naturel (TALN) du Laboratoire
Informatique de Nantes Atlantique (LINA UMR CNRS 6241) à l'Université de Nantes
propose un sujet de thèse en Informatique dans les domaines du Traitement
Automatique des Langues et du Multilinguisme.

*Titre:*
Analyse des structures discursives des textes et alignement de terminologies
multilingues en corpus comparables ; pour une modélisation discursive de la
notion de contexte.

*Résumé : *
La traduction automatique est l'une des activités de recherche les plus
ambitieuses de notre temps. Ce travail de thèse propose de s'attaquer à l'un de
ses enjeux, à savoir l'"alignement de terminologies multilingues" en corpus
comparables, et ce en explorant de nouvelles méthodes de mise en correspondance
des termes, à savoir à l'aide d'"analyses des structures discursives des
textes". L'approche état de l'art consiste à établir une mise en correspondance
des termes en mesurant la similarité de leurs contextes d'apparition à l'aide
de dictionnaires bilingues préexistants. Les problèmes fondamentaux de cette
approche sont qu'elle repose sur une modélisation très pauvre du contexte
d'apparition d'un terme (un sac de mots apparaissant autour des termes
analysés) et qu'elle présuppose l'existence de ressources lexicales bilingues
pour être réalisée.
Ce travail a pour objectif d'expérimenter des contextes de termes définis sur
la base de résultats d'analyses du discours ainsi que réfléchir à la définition
d'une notion de contexte discursif plus en adéquation avec la tâche.
Ce sujet émerge dans la continuité du projet européen TTC et du projet ANR
MeTRICC dont l'équipe TALN assure les coordinations.

*Mots clefs :*
Traduction, Alignement de terminologies multilingues, Analyse et modélisation
des structures du discours, Corpus comparables

*Profil et compétences recherchés: *
M2 Recherche informatique ou école d'ingénieurs
Bon niveau en anglais
Bonnes notions en apprentissage automatique
Bonnes connaissances en programmation Java/Python
Affinités avec le logiciel libre et le développement collaboratif

*Procédure de candidature* :
La date butoir de réception des candidatures est  le 20 Avril 2012 mais
la position restera ouverte jusqu'à ce qu'elle soit attribuée.
La thèse démarrera en Octobre 2012 et sera financée par une allocation ministérielle.
Les candidats intéressés sont invités à prendre contact le plus tôt possible
et à envoyer les informations suivantes : une lettre de motivation incluant votre
positionnement par rapport aux compétences attendues, un CV, un relevé
de notes avec classement au Master (au moins pour la période écoulée), un
lien vers un site web présentant le programme de votre master et des lettres
de recommandations de vos encadrants scientifiques.
Cette thèse pourra être précédée d'un stage de master recherche financé
sur le même thème. Prendre contact.

*Contact : *
Nicolas Hernandez et Emmanuel Morin (prenom.nom à univ-nantes.fr)

*Plus d'information sur le sujet de thèse :*
http://www.edstim.fr/these/sujets-de-these/informatique
http://e.nicolas.hernandez.free.fr/pub/rec/12 




-------------------------------------------------------------------------------
Researcher  position available: PhD in Natural Language Processing

The University of Nantes (West coast of France) offers an opening for a 3-year
PhD position at the LINA Computer Sciences Laboratory in the NLP Team (TALN).

LINA TALN leads research in several NLP domains such as term extraction,
syntactic and semantic analysis, and develops several applications (e.g.
machine translation, opinion mining, plagiarism detection).
LINA TALN participates in various projects founded by regional, national
and European sources.
http://www.lina.univ-nantes.fr/

*Subject:*
Discourse structure analysis and multilingual terminology alignment from comparable corpora.
Toward a discourse definition of the notion of context

*Brief description: *
Multilingual terminology alignment from comparable corpora is one of the major
issue of the automatic translation problem. To tackle this issue, the baseline
approach proposes to align terms whose contexts are considered as similar
thanks to bilingual dictionaries. This approach presents some drawbacks since
the context model is quite simple (a bag of words occurring around the
considered term) and because it requires external resources for performing.
The current study aims at exploring a new approach for building term contexts.
The idea is to use a more linguistically inspired approach: in particular to
use discourse analysis both for providing semantically delimited text area
around term occurrences and rhetorically dependent utterances in relation to
the utterance where a term occurs. The work will start by trying out
state-of-art discourse analysis methods, then it will go into the definition of
a discourse context notion related to the task in depth. This research will
pursue the works accomplished in the national and European projects MeTRICC
and TTC.

*Topics :*
Machine translation, Multilingual terminology alignment, Discourse analysis,
Comparable corpora

*Qualifications:
The ideal candidate would have:
- (or soon receive) a Master degree in computer science/engineering
- a background in NLP and/or machine learning
- programming skills in JAVA/Python
- experience in open source development (appreciated)
- good English proficiency and ability to learn French (if appropriate)

*Application procedure:*
The application deadline is April 20, 2012 , but consideration of candidates
will continue until the position is filled. It is expected to start on October 2012.
Candidates interested in the position are asked to contact Nicolas Hernandez
and Emmanuel Morin (firstname.lastname at univ-nantes.fr) with the following
documents: A letter of motivation outlining your interest in the specific project,
a curriculum vitae, at least two recommendation letters from a senior
researcher/professor who can judge your potential as a future PhD student.

The program will be funded by a grant from the French government.
Median annual earnings are between 20,000 and 24,000 Euros.

*More information on:*
http://www.edstim.fr/these/sujets-de-these/informatique
http://e.nicolas.hernandez.free.fr/pub/rec/12 

Master Informatique spécialité ATAL : Apprentissage et Traitement Automatique de la Langue

A la rentrée 2012/2013 ouvrira à l'université de Nantes un Master Informatique spécialité ATAL (Apprentissage et Traitement Automatique de la Langue).

Le Master ATAL viser à former des spécialistes de l'apprentissage automatique aux particularités des applications informatiques relevant du traitement automatique de la langue (TAL). Il s'agit notamment de pouvoir mettre en oeuvre des nouvelles applications prenant en compte des masses de données complexes et hétérogènes.

La formation se veut pratique et fondamentale. Le but est de former en deux ans des étudiants issus de filières informatiques à un ensemble de techniques d'apprentissage automatique et de traitement automatique de la langue qui sont au coeur des applications en ingénierie des langues (comme en recherche d'information, en aide à la traduction, en analyse d'opinions).

La formation s'inscrit dans une dynamique internationale en s'appuyant sur des personnalités scientifiques reconnues dans leurs domaines de compétences.

Plus d'information sur atal.univ-nantes.fr