Contents

Organizzazione dei tool

(Proposta di Antonio Fuschetto)


Al fine di poter utilizzare la pipeline in modo semplice ed intuitivo avevo pensato di riorganizzare i vari tool.

Un'idea è quella di organizzare i vari strumenti in moduli Python, in modo tale da dare la possibilità agli utenti della libreria Tanl di importare i moduli di loro interesse.

La possibile struttura potrebbe essere la seguente (i moduli già disponibili sono indicati in grassetto):

tanl ---+--- split ---+--- SentenceSplitter
        |             +--- Tokenizer
        |
        +--- tag ---+--- TreeTagger
        |           +--- HunPos
        |           +--- Lemmatizer
        |           +--- MorphSplitter
        |
        +--- parse --- DeSR
        |
        +--- classifier ---+--- MaxEnt
        |                  +--- SVN
        |                  +--- Perceptron
        |                  +--- BelNetwork
        |
        +--- core ---+--- Sentence
                     +--- Token
                     +--- Corpus
                     +--- SentenceReader

Con una libreria organizzata in questo modo risulta semplice, ad esempio, implementare una mini-pipeline che processa un testo dato in input splittandolo dapprima in sentence e successivamente in word:

import sys
from tanl.split.SentenceSplitter import *
from tanl.split.Tokenizer import *

splitter = SentenceSplitter('italian.pickle').pipe(sys.stdin)
tokenizer = Tokenizer().pipe(splitter)

for token in tokenizer:
    print token.form

Con questa semplice pipeline, dato in input il testo seguete:

<doc id="1" url="test">
Prima frase. Seconda frase.
</doc>

si ottiene:

<doc id="1" url="test">

Prima
frase
.

Seconda
frase
.

</doc>

Configurazione dei tool

(Proposta di Antonio Fuschetto)


Quasi tutti i tool della pipeline necessitano di parametri di configurazione per essere utilizzati (modello di apprendimento, ecc.), per tal motivo risulta necessaria un'organizzazione che faciliti l'utilizzo degli strumenti.

L'obiettivo è quello di avere un file pickle (un oggetto Python serializzato su file), per ogni tool della pipeline, che contenga i parametri di configurazione. In questo modo si possono avere diverse configurazioni salvate su diversi file, ad esempio per lingue differenti.

Segue un possibile esempio di utilizzo nel caso del SentenceSplitter:

import sys
import pickle
from Tanl.split.SentenceSplitter import *

# Carica una configurazione del SentenceSplitter
ssConf = pickle.load(open('italianSplitter.pickle'))

ss = SentenceSplitter(ssConf).pipe(sys.stdin)

Il costruttore di ogni tool quindi riceverà come parametro il proprio oggetto di configurazione (il SentenceSplitter, ad esempio, necessita del tokenizer Punkt addestrato su un corpus).

In questo modo, dal momento in cui ogni tool riceve un oggetto come parametro, sarà possibile salvare la configurazione di tutti i tool di una data pipeline (e non dei singoli strumenti) su un solo file pickle.

Ad esempio:

import sys
import pickle
from Tanl.split.SentenceSplitter import *
from Tanl.split.Tokenizer import *
from Tanl.tag.HunPosTagger import *

# Carica un dizionario con la configurazione di tutti i tool
conf = pickle.load(open('tanlConfiguration_italian.pickle'))

splitter = SentenceSplitter(conf['SetenceSplitter']).pipe(sys.stdin)
tokenizer = Tokenizer().pipe(splitter)
tagger = HunPosTagger(conf['HunPosTagger]).pipe(tokenizer)

# Eccetera...

Configurazione tool

(Commento di Giuseppe Attardi)


L'idea è buona, ma non si può utilizzare pickle per i file di configurazione, dato che la pipeline può essere usata da altri linguaggi, C++ in particolare.

L'architettura già prevede che il costruttore di ciascun tool abbia degli argomenti di configurazione. La soluzione più comune sarà che sia semplicemente il nome di un file. Sarà il costruttore stesso a decidere cosa farne, in particolare può essere un file di configurazione che si andrà a leggere da solo (senza che sia l'utente a doverlo aprire), oppure in certi casi è direttamente il file contenente il modello da usare. Qundi manterrei la soluzione già prevista nell'architettura:

ss = SentenceSplitter('italian.pickle').pipe(sys.stdin)

Naming

Per dare un naming uniforme alle classi, ogni tagger ha il suo namespace, ma hanno lo stesso nome. Inoltre implementano tutti l'interfaccia Tanl::Tagger. Per esempio:

 namespace TreeTagger {
   class PosTagger : public Tagger {
   ...
   }
}
 namespace HunPos {
   class PosTagger : public Tagger {
   ...
   }
}

In Python one will use them like this:

  import tanl.tag.TreeTagger
  import tanl.tag.HunPos

  tagger1 = tanl.TreeTagger.PosTagger(...)
  tagger2 = tanl.HunPos.PosTagger(...)

Pipeline e sub-pipeline

(Proposta di Antonio Fuschetto)


Nel tentativo di cercare una soluzione al problema della gestione dei tag document, ho pensato ad una differente modalità di assemblaggio dei vari tool. Premetto che questa tecnica viene in supporto alla tradizionale creazione di una pipeline Tanl, per cui quel che è stato detto in precedenza (ad esempio gli esempi sopra riportati) resta comunque valido e funzionate.

L'idea consiste nel fornire al modulo Tanl due metodi (nell'esempio sono banalmente chiamati pipeline1 e pipeline2), i quali permettono di comporre una pipeline a partire dagli oggetti (tool) forniti come parametro.

Un esempio aiuta a chiarire facilmente il concetto:

import sys
import tanl

parsed = tanl.pipeline1(
    sys.stdin,
    tanl.SentenceSplitter.SentenceSplitter('SS-Model'),
    tanl.Tokenizer.Tokenizer(),
    tanl.pipeline2(
        tanl.Hunpos.PosTagger('PT-Model'),
        tanl.NETagger.NETagger('NET-Model'),
        tanl.SenseTagger.SenseTagger('ST-Model'),
        tanl.Desr.Desr('P-Model')
    )
)

for sentence in parsed:
    print sentence

Il metodo pipeline2 differisce da pipeline1 dal fatto che permette la gestione delle informazioni senza considerare i tag document (vengono rimossi all'inizio, memorizzati in uno stato interno e reinseriti all'uscita). Ovviamente entrambi posso accettare un numero indefinito di parametri, e quindi tool.

Questa soluzione ha l'obiettivo di semplificare la creazione di pipeline, in quanto evita all'utente di dover chiamare di volta in volta i metodi pipe forniti dai tool.

Powered by MediaWiki