Combinaison de moteurs de résolution de requêtes sur annotations

Objectifs

Augmenter les fonctionnalités de TXM en combinant des moteurs de résolution de requêtes sur annotations.

Chaque moteur travaille sur son propre système d'annotation avec son propre langage de requête et le résultat est obtenu par combinaison des contraintes de sélection retournées par chaque moteur.

L'intérêt pour l'utilisateur est de pouvoir utiliser les forces (potentiel, ergonomie) de chaque langage de requêtes et du moteur associé. Par exemple :

  • CQP / CQL : rapidité d'extraction de propriétés de séquences de mots
  • XQuery : finesse d'expression de contraintes sur les balises XML source ou pivot (gestion min/maj, accents, etc.), langage XPath de navigation dans l'arbre DOM
  • TIGERSearch : langage de requête adapté à la syntaxe, assistant graphique de construction de requête

Moteurs intégrables : TIGERSearch, XSLT, XQuery, SPARQL, SQL

Fonctionnalités concernées, potentiellement toutes les fonctionnalités utilisant déjà CQL :

  • Index de sous-corpus et partition
  • Concordance
  • etc.

En amont, les annotations se trouvant dans les sources doivent être rapprochées au moment d'un import (il peut y avoir plusieurs import si on 'ajoute' par exemple des annotations syntaxiques TS à un corpus).

En aval, les contraintes de sélection de positions (tokens) servent à unifier les sélections des différents moteurs.

Si une requête de fait pas référence explicitement à des occurrences, il faut calculer les occurrences sous-jacentes au résultat retourné. Par exemple si on fait une requête XQuery pour construire un sous-corpus à partir de contraintes combinées sur différents niveaux de structures, il faut calculer quelles occurrences se trouvant dans les structures sélectionnées. Si ce n'est pas possible, il faudra que l'utilisateur exprime obligatoirement une requête se résolvant à des occurrences pour que le mécanisme fonctionne. Ceci peut être un premier mode de fonctionnement avant d'étendre au calcul automatique d'occurrences sous-jacentes.

Solution

On s'appuie sur TIGERSearch (TS) pour démontrer la faisabilité.

On utilise une stratégie de couplage basée sur les tokens. Soit :

  • couplage A) les tokens sont strictement identiques (même relation d'ordre et nombre)
  • couplage B) les tokens du moteur supplémentaire forment un sous-ensemble de ceux de CQP et partagent leurs ids.

Pour un corpus SRCMF, on utilise le couplage B.

On utilise le moteur supplémentaire comme système de contraintes de sélection qui s'additionnent à celles de CQP.

La requête TS doit aboutir à des terminaux.

Ce développement est réalisé dans un nouveau chantier “SRCMF” qui contient :

  • V1
    • une extension TIGERSearch
      • commande TIGERSearch : affiche les arbres TIGERSearch contenant les matchs d'une requête TIGERSearch (cette fonctionnalité est à l'origine de l'extension TIGERSearch et a été développée avant ce chantier dans le cadre du rapatriement de cette fonctionnalité depuis le portail TXM)
      • commande “Index TS”
      • commande “Concordance TS” (KNIC 1)
    • un module d'import : SRCMF 2
    • voir si le tronc commun est concerné
  • V2
    • une extension TIGERSearch
    • un module d'import : SRCMF 2
    • tronc commun : l'index et la concordance peuvent gérer de nouveaux moteurs en fonction du corpus utilisé.
      • point d'extension : moteur, champs requête

Import

Architecture cible : le corpus TIGERSearch d'un corpus binaire TXM se trouve dans le dossier “tiger”.

Générique : import XML-TS

Prend un fichier TIGER XML, créé un corpus TIGERSearch et un corpus CQP basé sur les tokens du corpus TIGERSearch → couplage A

Il s'agit de l'automatisation de la procédure d'import décrite ici : https://groupes.renater.fr/wiki/txm-users/public/extensions_alpha#tigersearch.

Dual : import SRCMF-notabene

