Anno Accademico 2009/2010
UNIVERSITÀ DEGLI STUDI DI TRIESTE
FACOLTÀ DI INGEGNERIA
Corso di Laurea Specialistica in Ingegneria Informatica
Tesi di Laurea in RETI DI CALCOLATORI
Tecniche per la rilevazione e correzione
di errori nell'elaborazione automatica di
documenti cartacei
Laureando: Relatore:
Matteo GAZZIN Prof. Ing. Alberto BARTOLI
Correlatori:
Prof. Ing. Eric MEDVET
Ing. Giorgio DAVANZO
I
SOMMARIO
SOMMARIO……………………………………………………………………………………………I
INDICE DELLE FIGURE……………………………………………………………………………III
INDICE DELLE TABELLE………………………………………………………………………….IV
INDICE DEI GRAFICI……………………………………………………………………………….V
INTRODUZIONE........................................................................................ 1
ANALISI E PROGETTAZIONE ..................................................................... 2
CLASSIFICAZIONE DEGLI ERRORI COMMESSI DAGLI OCR ...................................... 3
SCENARIO: IN CHE CONTESTO SI INSERISCE IL LAVORO SVOLTO .............................. 5
IL RUOLO DI SINTASSI E SEMANTICA ............................................................. 10
PROGETTAZIONE ..................................................................................... 14
REALIZZAZIONE ...................................................................................... 15
TECNOLOGIE UTILIZZATE ........................................................................... 15
SCENARIO FIXER SINGOLO .................................................................. 16
ALGORITMO ................................................................................... 16
SCENARIO FIXER AGGREGATO ............................................................ 21
ALGORITMO APPROSSIMATO ......................................................... 22
ALGORITMO: L’ESEMPIO CONSIDERATO PER QUESTA TESI .............. 23
VALUTAZIONI QUALITATIVE E QUANTITATIVE ..................................... 29
IMPLEMENTAZIONE ............................................................................... 32
INTERFACCIA JAVA ............................................................................. 32
ORGANIZZAZIONE DEL CODICE .................................................................... 33
VALUTAZIONE SPERIMENTALE ............................................................... 36
RISULTATI .......................................................................................... 37
SENZA FIXER .................................................................................. 37
CON I FIXER .................................................................................... 38
CONSIDERAZIONI GLOBALI ............................................................. 44
PRESTAZIONI ......................................................................................... 47
II
CONCLUSIONI ........................................................................................ 49
APPENDICE A: DOCUMENT GENERATOR ................................................ 50
SPECIFICHE TECNICHE .............................................................................. 50
FUNZIONAMENTO ................................................................................... 53
APPENDICE B: FILE DI CONFIGURAZIONE SUBSTITUTIONPAIRS .............. 57
RINGRAZIAMENTI .................................................................................. 61
BIBLIOGRAFIA ........................................................................................ 63
III
INDICE DELLE FIGURE
FIGURA 1 - SCREENSHOT DELL'INTERFACCIA DI DOCUMENT GENERATOR ..................... 7
FIGURA 2 - DIAGRAMMA DI FLUSSO DEL SISTEMA DI ELABORAZIONE AUTOMATICA DI
DOCUMENTI ........................................................................................ 9
FIGURA 3 - DIAGRAMMA DI FLUSSO SEMPLIFICATO DEL SISTEMA DI ELABORAZIONE
AUTOMATICA DI DOCUMENTI ................................................................. 10
FIGURA 4 - ERRORE DI INDIVIDUAZIONE DEL CONTENUTO. IL SOFTWARE DOVRÀ ESSERE IN
GRADO DI ESTRARRE LA PORZIONE CONTENENTE LA DATA SULLA QUALE APPLICARE
LA CORREZIONE SE NECESSARIA. .............................................................. 10
FIGURA 5 - ERRORE DI SEGMENTAZIONE ........................................................... 11
FIGURA 6 - ERRORE DI PUNTEGGIATURA, LA VIRGOLA DECIMALE È STATA SOSTITUITA DA
UNO SPAZIO ...................................................................................... 11
FIGURA 7 - ERRORE DI AMBIGUITÀ DI CARATTERE E DI SEGMENTAZIONE .................... 11
FIGURA 8 - VALORI SINTATTICAMENTE CORRETTI ................................................. 12
FIGURA 9 - DIAGRAMMA DELLE CLASSI ............................................................. 14
FIGURA 10 - DIAGRAMMA DI FLUSSO DATI DI UN FIXER SINGOLO ............................ 17
FIGURA 12 - PACKAGE E CLASSI DEL PROGETTO ................................................... 33
FIGURA 13 - DIAGRAMMA FISICO DEL DB USATO PER I TEST ................................... 36
FIGURA 14 - DOCUMENT GENERATOR: GENERAZIONE FATTURE DA NUOVI MODELLI ..... 53
FIGURA 15 - DOCUMENT GENERATOR: GENERAZIONE FATTURE DA MODELLI PREESISTENTI.
...................................................................................................... 55
FIGURA 16 – ESEMPIO DI FATTURA GENERATA DA DOCUMENT GENERATOR ............... 56
IV
INDICE DELLE TABELLE
TABELLA 1 - SUBSTITUTION PAIRS ................................................................... 18
TABELLA 2 – POSSIBILI STATI ALL’USCITA DI ERRORFIXER ....................................... 29
TABELLA 3 – POSSIBILI VALORI DI QUALITY ALL’USCITA DI ERRORFIXER ..................... 30
TABELLA 4 - RELAZIONE TRA STATUS E QUALITY .................................................. 31
TABELLA 6 - SITUAZIONE GROUND-TRUTH SENZA L'APPLICAZIONE DEI FIXER................ 37
TABELLA 7 - SITUAZIONE GROUND-TRUTH DOPO 1° TEST ....................................... 38
TABELLA 8 - ERRORI RESIDUI DOPO 1° TEST ....................................................... 41
TABELLA 9 - AGGIORNAMENTO SUBSTITUTIONPAIRS ............................................ 42
TABELLA 10 - SITUAZIONE GROUND-TRUTH DOPO L'APPLICAZIONE DEI FIXER .............. 42
TABELLA 11 - ERRORI RESIDUI DOPO 2° TEST ..................................................... 43
V
INDICE DEI GRAFICI
GRAFICO 1 - SITUAZIONE GROUND-TRUTH SENZA L'APPLICAZIONE DEI FIXER ............... 38
GRAFICO 2 - SITUAZIONE POST-FIXER 1° TEST ..................................................... 40
GRAFICO 3 - SITUAZIONE DOPO L'APPLICAZIONE DEI FIXER ..................................... 43
GRAFICO 4 – PERCENTUALE DI ERRORI SENZA L’APPLICAZIONE DEI FIXER .................... 44
GRAFICO 5 – PERCENTUALE DI ERRORI DOPO L’APPLICAZIONE DEI FIXER .................... 44
GRAFICO 6 – PERCENTUALE CORREZIONI FATTE RISPETTO AL TOTALE ........................ 45
GRAFICO 7 – PERCENTUALI CORREZIONI FATTE O SUGGERITE RISPETTO AL TOTALE DI
ERRORI SE NON FOSSERO PRESENTI I FIXER ................................................. 46
1
INTRODUZIONE
Negli ultimi anni è emerso un interesse sempre più crescente verso
la digitalizzazione di documenti cartacei, operazione che ne
permette una migliore conservazione nel tempo e apre le porte a
tutti i benefici offerti dal formato digitale.
Volendo andare oltre al semplice immagazzinamento di immagini,
che ha l’unico vantaggio di ridurre lo spazio fisicamente occupato
dagli archivi cartacei, l’interesse si è spostato verso l’estrazione di
contenuti con tipo, operazione che permette di valorizzare i dati di
interesse contenuti nel documento ed inserirli in un database; ad
esempio per una fattura potrebbero essere la data di emissione, il
numero della fattura, la partita iva del fornitore o altri. Il vantaggio
principale di questo approccio è dato dalla possibilità di gestire i
documenti con un sistema informativo.
L’estrazione di contenuti testuali da un’immagine è affidata a
software OCR (Optical Character Recognition) che hanno come
principale limitazione il fatto di commettere errori nella
conversione dell’informazione da immagine a testo.
L’obiettivo di questa tesi è l’implementazione di un sistema di
rilevazione e correzione degli errori generati da un OCR.
Il primo capitolo è dedicato all’analisi del problema; viene
presentata una descrizione degli errori comunemente commessi dai
software OCR e come si è pensato di risolverli; in seguito trova
spazio una descrizione dello scenario in cui si inserisce il
componente software realizzato.
Nel capitolo Realizzazione vengono descritti in dettaglio gli
algoritmi realizzati e le scelte effettuate.
Infine nel capitolo Valutazione sperimentale vengono descritti i test
effettuati e i risultati ottenuti sulla ground-truth di test.
2
ANALISI E PROGETTAZIONE
Il primo passo per trasformare un archivio cartaceo in uno digitale è
la scansione dei documenti. Il passo successivo prevede
l’applicazione di un software OCR che traduce il contenuto di ogni
pagina in caratteri ASCII interpretabili da un calcolatore. Questi
software tentano di imitare l’effetto combinato di cervello e occhio
umano che permette all’uomo di distinguere facilmente i caratteri
stampati in un documento e aggregarli in parole.
L’uomo è in grado di riconoscere rapidamente il layout di una
pagina, le sezioni, i titoli e leggere correttamente il testo di un
documento anche in presenza di porzioni dello stesso fortemente
degradate o addirittura mancanti. I moderni OCR riescono a fare
tutto questo abbastanza bene fino ad arrivare ad una precisione del
99% nel riconoscimento dei caratteri in stampe recenti, come ad
esempio stampe ad alta qualità e perfettamente conservate di file
Word o PDF. Questi risultati calano considerevolmente nel
momento in cui si prende in considerazione un vecchio giornale,
una vecchia stampa a getto d’inchiostro o ad aghi. A tal proposito,
un recente studio(Holley, 2009), ha evidenziato che prendendo in
considerazione 45 pagine di giornale prese a caso da un insieme
appartenente al periodo che va dal 1803 al 1954, l’accuratezza
raggiunta oscilla tra il 71% e il 98%. Nel caso peggiore, questo
significa che ci sono 145 caratteri errati in un paragrafo di 500.
Questi risultati possono essere migliorati in post-processing in
modo manuale, semiautomatico o completamente automatico. Nel
caso manuale, la correzione è lasciata alla pazienza certosina di un
revisore che manualmente confronta il testo originale con quello
acquisito. Un sistema di correzione semiautomatica invece, rileva
gli errori e propone un insieme di correzioni ad un operatore che ha
il compito di scegliere quale sia la proposta corretta. Un sistema di
correzione automatica infine, non prevede l’intervento umano ed è
3
in grado di rilevare e correggere autonomamente gli errori sulla
base di criteri a massima verosimiglianza.
CLASSIFICAZIONE DEGLI ERRORI COMMESSI DAGLI OCR
Prima di poterli correggere, gli errori vanno necessariamente
identificati e classificati. Esiste in letteratura una classificazione
universalmente impiegata che divide gli errori in 2 classi (Kukich,
1992):
NON-WORD ERROR: un errore non-word avviene quando la parola
rilevata non appartiene a nessun vocabolario (ad esempio “tho”
al posto di “the”) . Questo è un errore molto comune che può
essere rilevato con un controllo dell’ortografia.
REAL-WORD ERROR: un errore real-word avviene quando la parola
rilevata è corretta da un punto di vista ortografico ma è usata in
un contesto sbagliato (ad esempio “peace of paper” invece di
“piece of paper”). Questo tipo di errori sono rilevabili e
correggibili solo in base al contesto della frase.
Questa separazione in due gruppi non è ovviamente esaustiva, in
particolare per quanto riguarda l’ambito in cui si inserisce il lavoro
svolto per questa tesi, quindi è necessario arrivare ad una
classificazione più articolata che prevede:
ERRORI DI SEGMENTAZIONE: si verificano quando avviene la
separazione in più parti di una stringa originariamente unica,
o l’unione di più stringhe originariamente separate (ad
esempio “spaghetti””spa g hetti” oppure “la
pizza”“lapizza”).
ERRORI DI SILLABAZIONE: comuni in articoli di giornale,
aumentano il fenomeno della segmentazione (ad esempio
“piz- za”).
4
RICONOSCIMENTO ERRATO DI CARATTERI: il deterioramento del
documento o alcuni stili di scrittura particolari, possono
indurre ad una errata interpretazione dei caratteri (ad
esempio “suoiio” anziché “suono” ma anche “&-$tat’e” al
posto di “Estate”).
ERRORI DI PUNTEGGIATURA: il deterioramento del documento
può esserne la causa. Questo può significare ad esempio
scambiare punti con virgole o, più frequentemente,
l’inserimento di uno spazio vuoto al posto di un segno di
punteggiatura.
ERRORI DI AMBIGUITÀ DI SIGNIFICATO: Il riconoscimento errato di
alcuni caratteri potrebbe generare nuove parole corrette dal
punto di vista ortografico ma semanticamente fuori
contesto (Ad esempio “quest’auto fa le pizze” anziché
“quest’auto fa le bizze”).
DISTRUZIONE DEL CONTENUTO: La contemporaneità di più errori
all’interno di un’unica stringa potrebbe portare infine ad un
errore di distruzione del contenuto (ad esempio “| | 4 ç i c0”
al posto di “Magico”).
Appare quindi evidente che alcuni degli errori elencati sono
correggibili, altri potrebbero esserlo adottando tecniche atte a
verificare la correlazione tra caratteri successivi o la semantica della
frase, altri infine non lo sono. Richiamando le 3 tipologie di
correzione in post-processing viste in precedenza, l’unica soluzione
per il caso di errori non correggibili è la tediosa procedura manuale.
Fino ad ora sono stati discussi documenti contenenti testo
semplice, eventualmente formattato, costituito da parole
riconducibili ad un determinato linguaggio; l’appartenenza ad un
vocabolario noto all’OCR è una conditio sine qua non affinché siano
applicabili le metodologie di correzione semiautomatiche ed
automatiche legate al contesto e alla semantica della frase.
5
Per questo motivo utilizzare software OCR per elaborare documenti
contenenti un insieme di campi strutturati, aventi una precisa
sintassi e semantica non afferente ad una lingua parlata, non porta
a risultati soddisfacenti con le normali tecniche di correzione
automatica d’errore.
SCENARIO: IN CHE CONTESTO SI INSERISCE IL LAVORO SVOLTO
Oggetto di studio di questo elaborato, è la realizzazione di un
componente software con finalità di rilevazione e correzione di
errori basate su proprietà sintattiche e semantiche del contenuto
atteso.
Tale componente è parte di un progetto per la digitalizzazione e
classificazione automatica di informazioni contenute in documenti
cartacei, sviluppato all’interno del laboratorio di “Reti di
Calcolatori” dell’Università degli studi di Trieste.
Uno dei possibili scenari di utilizzo di un sistema di questo tipo è la
digitalizzazione delle fatture da parte di un’azienda. In questo
modo, anziché catalogare manualmente tutte le fatture ed inserire i
campi di interesse all’interno di un sistema di gestione
documentale, o più in generale di un database, l’operatore deve
limitarsi a scannerizzare il documento originale.
L’immagine scannerizzata viene elaborata dal sistema che estrae
automaticamente le informazioni di interesse e salva tutto in una
base dati.
Le informazioni estraibili dipendono dal tipo di documento: ad
esempio quelle estraibili da una fattura sono diverse da quelle
estraibili da uno scontrino fiscale.
Documenti che afferiscono alla medesima tipologia definiscono una
classe di documenti. Una classe può essere quindi quella delle
fatture, o quella degli scontrini fiscali.
6
Documenti appartenenti alla stessa classe contengono le stesse
informazioni divise in campi: ad esempio in una fattura sono
presenti i campi “Data”, “Partita Iva”, “Totale”, etc. Tuttavia la
disposizione di questi campi può variare, si definisce quindi modello
l’insieme dei documenti che condividono classe di appartenenza e
layout grafico. Gli scontrini stampati da un certo registratore di
cassa ad esempio, hanno lo stesso layout e per trattarli si dovrà
applicare lo stesso modello.
Sotto la guida del Prof. Alberto Bartoli, tesisti e dottorandi hanno
contribuito in diversa misura alla realizzazione di questo progetto
che ha già portato a varie pubblicazioni scientifiche internazionali.
La prima di queste è arrivata per merito del lavoro realizzato dal
Prof. Eric Medvet, culminato con la pubblicazione dell’articolo “A
Probabilistic Approach for Printed Document Understanding”
(Medvet, Bartoli, & Davanzo, 2010) nella rivista di riferimento per il
settore specifico “International Journal of Document Analysis and
Recognition”. In questo articolo si propone un approccio per
l’estrazione di informazioni da documenti cartacei multi pagina, nei
quali il set di possibili classi di documenti può evolvere nel tempo e
diversi documenti possono condividere contenuti e layout simili.
Nella pratica l’utilizzatore finale di questo software educa il sistema
proponendo un set di fatture di Test ed individuando per esse le
posizioni in cui si trovano i vari campi di interesse, ad esempio data
o partita iva, semplicemente localizzandole con il mouse. A questo
punto il sistema sarà in grado di trovare i campi di interesse per
tutte le fatture appartenenti ai modelli noti.
Relativamente alla fase di test di questo modulo, l’autore di questa
tesi di laurea ha realizzato come attività di tirocinio, un software,
Document Generator, per la generazione automatica di k fatture
afferenti a n diversi modelli grazie al quale è stato possibile testare
il classificatore su larga scala senza dover acquisire centinaia di
fatture con lo scanner. In appendice A una descrizione sintetica
7
relativa a questo software di cui si propone uno screenshot della
schermata principale qui di seguito.
Figura 1 - Screenshot dell'interfaccia di Document Generator
Una fase cruciale di quanto appena illustrato è la classificazione dei
documenti in base al contenuto, dev’esserci quindi a monte un
modulo in grado di discriminare una fattura Fastweb da una di
Telecom Italia e così via. Questo compito, apparentemente banale
ma nella pratica particolarmente complicato, è assolto dal modulo
realizzato dall’Ing. Enrico Sorio. Anche per questa componente non
è mancato il riconoscimento internazionale con la pubblicazione
dell’articolo “Open World Classification of Printed Invoices”(Sorio,
Bartoli, Davanzo, & Medvet, 09-2010).
La complessa infrastruttura software che garantisce il
funzionamento di tutte le componenti descritte, è stata realizzata in
varie misure dagli Ingegneri Giorgio Davanzo, Marco Mauri ed
Enrico Sorio.
Oggetto di studio di questa tesi è dunque la realizzazione di un
modulo software atto a rilevare e correggere in post-processing gli
errori commessi dall’OCR in campi con una particolare sintassi e
8
semantica. In particolare si è scelto di concentrarsi sulla rilevazione
e correzione di errori in documenti afferenti alla classe delle
fatture, ma il componente sarà comunque estendibile a qualunque
altra classe.
Tale modulo si inserisce nel workflow immediatamente dopo il
blocco demandato all’estrazione dei campi.
Come accennato nel capitolo precedente, le prestazioni degli OCR
in documenti strutturati come questi, non possono certamente
avvicinarsi ai risultati ottenibili con testi semplici, non essendo
possibile l’applicazione di algoritmi standard di correzione d’errore
in post-processing.
La situazione fin qui descritta è schematizzata nella seguente figura.
9
Figura 2 - Diagramma di flusso del sistema di elaborazione automatica di documenti
Il componente realizzato per questa tesi è identificabile con il
blocco verde con bordo rosso.
Una versione semplificata di quanto appena visto è data dal
seguente diagramma:
10
Figura 3 - Diagramma di flusso semplificato del sistema di elaborazione automatica di documenti
Anche in questo caso il blocco realizzato è evidenziato con un bordo
rosso.
Si vedranno ora gli errori più comuni legati a questo ambito
specifico e come si è pensato di risolverli.
IL RUOLO DI SINTASSI E SEMANTICA
Il software per l’estrazione dei contenuti identifica in modo
estremamente accurato la posizione dell’informazione desiderata,
ma non riesce ad estrarre correttamente il contenuto atteso.
Poiché l’OCR suddivide in blocchi il documento, è possibile che il
testo contenuto in un blocco contenga del rumore costituito
fondamentalmente da caratteri aggiuntivi che non c’entrano con
quanto cercato.
Figura 4 - Errore di individuazione del contenuto. Il software dovrà essere in grado di estrarre la
porzione contenente la data sulla quale applicare la correzione se necessaria.
Pertanto si dovrà far in modo che il software riesca a focalizzare la
sua attenzione sullo specifico contenuto di interesse.
11
In aggiunta, il degrado del documento potrebbe, come visto in
precedenza, portare a diversi tipi di errore. Di seguito si vedranno
alcune immagini di esempio che evidenziano in che modo la stringa
attesa, “19.556,25 euro”, possa venir mal interpretata. Si suppone
che il rumore aggiunto dato dalla stringa ”euro” sia stato già
rimosso.
Figura 5 - Errore di segmentazione
Figura 6 - Errore di punteggiatura, la virgola decimale è stata sostituita da uno spazio
Figura 7 - Errore di Ambiguità di carattere e di segmentazione
Di fronte a output come questi è evidente che un sistema di
archiviazione automatica di contenuti tipizzati non può funzionare.
In prima istanza si dovranno correggere gli errori di ambiguità di
carattere sulla base del tipo di campo considerato. Ad esempio se il
campo è di tipo numerico, è abbastanza evidente che il simbolo “|”
potrebbe corrispondere ad “1” ed “S” a ”5”, pertanto sarà
necessario creare una tabella di corrispondenze tra carattere errato
e carattere corretto.
Successivamente andrà effettuato un controllo sintattico per
verificare che le correzioni effettuate abbiano effettivamente dato
luogo a un contenuto formalmente corretto.
Data la particolare struttura di alcuni campi, dovrà essere anche
previsto un controllo semantico. La figura seguente mostra il
risultato della scansione di una partita iva e due possibili valori
estratti dall’OCR.
12
Figura 8 - Valori sintatticamente corretti
Sintatticamente entrambi i valori sono perfettamente validi
essendo formati da 11 cifre consecutive. Tuttavia solo la prima
soluzione proposta è semanticamente valida. Si può arrivare a
questa conclusione grazie al checksum fornito dall’ultima cifra che è
ottenuta effettuando alcune precise operazioni sulle precedenti.
Nel capitolo Realizzazione verranno esposti i vari algoritmi di
controllo semantico utilizzati. Nell’eventualità in cui i valori
semanticamente validi fossero più di uno, la scelta avverrà sulla
base di criteri a massima verosimiglianza.
Per questo progetto sono stati presi in considerazione i seguenti
campi:
Data
Numero Fattura
Partita Iva
Codice Fiscale
Valuta
Numero
Ogni campo preso in considerazione ha una sintassi ed una
semantica ben definite e necessiterà quindi di correzioni differenti.
Tuttavia buona parte delle procedure è standard, pertanto si è
deciso di creare una classe astratta contenente la logica comune ed
estenderla con implementazioni specifiche per i vari tipi di
contenuto. Esisteranno pertanto tanti correttori, fixer nel prosieguo
della trattazione, quanti sono i campi presi in considerazione.
Alcuni campi all’interno del documento, possono essere correlati
tra loro. In questo caso, oltre alle correzioni effettuate dai fixer
singoli, è possibile sfruttare la correlazione tra i dati ed
implementare un controllo semantico aggregato per arrivare ad
13
ulteriori correzioni. Correttori di questo tipo verranno chiamati
Fixer Aggregati. L’esempio preso in considerazione nel caso delle
fatture è quello dei quattro campi “Totale”, ”Imponibile”, “Iva” ed
“Aliquota”.
Il software quindi sarà completamente estendibile: per correggere
dati afferenti ad un nuovo campo o ad un insieme di campi, basterà
scrivere un fixer con un’implementazione ad hoc per quel formato.
14
PROGETTAZIONE
Tutte queste considerazioni hanno portato alla stesura del
seguente diagramma delle classi.
Figura 9 - Diagramma delle classi
15
REALIZZAZIONE
Il componente realizzato fa parte di quella branca di rilevatori e
correttori di errore che lavorano in post-processing sui risultati
generati da un OCR. In particolare l’obiettivo principe è quello di far
sì che funzioni in modo completamente automatico, ripiegando
verso la modalità semi-automatica solo quando strettamente
necessario, riducendo così al minimo l’intervento manuale.
TECNOLOGIE UTILIZZATE
Dovendo realizzare un componente aggiuntivo per un software
preesistente, la scelta delle tecnologie da utilizzare non è stata
libera. Il sistema di elaborazione automatica di documenti presenta
le seguenti caratteristiche:
Java Enterprise Edition (Oracle - J2EE) 6;
Enterprise Java Bean (Oracle - EJB);
application server GlassFish V3 (Glassfish);
web services con approccio REST (Representational State
Transfer);
data storage mediante l’utilizzo di JPA 2.0 (java persistence
api).
Il modulo realizzato va ad inserirsi all’interno del workflow J2EE ed
è quindi stato scritto in linguaggio Java.
Per allinearsi con l’ambiente di sviluppo adottato nel laboratorio
dove si è sviluppato il codice, si è utilizzato l’IDE (Integrated
Development Enviroment) Netbeans di Oracle Corporation
(Netbeans).
Totalmente libera invece è stata la scelta riguardante il DBMS
(DataBase Management System) da adottare per il codice di test.
Data la semplicità della base dati da realizzare, si è optato per
16
l’utilizzo del DBMS open source MySql di Oracle Corporation
(MySql).
SCENARIO FIXER SINGOLO
Un documento è costituito da un set di campi C={c1,c2,…,cm}. Ogni
campo ci è caratterizzato da un tipo t, un valore s rilevato dall’OCR
ed un valore atteso s0. Il valore atteso, ossia il valore
effettivamente scritto sul documento, non è noto.
La finalità di questo elaborato è quella di proporre un
procedimento per ottenere, a partire da t ed s, un set di soluzioni
candidate S={s1, s2, …, sn}. È auspicabile che S contenga il numero
minimo di elementi, sperabilmente uno solo, e che fra questi ci sia
s0.
In secondo luogo si vogliono ottenere una valutazione qualitativa
ed una quantitativa dell’eventuale correzione apportata. Questi
indici sono necessari per discriminare quando il fixer può agire in
modalità completamente automatica, quando in modalità semi-
automatica e quando, non potendo applicare alcuna correzione, è
richiesto l’intervento manuale.
Senza perdere di generalità, nel prosieguo della trattazione si
assume che il set C sia composto da un solo campo c0=<t,s,s0>.
ALGORITMO
Il diagramma seguente riassume l’architettura di un fixer singolo. Le
frecce rappresentano il flusso dei dati. I dati che transitano sono
indicati sulla porta in uscita. Con la notazione 's' minuscola si
intende una singola stringa mentre con 'S' maiuscola si intende un
set di stringhe.
17
Figura 10 - Diagramma di flusso dati di un Fixer Singolo
Si considerano i seguenti input:
s: Stringa in ingresso
ValRegex: una o più espressioni regolari usate dal Syntactic
Checker per verificare la correttezza sintattica della stringa
che riceve in ingresso.
Checksum: una o più espressioni regolari usate dal Semantic
Checker per verificare la correttezza semantica della stringa
in input.
SubstitutionPairs: insieme di correttori; ognuno associa
StringaErrata ad un insieme di StringaCorretta.
18
STRINGA ERRATA SET[STRINGA CORRETTA] TIPO
N 11 Multichar
11 N Multichar
Il 4 Multichar
~I 4 Multichar
o 0 CharNumber
O 0 CharNumber
/ 1 CharNumber
I 1,7 CharNumber
i 1 CharNumber
! 1 CharNumber
G 6 CharNumber
Q 0 CharNumber
D 0 CharNumber
B 8 CharNumber
Z 2 CharNumber
T 7 CharNumber
S 5 CharNumber
z 2 CharNumber
s 5 CharNumber
0 O,D NumberChar
1 I,l NumberChar
6 G NumberChar
8 B NumberChar
2 Z NumberChar
5 S NumberChar
6 5,8 NumberNumber
? 7 SpecialCharNumber
Tabella 1 - Substitution Pairs
Le sostituzioni possibili che costituiscono la tabella
SubstitutionPairs, sono state generate dall’osservazione
degli errori generati dall’OCR in campi appartenenti ad un
set di fatture di test.
BLOCCHI FUNZIONALI:
STRING CLEANER: rimuove dalla stringa s in ingresso i simboli che
non hanno significato ed utilità per lo specifico campo considerato.
Implementazioni specifiche per tipo di campo previste.
19
Es1: campo Partita Iva: s=”012.3 4: 56; 78’ 91”, s’=”01234567891”
(rimuove spazi e simboli).
Es2: campo Valuta: s=”13 4,76” s’=”134,76” (rimuove solo gli spazi)
APPLY SUBSTITUTION: genera un set di stringhe S1 ottenuto
iterando tutte le SubstitutionPairs alla stringa di ingresso s’.
Le sostituzioni possono essere:
Uno-a-uno: una stringa errata viene corretta con una e solo
una stringa corretta;
Uno-a-molti: una stringa errata può essere corretta con più
di una stringa corretta.
Ad ogni iterazione applica la sostituzione presente alla riga i-esima
della tabella SubstitutionPairs come segue:
Sia k il numero di occorrenze in s’ di StringaErrata.
Sia n il numero di StringaCorretta possibili per StringaErrata
considerata.
Sia sp la riga di SubstitutionPairs dell’iterazione corrente.
Il numero di stringhe generate è 2k-1 per sp uno a uno.
Queste stringhe vengono aggiunte al set contenente la
stringa originale.
o Esempio uno-a-uno: s="aibi", S1=[aibi], sp = i-->1.
Dopo ApplySubstitution: S1’=[aibi, a1bi, aib1, a1b1]
Il numero di stringhe generate è nk-1 per sp uno-a-molti:
Queste stringhe vengono aggiunte al set contenente la
stringa originale.
o Esempio uno-a-molti: s="aibi",S1=[aibi], sp = i-->1,7.
Dopo ApplySubstitution: S1’=[aibi, aib1, aib7, a1bi,
a1b1, a1b7, a7bi, a7b1, a7b7]
k=2, n =3 => nk-1 = 32 - 1 = 8
20
SYNTACTIC CHECKER: elimina dal set di ingresso S1 le stringhe che
non soddisfano nessuna delle espressioni regolari ValRegex in
ingresso
SEMANTIC CHECKER: elimina dal set di ingresso S2 le stringhe che
non soddisfano nessuna delle espressioni regolari Checksum in
ingresso
ELEMENT SELECTOR: genera il sottoinsieme di S3 contenente le
stringhe a distanza di Levenshtein minima da s.
IF (S3.size>1) THEN controlla se s è superstringa di uno dei valori
di S3. Se è così, in S3 rimane solo quel valore. Altrimenti non
vengono apportate modifiche ad S3. (Questo ulteriore controllo è
stato aggiunto in un secondo momento per risolvere uno
specifico problema evidenziato in fase di valutazione dei risultati
ottenuti per il campo numero fattura. Si veda a tal proposito il
capitolo Valutazione Sperimentale.)
STATUS UPGRADER: genera una tupla < status , values, quality,
errorMessage, content >; content è il valore presente nel field
prima dell’applicazione del fixer (cioè la stringa estratta dall’OCR)
come segue:
IF (SelectedItems.size ==1) THEN // Da element selector è uscito un solo valore s*.
o status OK
o values SelectedItems (ha un solo valore che è s*)
o quality 1.0
o errorMessage null
o content s*
ELSE IF (SelectedItems.size >1) THEN // Significa che dal semantic checker sono uscite più stringhe con distanza di
Levenshtein da s minima.
o status MULTIPLE_RESULTS
21
o values SelectedItems
o quality 0.5
o errorMessage concatenazione status+values
o content Unchanged
ELSE IF (SelectedItems vuoto) THEN // Da Element Selector non sono uscite stringhe.
o status NOT_FOUND
o values empty set
o quality 0.0
o errorMessage status
o content null
Nel capitolo Valutazioni qualitative e quantitative sono presenti tre
tabelle che esplicitano il significato di status e quality.
SCENARIO FIXER AGGREGATO
Un documento è costituito da un set di campi C = {c1,c2,…,cm}. Ogni
campo ci è caratterizzato da un tipo t, un valore s rilevato dall’OCR
ed un valore atteso s0. Il valore atteso, ossia il valore
effettivamente scritto sul documento, non è noto.
Esiste il sottoinsieme T di C tale che T = {ci1, ci2, …, cik} per il quale
sussiste una relazione logica R(T) che può essere soddisfatta o
meno: R(T) = R(ci1, ci2, …, cik) {Soddisfatta, Non Soddisfatta}.
Ad esempio si consideri l’insieme formato dai campi “TOTALE”,
”IMPONIBILE”, “IVA” ed “ALIQUOTA”.
Sussiste la relazione logica seguente:
R(TOTALE,IMPONIBILE,IVA,ALIQUOTA) :=
[TOTALE = IMPONIBILE + IVA AND IVA =
].
22
Esistono inoltre k funzioni tali per cui fj(Tk≠j) = cij , ossia dati k-1
elementi, la funzione fj è in grado di calcolare il j-esimo elemento
tale che R sia soddisfatta.
Ad esempio, considerando nuovamente l’insieme formato dai
campi “TOTALE”, ”IMPONIBILE”, “IVA” ed “ALIQUOTA”, si possono
definire le seguenti funzioni:
fTOTALE = IMPONIBILE + IVA;
fIMPONIBILE = TOTALE – IVA;
fIVA = TOTALE – IMPONIBILE;
fALIQUOTA =
.
La finalità di questo elaborato è quella di proporre un
procedimento per ottenere, a partire dal set T = {ci1, ci2, …, cik}, un
set = {T’1, T’2, …, T’n } di tuple T’n che soddisfano R(T’n). È
auspicabile che contenga un solo elemento T’.
In secondo luogo si vogliono ottenere una valutazione qualitativa
ed una quantitativa dell’insieme T per gli stessi motivi elencati nella
trattazione del fixer singolo.
Si propone di seguito un algoritmo approssimato del fixer
aggregato.
ALGORITMO APPROSSIMATO
Vengono eseguiti i fixer singoli per i campi appartenenti a T={ci1,
ci2, …, cik}.
IF( )
o IF(R(T) è soddisfatta)
Il set T soddisfa R. Pertanto i dati dei campi Cik
sono coerenti.
o ELSE
I dati ricavati dai campi Cik sono incoerenti.
23
ELSE IF(
)
o Applica il set di funzioni fj
o IF( )
Il valore Cij calcolato ha permesso di trovare un
set T che soddisfa la relazione R.
o ELSE
I dati ricavati dai campi Cik non sono sufficienti.
Per semplificare la trattazione, nel prossimo paragrafo viene
esposta la versione dell’algoritmo specifica per la 4-upla di campi
composta da “TOTALE”, ”IMPONIBILE”, “IVA” ed “ALIQUOTA”.
ALGORITMO: L’ESEMPIO CONSIDERATO PER QUESTA TESI
Per prima cosa il fixer aggregato esegue i fixer singoli per
Imponibile, Iva, Totale, Aliquota in sequenza. Se un campo non è
presente, l’elemento è trattato come se il fixer singolo avesse
restituito status = NOT_FOUND.
Si definiscono:
o originalValue: il valore del campo prima dell’applicazione
del fixer Singolo (empty se status = NOT_FOUND).
o R: set di FixerOutputList; una FixerOutputList ha 4
elementi FixerOutput ognuno dei quali è l’output di uno
dei quattro fixer. All’inizio dell’esecuzione del
FixerAggregato, R contiene 1 solo elemento.
o numErr: numero di elementi dell’unica FixerOutputList
contenuta inizialmente in R con status = NOT_FOUND.
IF (numERR == 0) THEN
o Sia numMULTI il numero di elementi con status =
MULTIPLE_RESULTS.
24
o IF (numMULTI >= 1) THEN // (Si suppone per semplificare la
descrizione numMULTI=1, ossia 1 solo FixerOutput ha Status
=MULTIPLE_RESULTS e values = “un insieme di n stringhe”. )
Crea R1 come segue:
Per ogni stringa n di values viene creata ed
aggiunta in R1 una nuova FixerOutputList
contenente:
o i 3 FixerOutput con status OK
o un quarto FixerOutput con values= n
ELSE //numMulti ==0, ossia 4 FIxerOutput con status OK.
o Crea R1 come segue:
Viene creata ed aggiunta in R1 una nuova
FixerOutputList contenente:
i 4 FixerOutput con status OK
o Viene effettuato un controllo semantico su R1 e vengono
eliminati i FixerOutputList che non lo soddisfano.
o IF (R1.size == 0) THEN //nessun FixerOutputList ha passato il
controllo semantico
Sia folR l’unica FixerOutputList in R.
Per i FixerOutput di folR con Status = OK
Status INCONSISTENT_RESULTS
Values invariato
quality 0.75
errorMessage concatenazione status+values
content originalValue
Per i FixerOutput di folR con Status =
MULTIPLE_RESULTS
status INCONSISTENT_RESULTS
values invariato
quality 0.5
errorMessage concatenazione status+values
content originalValue
25
o ELSE IF (R1.size == 1) THEN //una sola FixedOutputList ha passato
il controllo semantico
Sia folR1 l’unica FixerOutputList in R1.
Per tutti i FixerOutput di folR1:
status OK
values invariato
quality 1.0
errorMessage null
content l’unico elemento di values
o ELSE //R1.size > 1 più di una FixerOutputList ha passato il controllo
semantico (nella pratica non avviene)
Sia folR l’unica FixerOutputList in R
Per ogni folR1 in R1:
Per i FixerOutput di folR con Status = OK
o Status invariato
o values invariato
o quality 0.75
o errorMessage concatenazione
status+values
o content originalValue
Per i FixerOutput di folR con Status =
MULTIPLE_RESULTS
o Status MULTIPLE_RESULTS
o Values sottoinsieme di values
rimasto in folR1
o quality 0.5
o errorMessage concatenazione
status+values
o content originalValue
ELSE IF (numErr == 1) THEN
o Sia r l’elemento di R con Status = NOT_FOUND.
26
o Sia numMULTI il numero di elementi con status =
MULTIPLE_RESULTS.
o IF (numMULTI >= 1) THEN // (Si suppone per semplicità
numMULTI=1, ossia 1 solo FixerOutput ha Status =MULTIPLE_RESULTS e
values = “un insieme di n stringhe”. )
Crea R1 come segue:
Per ogni stringa n di values:
o 2 FixerOutput hanno status OK
o un terzo FixerOutput ha values = n
o Se è possibile calcolare values del
quarto FixerOutput sulla base dei
precedenti 3 FixerOutput, viene creata
ed aggiunta in R1 una nuova
FixerOutputList contenente i 4
fixerOutput qui elencati. In caso
contrario non viene aggiunto nulla in R1
per n corrente.
o ELSE //numMulti ==0, ossia 3 FIxerOutput con status OK.
3 FixerOutput hanno status OK
Se è possibile calcolare values del quarto FixerOutput
sulla base dei precedenti 3 FixerOutput, viene creata
ed aggiunta in R1 una nuova FixerOutputList
contenente i 4 fixerOutput qui elencati. In caso
contrario non viene aggiunto nulla in R1.
o IF (R1.size == 0) THEN //non è possibile calcolare un content per r.
Sia folR l’unica FixerOutputList in R
Per i FixerOutput di folR con Status = OK
Status INCONSISTENT_RESULTS
values invariato
quality 0.75
errorMessage concatenazione status+values
27
content originalValue
Per i FixerOutput di folR con Status =
MULTIPLE_RESULTS
status INCONSISTENT_RESULTS
values invariato
quality 0.5
errorMessage concatenazione status+values
content originalValue
Per r:
status NOT_FOUND
values invariato
quality 0.0
errorMessage concatenazione status+values
content originalValue
o ELSE IF (R1.size == 1) THEN // unico valore calcolato per il content
di r.
Sia folR1 l’unica FixerOutputList in R1
sia suggestedValue il valore calcolato per r.
Per r:
status SUGGESTED_VALUE
values set contenente
suggestedValue.
quality 0.25
errorMessage concatenazione status+values
content originalValue.
Per gli altri FixerOutput di folR1:
status OK
values invariato
quality 0.75
errorMessage null
content l’unico elemento di values
28
o ELSE //R1.size > 1 è stato possibile calcolare più di un valore per il content
di r (nella pratica non avviene)
Sia folR1 l’unica FixerOutputList in R1
Sia setSuggested l’insieme dei valori calcolati per r.
Per r:
status
MULTIPLE_SUGGESTED_VALUES
values setSuggested.
quality 0.125
errorMessage concatenazione status+values
content originalValue.
Per i FixerOutput di folR1 con Status = OK
status invariato
values invariato
quality 0.75
errorMessage concatenazione status+values
content originalValue
Per i FixerOutput di folR1 con Status =
MULTIPLE_RESULTS
status MULTIPLE_RESULTS
values sottoinsieme di values rimasto
in folR1
quality 0.5
errorMessage concatenazione status+values
content originalValue
ELSE //numErr>1
o Per gli elementi di R con Status = OK
status NOT_CONFIRMED_VALUE
values invariato
quality 0.75
errorMessage concatenazione status+values
content originalValue
29
o Agli gli elementi di R con Status NOT_FOUND oppure
MULTIPLE_RESULTS non viene apportata alcuna modifica
ai risultati del fixer singolo.
VALUTAZIONI QUALITATIVE E QUANTITATIVE
Le seguenti tabelle riassumono tutti i possibili output dei fixer. La
colonna modifiche applicate mette in evidenza i campi che vengono
aggiornati nella map nei vari casi. Con T si intende il campo text,
con Q il campo quality e con E il campo errorMessage.
STATUS VALUE
DESCRIZIONE MODIFICHE APPLICATE NOTE
OK Unico valore semanticamente valido trovato.
T, Q, E
MULTIPLE RESULTS
Più valori semanticamente validi trovati.
Q, E
NOT FOUND Nessun valore semanticamente valido trovato.
Q, E
INCONSISTENT RESULTS
Il controllo semantico aggregato è fallito, quindi i risultati dati dai fixer singoli erano incoerenti.
Q, E Solo fixer aggregato
SUGGESTED VALUE
Il fixer aggregato ha calcolato il campo con status NOT_FOUND sulla base degli altri che avevano status OK o MULTIPLE_RESULTS. Tale calcolo ha fornito un risultato univoco.
Q, E
Solo fixer aggregato
MULTIPLE SUGGESTED
VALUE
Il fixer aggregato ha calcolato il campo con status NOT_FOUND sulla base degli altri che avevano status OK o MULTIPLE_RESULTS. Tale calcolo ha fornito più di un valore.
Q, E
Solo fixer aggregato
NOT CONFIRMED
VALUE
Il fixer aggregato non ha elementi a sufficienza (più di un campo ha status NOT_FOUND) per confermare il risultato del fixer singolo.
Q, E Solo fixer aggregato
Tabella 2 – Possibili stati all’uscita di ErrorFixer
30
QUALITY DESCRIZIONE MODIFICHE APPLICATE
NOTE
1.0 Unico valore semanticamente valido trovato (eventualmente confermato anche dal fixer aggregato).
T, Q, E
0.75 Il valore corretto trovato dal fixer singolo non è confermabile dal fixer aggregato.
Q, E Solo fixer aggregato
0.5 Più valori semanticamente validi trovati. Q, E
0.25
Il fixer aggregato ha calcolato il campo con status NOT_FOUND sulla base degli altri che avevano status OK o MULTIPLE_RESULTS. Tale calcolo ha fornito un risultato univoco.
Q, E
Solo fixer aggregato
0.125
Il fixer aggregato ha calcolato il campo con status NOT_FOUND sulla base degli altri che avevano status OK o MULTIPLE_RESULTS. Tale calcolo ha fornito più di un valore.
Q, E
Solo fixer aggregato
0.0 Nessun valore semanticamente valido trovato.
Q, E
Tabella 3 – Possibili valori di Quality all’uscita di ErrorFixer
31
STATUS VALUE QUALITY DESCRIZIONE NOTE
OK 1.0 Unico valore semanticamente valido trovato.
OK 0.75 Il valore corretto trovato dal fixer singolo non è confermabile dal fixer aggregato.
Solo fixer aggregato
MULTIPLE RESULTS
0.5 Più valori semanticamente validi trovati.
NOT FOUND 0.0 Nessun valore semanticamente valido trovato.
INCONSISTENT RESULTS
0.75
Il controllo semantico aggregato è fallito, quindi i risultati dati dai fixer singoli erano incoerenti. Per il campo specifico, il fixer singolo aveva trovato un unico valore.
Solo fixer aggregato
INCONSISTENT RESULTS
0.5
Il controllo semantico aggregato è fallito, quindi i risultati dati dai fixer singoli erano incoerenti. Per il campo specifico, il fixer singolo aveva dato Status MULTIPLE RESULTS.
Solo fixer aggregato
SUGGESTED VALUE
0.25
Il fixer aggregato ha calcolato il campo con status NOT_FOUND sulla base degli altri che avevano status OK o MULTIPLE_RESULTS. Tale calcolo ha fornito un risultato univoco.
Solo fixer aggregato
MULTIPLE SUGGESTED
VALUE 0.125
Il fixer aggregato ha calcolato il campo con status NOT_FOUND sulla base degli altri che avevano status OK o MULTIPLE_RESULTS. Tale calcolo ha fornito più di un valore.
Solo fixer aggregato
NOT CONFIRMED
VALUE 0.75
Il fixer aggregato non ha elementi a sufficienza (più di un campo ha status NOT_FOUND) per confermare il risultato del fixer singolo.
Solo fixer aggregato
Tabella 4 - Relazione tra Status e Quality
32
IMPLEMENTAZIONE
INTERFACCIA JAVA
Tutti i fixer implementano l’interfaccia ErrorFixer il cui unico
metodo esposto è fixErrors.
Un ErrorFixer è un correttore di errori specifico per un determinato
tipo di campo. Il metodo fixErrors ha come parametri una
Map<SearchedField, ResultTextBlock> che rappresenta l’insieme di
campi da correggere.
L’oggetto SearchedField definisce la singola informazione che viene
cercata all’interno del documento. I metodi esposti permettono di:
assegnare il tipo di documento cui fa riferimento;
estrarre il tipo di documento cui fa riferimento;
assegnare un nome identificativo dell’informazione cercata;
estrarre il nome identificativo dell’informazione cercata;
assegnare la tipologia di informazione cercata;
estrarre la tipologia di informazione cercata.
SearchedField viene utilizzato come chiave nella mappa dei campi
trovati e permette di estrarre il ResultTextBlock.
L’oggetto ResultTextBlock rappresenta il campo estratto attraverso
i valori di quality, errorMessage e text. I metodi esposti permettono
di:
assegnare il valore di text;
assegnare il valore di quality;
assegnare il valore di errorMessage;
estrarre il valore di text;
estrarre il valore di quality;
estrarre il valore di errorMessage;
33
Il metodo fixErrors di ErrorFixer può modificare le informazioni
contenute nella map sulla base dei risultati delle operazioni di
rilevazione e correzione d’errore. La modifica prevede
l’aggiornamento dei campi text, quality e errorMessage.
ORGANIZZAZIONE DEL CODICE
La figura seguente mostra come è stato organizzato il progetto in
termini di package e classi.
Figura 11 - Package e classi del progetto
Il package invoiceinspector.commons contiene:
CombinationIterable: classe che implementa Iterable e
fornisce le combinazioni semplici di k elementi presi da un
set di n elementi. Ad esempio si consideri il set S = {A,B,C}
pertanto n=3. Si consideri k=2, ne consegue che si vogliono
generare tutte le combinazioni possibili degli elementi di S
presi a due a due, pertanto si avranno m = nk = 9 possibili
34
combinazioni: {[A,A], [A,B], [A,C], [B,A], [B,B], [B,C], [C,A],
[C,B], [C,C]}.
defaultFieldFixers.xml: file che contiene la tabella delle
SubstitutionPairs (il file completo è consultabile in
Appendice B). Ogni coppia stringa errata-stringa corretta è
così descritta: <fixer>
<wrong>stringa Errata</wrong>
<right>stringa Corretta</right>
</fixer>
FixerLoader: classe adibita all’inizializzazione e alla
suddivisione delle SubstitutionPair in categorie:
o numerolettera;
o letteranumero;
o stringastringa;
o numeronumero.
Questa ripartizione non è strettamente necessaria ma è
un’ottimizzazione che permette ai fixer di applicare
solamente le sostituzioni che portano verso stringhe
sintatticamente corrette. Ad esempio se il campo in
questione è una data, una correzione numerolettera che
porta “2” a diventare “Z”, non ha senso e, grazie a
quest’ottimizzazione, non viene presa in considerazione.
Il package invoiceinspector.fixers contiene:
ErrorFixer: è l’interfaccia implementata da tutti i fixer. È
estesa da SingleFieldFixer per il caso dei fixer singoli ed è
implementata da ImponibileIvaTotaleAliquotaErrorFixer per
il fixer aggregato.
AbstractErrorFixer: è l’implementazione standard di tutti i
fixer singoli ed implementa SingleFieldFixer. Contiene i
35
metodi e le rispettive implementazioni di default, comuni a
tutti i fixer singoli.
Viene estesa da:
o CodiceFiscaleErrorFixer
o ConcatErrorFixer
o CurrencyErrorFixer
o DateErrorFixer
o NumberErrorFixer
o PartitaIvaErrorFixer
o PivaCfGlobalErrorFixer
o RateErrorFixer.
ErrorFixersFactory: è la classe che verrà utilizzata per
scegliere quali fixer vanno caricati per il documento da
analizzare.
Il package invoiceinspector.test contiene alcune classi utilizzate per
testare l’applicazione. Tale package non verrà inglobato nel modulo
finale.
36
VALUTAZIONE SPERIMENTALE
Per effettuare un test significativo, si è considerata una ground-
truth di 76 fatture, per un totale di oltre 500 campi. Ai risultati
ottenuti dal software di riconoscimento è stato associato il valore
atteso per ogni blocco, così come definito da un operatore che ha
analizzato visivamente ogni singola fattura del dataset.
Quest’operazione è di fondamentale importanza in quanto
permette da un lato di capire qual è la percentuale di campi già
corretti prima dell’applicazione dei fixer, dall’altro di verificare che
le correzioni effettuate abbiano portato al risultato sperato.
L’output generato dal modulo di estrazione dei dati, è costituito da
1 file csv (Comma Separated Value) per ogni fattura.
Si è pensato pertanto di costruire un semplice database per gestire
più comodamente una tale quantità di dati. Di seguito se ne riporta
il diagramma fisico.
Figura 12 - Diagramma fisico del DB usato per i test
37
Il software di test estrae dal database una fattura per volta e, sul
set di campi ricavato, esegue i fixer. Dal confronto con i valori attesi
viene poi aggiornata la statistica. L’output finale è una tabella
riassuntiva dei risultati ottenuti.
Si è inoltre verificato che il software sia completamente stateless e
che funzioni correttamente anche in ambiente multithread.
RISULTATI
SENZA FIXER
La tabella seguente mostra la composizione della ground-truth
senza l’applicazione del software di correzione.
OK NOT_OK TOTALE
Data 35 (46%) 41 (54%) 76
P.Iva & C. Fiscale 54 (40%) 81 (60%) 135
N° Fattura 22 (39%) 34 (61%) 56
Imponibile, Totale,
Iva, Aliquota 0 (0%) 76 (100%) 76
Tabella 5 - Situazione ground-truth senza l'applicazione dei fixer
Com’è facilmente intuibile dalle percentuali riportate, l’accuratezza
nella rilevazione del contenuto cercato è, per i campi singoli,
attorno al 40%. Risultati pessimi invece si hanno per il set aggregato
di Imponibile, Iva, Totale ed Aliquota: nessuna delle 4-uple è
corretta. Tuttavia, questo è giustificabile dal fatto che nella maggior
parte delle fatture uno di questi campi non era presente o era
totalmente illeggibile.
Per un’ulteriore visione della situazione descritta, si propone il
seguente grafico: in verde chiaro i valori estratti correttamente
dall’OCR, in rosso quelli non rilevati.
38
Grafico 1 - Situazione ground-truth senza l'applicazione dei fixer
CON I FIXER
I risultati ottenuti dall’applicazione dei fixer sono stati
particolarmente soddisfacenti.
OK OK_FIXED
_BY_FIXER
OK_IN_
MULTIPLE
_RESULTS
SUGGESTED
_VALUE
NOT_
FOUND TOTALE
Data 35 33 (+43%) 1 0 7 76
P.Iva & C.
Fiscale 54 66 (+49%) 0 0 15 135
N° Fattura 22 20 (+36%) 14 0 0 56
Fixer
Aggregato 0 3 (+4%) 0 22 51 76
Tabella 6 - Situazione ground-truth dopo 1° test
Una prima considerazione apparentemente banale ma significativa,
è deducibile dalla prima colonna, etichettata con OK.
Confrontandola con la corrispettiva della tabella precedente infatti,
non si notano differenze e questo dimostra che il software
39
realizzato assolve all’importante requisito di non introdurre errori
in campi già corretti.
La seconda colonna, “OK_FIXED_BY_FIXER”, evidenzia le correzioni
effettuate dai vari fixer. L’incremento di prestazioni è notevole ed
arriva, nel caso migliore, al 49%.
La terza colonna, “OK_IN_MULTIPLE_RESULTS”, conteggia i casi in
cui il valore atteso non è stato trovato in maniera univoca, ma è
presente nel set di possibili candidati. Pertanto un operatore potrà
scegliere la soluzione corretta fra quelle proposte.
La quarta colonna, “SUGGESTED_VALUE”, è una colonna specifica
per il fixer aggregato e sottolinea come il fixer aggregato sia stato in
grado di calcolare e suggerire il valore corretto che completa la
quartina.
La penultima colonna, “NOT_FOUND”, rappresenta gli errori residui
dopo l’applicazione dei fixer.
La situazione è quindi completamente mutata e la percentuale
d’errore di data e partita iva/codice fiscale è attorno al 10% contro
il 60% rilevato in precedenza. Nel caso del numero fattura, il
miglioramento è stato del 36% ma si nota che in molti casi il
risultato corretto fa parte dei risultati multipli proposti dal fixer.
Un miglioramento meno eclatante ma comunque degno di nota si è
ottenuto anche nel caso del fixer aggregato. La cosa
particolarmente interessante è che nel 29% dei casi il fixer è stato in
grado di calcolare correttamente il valore mancante e suggerirlo
all’operatore. Considerando valide anche queste soluzioni, la
percentuale d’errore è passata dal 100% iniziale al 67%.
40
Anche in questo caso si propone un grafico riassuntivo.
Grafico 2 - Situazione post-fixer 1° test
Nonostante i risultati soddisfacenti, si sono volute analizzare le
tipologie di errori residui per verificare che i fixer abbiano svolto
correttamente il loro compito.
L’analisi ha portato alla stesura della tabella 8 consultabile nella
pagina seguente.
41
TIPO CAMPO
VALORE RILEVATO VALORE ATTESO
NOTE
Partita Iva Cod.fise. e Per (. IVA n.00930630324
00930530324 (1)
Partita Iva 00046530323 00048530323 (1)
Partita Iva Cod fise e Pari IVA n 0093053032e 00930530324
Partita Iva 00048630323 00048530323 (1)
Partita Iva I0072016032il 00720160324 (3)
Partita Iva 00720‘l6032lù 00720160324
Partita Iva "007 20 160 2N" 00720160324
Partita Iva 0072016032~I 00720160324 (3)
Partita Iva IVA 00663400325 00653400325 (1)
Partita Iva IVA 00:1.66300327 00166300327 (4)
Partita Iva Cod. Fise. e P. IVA 04209G80168 04209680158 (1)
Partita Iva "cc.i.a.a. 28866 - M. 861097 - Iscr. Trib.4111 - Cod. Part. IVA 00046290327"
00045290327 (1)
Partita Iva c.c.i.a.a. 28865 - 88. 861097 . iacr. Trib.4111 ~ Ccd. Pari. IVrt 000852903
00045290327
Partita Iva "c.c.i.a.a. 28865 - M. 85109? - Iscr. Trib.4111 - Cod Part. IVA 0004529032?"
00045290327 (2)
Partita Iva "c.c.i.a.a 28866 - M 851097 - iscr. Trib.4111 - Cod. Part. IVA 00046290327"
00045290327 (1)
Data "dei.‘ 3 j Q ‘i j QI f" 13/01/07
Data I G/G i/ 07 10/01/07
Data ‘ÙIG I/Q i 20/01/07
Data g ;. 3/01/07 23/01/07
Data ‘‘lr‘G i/G i 24/01/07
Data 17/01/2ùod 17/01/2006
Tabella 7 - Errori Residui dopo 1° test
Immediatamente si può notare che i casi (1), (2) e (3) potrebbero
essere risolti con il seguente aggiornamento della tabella
SubstitutionPairs:
42
STRINGA ERRATA SET[STRINGACORRETTA] TIPO
6 5,8 NumberNumber
? 7 SpecialCharNumber
il 4 Multichar
~I 4 Multichar
Tabella 8 - Aggiornamento SubstitutionPairs
Le ultime righe della tabella errori residui evidenziano, invece,
quello che in precedenza è stato chiamato errore di distruzione del
contenuto per il quale nessuna correzione è possibile.
Di seguito sono descritte le prestazioni (tabella e grafico
riassuntivo) ottenute dopo la modifica alle Substitution Pair.
OK OK_FIXED
_BY_FIXER
OK_IN_
MULTIPLE
_RESULTS
SUGGESTED
_VALUE
NOT_
FOUND TOTALE
Data 35 34 1 0 6 76
P.Iva & C.
Fiscale 54 77 0 0 4 135
N° Fattura 22 34 0 0 0 56
Fixer
Aggregato 0 3 0 22 51 76
Tabella 9 - Situazione ground-truth dopo l'applicazione dei fixer
43
Grafico 3 - Situazione dopo l'applicazione dei fixer
Come ci si aspettava, l’aggiornamento ha dato diversi benefici e la
tabella errori residui aggiornata risulta così:
TIPO CAMPO
VALORE RILEVATO VALORE ATTESO
Partita Iva Cod fise e Pari IVA n 0093053032e 00930530324
Partita Iva 00720‘l6032lù 00720160324
Partita Iva "007 20 160 2N" 00720160324
Partita Iva c.c.i.a.a. 28865 - 88. 861097 . iacr. Trib.4111 ~ Ccd. Pari. IVrt 000852903
00045290327
Data "dei.‘ 3 j Q ‘i j QI f" 13/01/07
Data I G/G i/ 07 10/01/07
Data ‘ÙIG I/Q i 20/01/07
Data g ;. 3/01/07 23/01/07
Data ‘‘lr‘G i/G i 24/01/07
Data 17/01/2ùod 17/01/2006
Tabella 10 - Errori residui dopo 2° Test
Guardando il grafico 3 inoltre, si nota anche un miglioramento delle
prestazioni del fixer per il campo “numero fattura” dovuto
all’aggiornamento dell’algoritmo di elementSelector descritto nel
capitolo Algoritmo del fixer singolo.
44
CONSIDERAZIONI GLOBALI
Si vedranno ora alcuni grafici che mostrano da altri punti di vista i
risultati ottenuti.
I grafici 4 e 5 mostrano rispettivamente la percentuale d’errore
(
) senza e con l’applicazione dei fixer.
Il calcolo tiene conto anche dei campi già corretti prima
dell'applicazione del fixer.
Grafico 4 – Percentuale di errori senza l’applicazione dei fixer
Grafico 5 – Percentuale di errori dopo l’applicazione dei fixer
45
Nel grafico 5, #sbagliate è uguale a:
per
i fixer singoli;
per il fixer
aggregato. Pertanto vengono contati come sbagliati anche i
risultati suggeriti correttamente dal fixer.
In altre parole solo i casi in cui il valore di quality è impostato ad 1.0
sono considerati corretti:
Il grafico 6 evidenzia la percentuale di correzioni fatte o suggerite
rispetto alla totalità dei campi presenti nella ground-truth:
Per i fixer singoli:
Per I fixer aggregati:
Grafico 6 – Percentuale correzioni fatte rispetto al totale
46
Il grafico 7 rappresenta la stessa situazione del grafico 6 ma rispetto
ai soli errori prima dell'applicazione dei fixer:
Per i fixer singoli:
Per I fixer aggregati:
Grafico 7 – percentuali correzioni fatte o suggerite rispetto al totale di errori se non fossero
presenti i fixer
Questo grafico evidenzia quindi l’effettivo miglioramento apportato
dai fixer alla ground-truth. Per i fixer singoli la percentuale di
correzioni applicate è dell’86% per la data, del 95% per partita
Iva/codice Fiscale ed arriva fino al 100% per il campo numero
fattura.
47
PRESTAZIONI
Appurati gli ottimi risultati ottenuti, ci si chiede come siano le
prestazioni complessive del sistema. Per analizzarle si è utilizzato lo
strumento di profiling offerto dalla piattaforma di sviluppo
Netbeans di Sun Microsystems, che permette di verificare quali
metodi occupano per più tempo la CPU e quanta memoria
utilizzano. Per dare un’idea dell’hardware a disposizione, il pc
utilizzato per i test è il notebook del tesista dotato di processore
Intel Core 2 Duo T8300 a 2.40GHz e 4GB di ram.
L’analisi ha preso in considerazione l’esecuzione del programma di
test su tutta la ground-truth ed evidenzia di conseguenza
l’andamento medio del sistema.
Un’attenta revisione del codice ha portato ad un sostanziale
miglioramento delle prestazioni, rispetto alle prime versioni
sviluppate, da vari punti di vista. Sono state realizzate delle
implementazioni alternative più efficienti per le porzioni di codice
critiche. Si è passati in questo modo da poco meno di 1 minuto
impiegato dalla prima versione realizzata, a soli 2 secondi per
l’analisi e la correzione dell’intera ground-truth (oltre 500
elementi). Anche l’occupazione in memoria è calata
considerevolmente: dai 200MB necessari prima della revisione, agli
11MB della versione finale. Questi dati sono stati ottenuti dalla
media di 10 esecuzioni complete del software e la varianza
riscontrata e circa del 4%. Pertanto, mediamente, un fixer è in
grado di correggere un dato in circa 3,5mS.
Infine si è verificato che il tutto funzionasse anche in ambiente
multithreaded mediante l’uso dell’interfaccia ExecutorService che
consente facilmente di creare un thread pool. Sono stati quindi
suddivisi gli esperimenti in 6 thread paralleli che utilizzano in modo
concorrente i fixer.
48
I risultati prodotti in ambiente multithreaded sono stati confrontati
con quelli ottenuti in ambiante non concorrente.
Non sono stati riscontrati problemi di sorta, tuttavia il tempo
impiegato è all’incirca il medesimo; questa situazione è
giustificabile dal fatto che se uno dei campi contiene una parte
consistente di rumore, questo fa sì che vengano generate un gran
numero di combinazioni di possibili risultati; uno dei thread
pertanto rimane bloccato ad eseguire una certa correzione facendo
salire il tempo di esecuzione.
Questo dimostra come la criticità di un sistema di correzione di
questo tipo sia nella generazione di tutte le possibili correzioni per
la stringa data.
49
CONCLUSIONI
Come evidenziato nel capitolo Valutazione sperimentale, i risultati
ottenuti dal componente software realizzato sono stati
particolarmente soddisfacenti sia dal punto di vista delle
funzionalità, sia da quello delle prestazioni in termini di risorse di
calcolo. Pertanto si può affermare che gli obiettivi preposti sono
stati raggiunti.
Il principale problema riscontrato è che essendo un progetto in
continuo sviluppo, si sono presentate in itinere parecchie modifiche
rispetto all’idea originale. Le varie componenti per questo motivo
sono state riviste più volte fino a pervenire alla versione definitiva.
Il lavoro svolto mi ha permesso di approfondire le conoscenze
acquisite riguardo alla programmazione ad oggetti, in particolare
per quanto riguarda il linguaggio Java. Il fatto di dover creare un
componente da inserire in una complessa infrastruttura software,
ha richiesto di sottostare pedissequamente a specifiche molto
restrittive e a paradigmi di programmazione standard che
garantiscono la manutenibilità e l’affidabilità del software.
Per quanto concerne gli sviluppi futuri, si prevede il porting in
produzione del modulo realizzato. Inoltre è facilmente
immaginabile l’estensione del lavoro realizzato a documenti
afferenti ad altre classi sviluppando quindi altri fixer.
50
APPENDICE A: DOCUMENT GENERATOR
Document generator è un software per la generazione di k di
fatture afferenti ad n modelli realizzato dal tesista come attività di
tirocinio presso il laboratorio di reti dell’Università degli studi di
Trieste. Di seguito se ne riportano le specifiche tecniche.
SPECIFICHE TECNICHE
Definizione di modello
Un modello di fattura è dato da:
1. un insieme di modello di blocchi
2. un insieme di modello di tabelle
Ogni modello di blocco ha:
1. id (univoco)
2. tipo (enum: immagine, testo)
3. posizione (x, y) e dimensione (w, h*):
o sono 4 distribuzioni numeriche; per ognuna il
modello comprende il tipo di distribuzione (normale
o uniforme) e i parametri (mu e sigma o min e max)
o nota: per la maggior parte si tratterà di distribuzioni
fisse, cioè normali con sigma=0
o nota: per blocchi di testo ed immagine non si
definisce la distribuzione per h: il valore dell'altezza
del blocco dipenderà da dimensione e quantità di
testo o dalle dimensioni dell'immagine.
4. pagina (int)
5. probabilità di essere presente
6. circondato da riquadro
Solo per i modelli di blocchi di testo:
1. font:
o famiglia
o dimensione
o decorazione (bold, italic, underline)
51
2. tipo etichetta (enum: nessuno oppure tipo)
o il tipo va scelto tra un elenco finito: totale,
imponibile, data, codice fiscale o partita iva cliente,
codice fiscale o partita iva emettitore, numero
fattura)
o deve essere possibile poter aumentare questi tipi in
futuro (non per uno specifico modello, ma per il
generatore di modelli)
3. se il tipo etichetta è diverso da nessuno, tabella di frequenza
delle possibili diciture (mappa chiave=tipo,
valore=probabilità (float))
o la mappa contiene chiavi prese da un insieme
predefinito per ogni tipo, ad esempio per totale:
"totale", "tot.", "importo totale", ecc...
4. tipo valore (enum: nessuno oppure tipo)
o il tipo va scelto tra un elenco finito, stesso discorso
del punto 1
5. se il tipo valore è diverso da nessuno, tabella di frequenza
dei possibili formati (mappa chiave=tipo, valore=probabilità
(float))
o ad esempio per il totale: "€ ###,##", "###.##", "euro
###,##", ...
6. se il tipo valore è diverso da nessuno:
o può esserci un riferimento all'id di un altro blocco
che ha lo stesso tipo valore, che dirà al generatore
che va utilizzato lo stesso valore casuale dentro al
blocco;
o oppure, può esserci un riferimento all'id di una
tabella che ...
7. se tipo etichetta o tipo valore sono entrambi nessuno, tipo
testo (enum: fisso, casuale):
o se fisso: specificare il testo
o se casuale: specificare lunghezza media in caratteri
52
Solo per i modelli di blocchi immagine:
1. Contenuto (enum: fisso, casuale):
o se fisso: specificare l'immagine
o se variabile: specificare l'insieme da cui scegliere a
caso
o nota: le dimensioni sono già specificate dai
parametri del blocco
2. Presente su ogni pagina (boolean)
3. Rotazione (distribuzione numerica, vedi punto 3 del modello
di blocco)
4. Può sovrapporsi (boolean)
o nota: se sì, può sovrapporsi ad altri blocchi, serve per
rappresentare immagini di timbri o cose simili
Ogni modello di tabella ha:
1. id (univoco)
2. posizione (x, y) e dimensione (w), vedi punto 3 del modello
di blocco
3. distanza media tra le righe
4. pagina
5. header (boolean, indica se è presente o meno)
6. header font (vedi punto 1 del modello di blocco di testo)
7. line font (font del resto della tabella)
8. se header è true, nomi colonne (elenco di stringhe)
9. elenco di tipi colonne (stesso numero delle colonne del
punto 6), ogni tipo colonna ha:
o tipo (enum: testo fisso, testo casuale, stringa casuale
formattata)
se testo fisso: il testo fisso
se testo casuale: lunghezza media in caratteri
se stringa casuale formattata: il formato
o probabilità di essere vuota
o larghezza in percentuale della tabella
53
FUNZIONAMENTO
Per rendere semplice l’utilizzo del software si è realizzata
un’interfaccia grafica che permette anche ad un utente non esperto
di generare facilmente modelli e fatture relative.
La tab Genera fatture da Nuovi Modelli permette di creare
dapprima un certo numero di modelli e poi, sulla base di questi,
generare un certo numero di fatture per ogni modello.
Nella generazione di un modello è possibile definire che campi
devono essere presenti e con che cardinalità. Inoltre possono
essere presenti un logo dell’azienda, preso casualmente da un
insieme di immagini, e dei timbri che possono sovrapporsi ad altro
contenuto.
Figura 13 - Document Generator: generazione fatture da nuovi modelli
Per ogni campo è possibile definire:
Se può o meno avere un’etichetta (ad esempio Totale)
prima del valore;
se quest’etichetta può variare tra una fattura e l’altra;
se può esserci uno spazio bianco tra etichetta e nome;
54
qual è la dimensione minima e massima del carattere usato;
qual è l’intensità del nero, per simulare una stampa
degradata.
È possibile definire un certo numero di blocchi di testo con queste
caratteristiche:
il contenuto è generato casualmente a partire da un file
contenente un testo arbitrariamente lungo;
la dimensione dei blocchi di testo è definibile dall’utente.
È possibile definire un certo numero di Tabelle caratterizzate da:
numero minimo e massimo di righe;
numero di colonne;
dimensioni delle tabelle;
presenza o assenza di header
presenza o assenza di bordi
Sulla base dei modelli così generati si possono poi generare un
certo numero di fatture con le seguenti caratteristiche:
Dimensione dell’immagine in pollici e risoluzione in DPI(Dots
Per Inch);
Traslazione e Rotazione dell’immagine per simulare l’effetto
generato da una rotazione della fattura sul piano dello
scanner durante una scansione.
È possibile anche salvare i modelli generati.
55
La tab Genera Fatture da Modelli Preesistenti permette di creare
fatture sulla base di modelli generati in precedenza. L’interfaccia
permette anche di visualizzare un’anteprima del modello che si
vuole utilizzare. Si possono impostare dimensione, traslazione e
rotazione dell’immagine.
Figura 14 - Document Generator: generazione fatture da modelli preesistenti.
È possibile anche eliminare un modello precedentemente salvato.
Nella figura seguente un esempio di fattura generata:
56
Figura 15 – esempio di fattura generata da Document Generator
57
APPENDICE B: FILE DI CONFIGURAZIONE SUBSTITUTIONPAIRS
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : defaultFieldFixers.xml
Created on : 16 ottobre 2010, 11.50
Author : GazzinMatteo
Description:
-->
<typeoffield>
<fixer>
<wrong>N</wrong>
<right>11</right>
</fixer>
<fixer>
<wrong>11</wrong>
<right>N</right>
</fixer>
<fixer>
<wrong>o</wrong>
<right>0</right>
</fixer>
<fixer>
<wrong>O</wrong>
<right>0</right>
</fixer>
<fixer>
<wrong>/</wrong>
<right>1</right>
</fixer>
<fixer>
<wrong>I</wrong>
<right>1</right>
</fixer>
<fixer>
<wrong>I</wrong>
<right>7</right>
</fixer>
<fixer>
<wrong>i</wrong>
<right>1</right>
</fixer>
<fixer>
<wrong>l</wrong>
<right>1</right>
</fixer>
58
<fixer>
<wrong>!</wrong>
<right>1</right>
</fixer>
<fixer>
<wrong>G</wrong>
<right>6</right>
</fixer>
<fixer>
<wrong>Q</wrong>
<right>0</right>
</fixer>
<fixer>
<wrong>D</wrong>
<right>0</right>
</fixer>
<fixer>
<wrong>B</wrong>
<right>8</right>
</fixer>
<fixer>
<wrong>Z</wrong>
<right>2</right>
</fixer>
<fixer>
<wrong>T</wrong>
<right>7</right>
</fixer>
<fixer>
<wrong>S</wrong>
<right>5</right>
</fixer>
<fixer>
<wrong>z</wrong>
<right>2</right>
</fixer>
<fixer>
<wrong>s</wrong>
<right>5</right>
</fixer>
<fixer>
<wrong>0</wrong>
<right>o</right>
</fixer>
<fixer>
<wrong>0</wrong>
59
<right>O</right>
</fixer>
<fixer>
<wrong>1</wrong>
<right>I</right>
</fixer>
<fixer>
<wrong>1</wrong>
<right>i</right>
</fixer>
<fixer>
<wrong>1</wrong>
<right>l</right>
</fixer>
<fixer>
<wrong>1</wrong>
<right>!</right>
</fixer>
<fixer>
<wrong>6</wrong>
<right>G</right>
</fixer>
<fixer>
<wrong>0</wrong>
<right>D</right>
</fixer>
<fixer>
<wrong>8</wrong>
<right>B</right>
</fixer>
<fixer>
<wrong>2</wrong>
<right>Z</right>
</fixer>
<fixer>
<wrong>5</wrong>
<right>S</right>
</fixer>
<fixer>
<wrong>6</wrong>
<right>5</right>
</fixer>
<fixer>
<wrong>6</wrong>
<right>8</right>
</fixer>
60
<fixer>
<wrong>il</wrong>
<right>4</right>
</fixer>
<fixer>
<wrong>~I</wrong>
<right>4</right>
</fixer>
<fixer>
<wrong>?</wrong><!--"?"-->
<right>7</right>
</fixer>
</typeoffield>
61
RINGRAZIAMENTI
Ancora una volta il primo e più grande ringraziamento va agli
sponsor mamma Cela e papà Gigi che con infinita pazienza hanno
saputo attendere questo importante momento. Non potrò mai
ripagare quanto mi è stato incondizionatamente dato in questi
anni. Grazie di cuore.
Ringrazio il mio fratellone Massimo per avermi sopportato quando
gli sbalzi d’umore mi rendevano intrattabile, per tutti gli anni
passati insieme in taverna giocando Barcellona – Real Madrid con il
FIFA di turno e per esserci sempre, in generale… il fratellone è
sempre il fratellone! Lo ringrazio anche per la questione dei 50
euro… anche se solo in pochi potranno capire a cosa mi riferisco… :)
Ringrazio il Prof. Ing. Alberto Bartoli che mi ha dato la possibilità di
realizzare questo elaborato. Lo ringrazio in particolare per le e-mail
di incoraggiamento, che in qualche occasione mi ha inviato, e che
mi hanno spronato a proseguire con entusiasmo il lavoro.
Un doveroso ringraziamento va ai ragazzi del laboratorio: Giorgio in
primis per avermi seguito passo passo nella realizzazione del
progetto, Eric per la correzione della tesi all’ultimo minuto, Marco,
Enrico ed Andrea per essere stati sempre disponibili.
Ringrazio la nonna Maria che purtroppo non sta attraversando un
periodo facile. La ringrazio per avermi sempre sostenuto, per aver
cercato sempre qualche parola di conforto nei momenti difficili e
per quel “Forti Sempre” che ormai è un motto per noi cugini. Spero
che la felicità che deriva dal conseguimento di questo traguardo
possa in qualche modo aiutarla a superare le recenti difficoltà. Un
abbraccio forte forte e mi raccomando, Forti Sempre!
62
Ringrazio la zia Paola e quel “ eh, a coa a crigoa ciuti”, anche lei
purtroppo non attraversa un bel momento, ringrazio la nonna
Mariucci e mi scuso con lei se ultimamente sono passato poche
volte a trovarla.
Ringrazio gli zii dee gafaree Fausti e Stefy che mi chiamano
Ingegnere da quando ho 15 anni! Finalmente ce l’abbiamo fatta!!!
Ringrazio la zia Mari, approfitto per farle anche gli auguri :), e lo zio
Guido. Ringrazio lo zio Paolo per le strette di mano, gli zii Andrea e
Daniela.
Ringrazio i cugini dee gafaree: il cugino grande Andrea, mio
mentore in fatto di scelte di studio; il fratello del cugino grande,
Daniele e gli sconti alla SME :); Davide che era un bambino quando
ho iniziato l’università ed ora è un quasi un uomo… ma questa
credo sia colpa mia :); Filippo che sa a memoria il programmi della
mia dockbar :). Ringrazio anche i cugini deà del punt Alberto e
Chiara.
Ringrazio gli amici senza nominarne nessuno, chi sa di essere
importante per me non ha bisogno d’esser nominato, che
brinderanno e festeggeranno con me questo traguardo raggiunto.
Ringrazio i vecchi compagni d’appartamento: Andrea, Fabio, Nicola,
quel papavero dell’Enz e il rito della pizza al martedì-mercoledì-
giovedì-quandocapita, Claudia ma soprattutto Epsilon, Willy e il fu
Basilio!
Ringrazio infine tutti quelli che la fretta mi ha fatto dimenticare in
queste poche righe e che si meritavano un grazie…
63
BIBLIOGRAFIA
Glassfish. (s.d.). GlassFish - Open source application server. Tratto il
giorno 03 2011 da http://glassfish.java.net/
Holley, R. (2009, Marzo/Aprile). How Good Can It Get? Analysing
and Improving OCR Accuracy in Large Scale Historic Newspaper
Digitisation Programs. Retrieved 03 09, 2011, from
http://www.dlib.org:
http://www.dlib.org/dlib/march09/holley/03holley.html
Kukich, K. (1992). Techniques for Automatically Correcting Words
in. ACM Computing Surveys , 24(4):377–439.
Medvet, E., Bartoli, A., & Davanzo, G. (2010). A probabilistic
approach to printed document understanding. INTERNATIONAL
JOURNAL ON DOCUMENT ANALYSIS AND RECOGNITION .
Ministero delle Finanze. (1977, Gennaio 13). Decreto del 23
dicembre 1976 n. 13813. Tratto il giorno Ottobre 2010 da CeRDEF -
Documentazione economica e finanziaria:
http://dt.finanze.it/DocTribFrontend/RS1_HomePage.jsp
MySql. (s.d.). MySql - The world's most popular open source
database. Tratto il giorno 03 28, 2011 da http://www.mysql.com/
Netbeans. (s.d.). Netbeans. Tratto il giorno 03 28, 2011 da
http://netbeans.org/
Oracle - EJB. (s.d.). Enterprise JavaBeans Technology. Tratto il
giorno 03 2011 da Oracle Technology Network:
http://www.oracle.com/technetwork/java/javaee/ejb/index.html
Oracle - J2EE. (s.d.). Java EE at a Glance. Tratto il giorno 03 2011 da
Oracle Technology Network:
http://www.oracle.com/technetwork/java/javaee/overview/index.
html
64
Sorio, E., Bartoli, A., Davanzo, G., & Medvet, E. (09-2010). Open
World Classification of Printed Invoices. The ACM Symposium on
Document Engineering. Manchester.