Prend 1 dossier XML-TXM et 1 dossier XML-TS issu d'une conversion d'annotations SRCMF depuis NotaBene, fait un corpus CQP avec les fichiers XML-TXM et un corpus TIGERSearch avec le fichier du dossier XML-TS. Et fait tout un tas de transformations.

Les 2 corpus sont hébergés dans un corpus binaire TXM.

Dual : import SRCMF 2

Prend 1 dossier XML-TXM et 1 dossier XML-TS, fait un corpus CQP avec les fichiers XML-TXM et un corpus TIGERSearch avec le fichier du dossier XML-TS.

Attention : il y a une relation extrêmement forte entre les fichiers sources XML-TXM et XML-TS : les fichiers XML-TXM et XML-TS doivent provenir de Stuttgart (TR).

  • Les métadonnées des textes sont prises dans le fichier metadata.csv.
  • L'ordre des textes est défini par la metadonnée “datecompo”

Les 2 corpus sont hébergés dans un corpus binaire TXM.

Charger

Équiper un corpus TXM d'un corpus TIGERSearch :

  • à la main : en copiant les fichiers dans le binaire TXM
  • à l'aide d'une commande “Lier/Ajouter/Charger” lancé sur un corpus sélectionné dans la vue Corpus et une archive d'un corpus TIGERSearch.

UI

Pour pouvoir combiner l'usage simultané de plusieurs moteurs, on peut étendre les UI actuelles. Pour la zone de saisie de requête CQL actuelle, par exemple dans l'Index, cela peut donner :
UI de combinaison de moteurs

  • A) la zone de saisie de base, composée :
    • de la désignation du moteur de résolution concerné
    • de la zone de saisie
    • de contrôles de changement de taille de la zone de saisie
    • d'ajout de requête supplémentaire
  • B) on peut choisir à gauche le moteur de résolution correspondant à la requête saisie. Dans cet exemple on est passé du moteur CQP au moteur XQuery
  • C) on peut augmenter ou réduire la taille de la zone de saisie. Certains langages de requêtes ont besoin d'espace pour la saisie
  • D) on ajoute des requêtes pour combiner avec d'autres moteurs ou avec le même moteur avec un bouton [+]. Par défaut les requêtes sont combinées (&) mais peuvent être des alternatives (|). Un bouton [-] permet de supprimer une requête.

Remarques :

  • la possibilité D) permet d'étendre l'Index à n requêtes CQL → il faut définir les fonctionnalités correspondantes, notamment en utilisant l'expression de l'alternative (|)
  • l'interface d'ajout de requêtes ressemble à celle de la Progression, mais pour cette dernière il faut une double interface d'ajout (ajout de requêtes + ajout de requêtes par moteur)
  • l'interface doit bien sûr comprendre le bouton d'accès à l'assistant de saisie de chaque moteur pour une requête donnée

Index

Étant donnée la liste des terminaux matchés par TS, on fait l'intersection avec la liste des matchs du sous-corpus CQP sur lequel est construit l'index.

requête TS → liste d'identifiants de mots → liste de positions CQP → intersection CQP/Java

Une requête TS retourne une liste d'identifiants de mots (propriété de mot TS “id”).

V1

On augmente l'extension TIGERSearch avec une version modifiée de la commande Index qui s'ouvre avec un champ de requête TIGERSearch à la place du champ CQL habituel (baguette + champ texte).

Pour croiser des contraintes CQL et TS, il faut utiliser des sous-corpus.

Les projections disponibles dans l'index ne sont que celles de CQP.

L'utilisateur ne doit nommer dans la requête qu'un (et un seul) nœud avec la variable #@ (ou #pivot) qui sera à la base du couplage :

  • si le nœud du match est un terminal (token) on l'utilise
  • si le nœud du match est un non-terminal, on utilise tous les terminaux qu'il domine. La séquence des terminaux correspondante n'est pas construite. (il faut donc, si nécessaire, faire attention aux décomptes de tokens dans l'Index dans les cas de séquences)

V2

Dans l'éditeur d'Index on ajoute des champs de recherche supplémentaires qui vont se combiner (intersection des matchs) en plus de l'intersection avec le sous-corpus à la base de l'Index : (CQL + TIGERSearch QL) + CQL sous-corpus.
→ (ce qui permet d'éviter d'avoir à construire des sous-corpus à durée de vie limitée)

V3

On ajoute la coloration TIGERSearch.

On donne accès à l'assistant TIGERSearch.

Les projections de propriétés d'objets TS (terminaux et non-terminaux) sont disponibles et mixables.

Concordances

Les principes de l'Index s'appliquent à la concordance.

V1

Correspond à KNIC 1 (concordance pivot).

V2

On peut marquer les mots non dominés de la séquence contiguë.

V3

Formes de retour au texte possibles :

  • retour dans une vue synoptique verticale qui comprend :
    • l'édition des arbres syntaxiques contenant les mots de la page d'édition (zoom + pan).
    • la page d'édition “default”
  • la page d'édition “default”
  • l'édition des arbres syntaxiques contenant les mots de la page d'édition (zoom + pan).

TIGERSearch

Recherche de noeuds syntaxiques (terminaux ou non-terminaux) avec l'aide du moteur de résolution de requêtes syntaxiques TIGERSearch : https://groupes.renater.fr/wiki/txm-users/public/extensions_alpha#tigersearch

XSLT

La plateforme TXM utilise le moteur XSLT 2 Saxon notamment dans les modules d'import XML et la macro ApplyXSL.

L'idée est d'utiliser la transformation de la représentation XML pivot des textes d'un corpus en une liste d'id des mots des textes correspondants à une extraction donnée comme “moteur de recherche” : faisant correspondre une “requête” (une feuille XSL) à une “liste de matches” (de type CQP) interfaçable ensuite avec les commandes prenant en entrée des listes de matches CQP habituellement.

La requête est soit :

  • V1) un fichier XSL complet donné en paramètre ou son contenu édité dans un éditeur XML de TXM ;
  • V2) un bout de la XSL saisi dans un champ de paramètre de macro ou de commande. La XSL est finalisée avant l'appel de la XSL ;
  • V3) un bout de la XSL utilisant des fonctions XSL et des éléments de syntaxe XQuery (peut-être plus concis qu'une série de templates comme ci-dessus) saisi dans un champ de paramètre de macro ou de commande. La XSL est finalisée avant l'appel de la XSL ;

La requête (XSL) s'applique soit :

  • V1) à un fichier XML-TEI TXM de corpus binaire (contenant toutes les structures TEI d'origine + les mots avec @id et annotés) ;
  • V2) à un répertoire 'txm' contenant les fichiers

La XSL retourne la liste de tous les identifiants de mots correspondant à la requête d'extraction :

  • soit sous forme XML : <matches><match><wRef id=“ID1”/><wRef id=“ID2”/>…</match>…<matches>
  • soit sous forme TXT : un ID de mot par ligne

Ensuite le contexte d'appel (une macro pour l'instant) transforme cette liste en requête CQL utilisant des ID ou des positions de mots (et donc avant il faut calculer la liste des matchs CQP équivalente ([start, end], [start, end]…), pour pouvoir faire ensuite une Concordance ou un Index.

Dans une version ultérieure on verra comment pouvoir calculer la Concordance ou l'Index dans la foulée (voir aussi les exemples ci-dessous pour le cas TIGERSearch).

On commence par faire une macro prototype appelée XSL2CQL :

  • prenant comme paramètres :
    • une sélection de corpus dans la vue Corpus ;
    • un bout de requête XSL ou le chemin vers une feuille XSL complète
  • retournant une CQL de sélection des mots dont la liste des IDs est retournée par la XSL

XQuery

La plateforme TXM utilise le moteur XQuery Saxon.

Voici un exemple de script XQuery (getNOM.xq) retournant tous les IDs de mots dont le frpos vaut 'NOM', par exemple dans le corpus TDM80J. Le contexte d'appel du script doit faire en sorte que le répertoire courant soit le répertoire binaire du corpus, de sorte à ce que le chemin 'txm' de l'URI corresponde au répertoire des fichiers XML-TXM du corpus requêté (sinon on peut mettre le chemin absolu dans le paramètre URI de la fonction fn:collection du script). Le script parcourt tous les fichiers '.xml' qui se trouvent dans le répertoire 'txm' :

<matches>
  { 
    for $t in fn:collection(file:txm?select=*.xml)
      for $w in $t//tei:w
        let $pos := $w/txm:ana[@type="#frpos"]/text()
        where $pos = "NOM"
        return <match>{$w/@id}</match>
  }
</matches>

Étape 1

Objectif

On commence par faire une macro ApplyXQuery qui prend en paramètres :

  • une sélection de corpus dans la vue Corpus
  • une sélection de chemin de script .xq, comme celui ci-dessus (il faudra penser à créer un répertoire 'xq' à côté du répertoire 'xsl' dans le répertoire $TXMHOME)
  • éventuellement le chemin d'un fichier de sortie

Et qui affiche l'output dans la console ou dans le fichier de sortie.

Solution

Étape 2

S'appuyer sur les résultats de l'étape 1 pour construire une requête CQL à partir de matches de mots TXM en XQuery.

Recette

TIGERSearch

V1

  • Réserver un paquet de madeleines pour se prémunir de toute fringale occasionnée par l'exécution de cette recette
  • Lancer une première fois TXM pour finir l'installation. Puis re-lancer TXM.
  • Installer la mise à jour TXM 0.7.8 (201604211410)
    • dans TXM, utiliser le menu “Fichier / Ajouter une extension tierce”
    • Cliquer sur Ajouter…
      • Coller dans le champ URL l'adresse suivante :
        • http://textometrie.ens-lyon.fr/dist/srcmf
      • Cliquer sur OK
    • Cliquer sur Annuler
  • Utiliser le menu Fichier / Vérifier les mises à jour
    • La mise à jour TXM (201604211410) s'installe (valider tous les choix proposés)

Récupération des corpus à utiliser pour la recette

  • Télécharger le corpus binaire depuis le disque partagé (accès restreint) :
  • Charger le corpus dans TXM

Index TIGERSearch : commande TSIndex

  • Sélectionner le corpus SRCMFMADRID
    • Sélectionner la commande TSIndex (tete de tigre + AZ)
    • Rentrer la requête dans le champ :
      #pivot:[word=/[Cc][ou]m?me?/ & pos="CONsub"]
      • la requête doit retourner 745 résultats (t)
    • Rentrer la requête dans le champ :
      [headpos="VERcjg" & cat="Circ"] >R #n:[cat="RelNC"] & #n >L #pivot
      • la requête doit retourner 3361 résultats (t)
  • Faire le sous-corpus du discours direct : q
    • Mode avancé, requête
      [q] expand to q
    • Sélectionner le sous-corpus q
    • Sélectionner la commande TSIndex (tete de tigre + AZ)
    • Rentrer la requête dans le champ :
      #pivot:[word=/[Cc][ou]m?me?/ & pos="CONsub"] 
      • la requête doit retourner 189 résultats (t)
    • Rentrer la requête dans le champ :
      [headpos="VERcjg" & cat="Circ"] >R #n:[cat="RelNC"] & #n >L #pivot
      • la requête doit retourner 1422 résultats (t)
  • Faire le sous-corpus du discours non direct : nonq
    • Mode avancé, requête
      [!q]
    • Sélectionner le sous-corpus nonq
    • Sélectionner la commande TSIndex (tete de tigre + AZ)
    • Rentrer la requête dans le champ :
      #pivot:[word=/[Cc][ou]m?me?/ & pos="CONsub"]
      • la requête doit retourner 556 résultats (t)
    • Rentrer la requête dans le champ :
      [headpos="VERcjg" & cat="Circ"] >R #n:[cat="RelNC"] & #n >L #pivot
      • la requête doit retourner 1939 résultats (t)

Les décomptes doivent correspondre : la somme des fréquences des indexes q et nonq est égale aux fréquences de l'index de SRCMFMADRID.

L'ensemble des requêtes nécessaires est présenté dans ce google doc.

le retour à la concordance ne fonctionne pas :(

des div et des q ont été perdus lors de l'import (deep neesting)

Recette automatique

Depuis TXM, après avoir charger le corpus SRCMFMADRID et l'avoir sélectionner. Sélectionner la commande “TS Index - Recette 1” depuis le menu principal “Recettes”.

V2

Comparaison de TSIndex entre 2 corpus CQP+TIGERSearch.

  1. Charger le corpus SRCMFMADRID1 datant du xxxxx
  2. Charger le corpus SRCMFMADRID2 datant du yyyyy
  3. Sélectionner les 2 corpus dans la vue Corpus
  4. Sélectionner la commande “TSIndex - Recette 2” dans le menu principal “Recettes”
  5. La commande produit 2 TSIndex avec la requête
    #pivot:[word=/[Cc][ou]m?me?/ & pos="CONsub"] 
  6. Elle produit aussi un comparatif dans la console sous la forme d'un tableau TSV avec 3 colonnes :
    1. ID : les identifiants de mots qui ont matchés la requête dans les 2 corpus
    2. SRCMFMADRID1 : 1 ou 0. avec 1=présence et 0=absence
    3. SRCMFMADRID2 : 1 ou 0. avec 1=présence et 0=absence

XSLT

V0

On crée :

  • la macro XSL2CQL
  • une XSL type appelée 'matches-tdm80j.xsl' pour le corpus TDM80J qui sélectionne 3 séquences : 1-5, 8 et 11-12

En cochant 'debug' on peut observer le résultat de la XSL dans 'results' :

<?xml version="1.0" encoding="UTF-8"?>
<matches>
    <match>
        <wRef id="w_tdm80j_1"/>
        <wRef id="w_tdm80j_2"/>
        <wRef id="w_tdm80j_3"/>
        <wRef id="w_tdm80j_4"/>
        <wRef id="w_tdm80j_5"/>
    </match>
    <match>
        <wRef id="w_tdm80j_8"/>
    </match>
    <match>
        <wRef id="w_tdm80j_11"/>
        <wRef id="w_tdm80j_12"/>
    </match>
</matches>

La CQL résultat est :

[id="w_tdm80j_11"][]|[id="w_tdm80j_8"]|[id="w_tdm80j_1"][]{4}

La macro et la XSL ont été déposées dans : davs://sharedocs.huma-num.fr/dav.php/@Shares/(948)%20Cactus/(3792)%20Cactus/Projets/Textométrie/TXM/scripts-et-macros/xsl2cql

V1

On reproduit en XSL la requête CQL :

<w src="|Vg.Ps.1.1|Vg.Ct.1.1|" type="|inexactQuotation|inexactQuotation|" subtype="|implicit|implicit|" ana="|null|allusion|">Deo</w>
sur le corpus de Bernard en tenant compte de la contrainte croisée (Vg.Ct.1.1+inexactQuotation+allusion).

V2

On écrit la XSL travaillant directement sur les <seg> source, disponibles dans le XML-TEI TXM pivot.

Les sources utilisées se trouvent dans le répertoire davs://sharedocs.huma-num.fr/dav.php/@Shares/(948)%20Cactus/(3792)%20Cactus/Projets/Sources%20Chrétiennes/BernardXSL/BernardXSL.

Le répertoire davs://sharedocs.huma-num.fr/dav.php/@Shares/(948)%20Cactus/(3792)%20Cactus/Projets/Sources%20Chrétiennes/BernardXSL contient des tableaux de statistiques des éléments seg, note, span, link, ptr et ref.

public/specs_ajout_moteur_resolution_annotation.txt · Dernière modification: 2018/05/04 12:21 par slh@ens-lyon.fr