THESISSIMO è un sistema avanzato di ricerca documentale progettato per permettere agli studenti, ricercatori e professionisti di cercare tra decine di migliaia di documenti scientifici. Il sistema implementa tre motori di ricerca differenti (PostgreSQL, PyLucene, Whoosh) con algoritmi di ranking avanzati e tecniche di Natural Language Processing per garantire risultati precisi e rilevanti.
- PostgreSQL: Full-text search con
ts_rankets_rank_cd. - PyLucene: Motore basato su Apache Lucene con
BM25SimilarityeClassicSimilarity(TF-IDF). - Whoosh: Search engine Python puro con
BM25FeTF_IDF.
- Espansione Semantica delle Query: Utilizzo di WordNet per arricchire le query con sinonimi, iperonimi e iponimi.
- Estrazione Automatica di Keyword: YAKE! (Yet Another Keyword Extractor) per identificare i termini più significativi.
- Lemmatizzazione e POS Tagging: NLTK per normalizzare le parole alla loro forma base e identificarne il ruolo grammaticale, migliorando la qualità dell'espansione e della ricerca.
- Analizzatori Personalizzati: StemmingAnalyzer in Whoosh per una migliore corrispondenza morfologica.
- Metriche Standard IR: Calcolo di Precision@k, Recall@k e Mean Average Precision (MAP).
- Pooling Method: Creazione di un ground truth affidabile aggregando i top N risultati da tutti i motori e algoritmi di ranking.
- Analisi Comparativa: Visualizzazioni dettagliate delle performance dei motori (precision-recall curves, box plots, bar charts) generate con Matplotlib e Seaborn.
- Analisi dei Tempi di Risposta: Misurazione e confronto della velocità di ricerca dei diversi motori.
- Dashboard Multi-Engine: Selezione facile del motore di ricerca desiderato.
- Filtri Dinamici: Possibilità di restringere la ricerca a campi specifici (titolo, abstract, corpus).
- Visualizzazione Metriche in Real-Time: Grafici precision-recall direttamente nell'interfaccia utente per Whoosh e PyLucene (se implementato).
- Design Responsive: Accessibile e facile da usare su diversi dispositivi.
- Generazione URL Dinamica: Modulo
UrlGenerator.pyper creare liste di URL da sorgenti accademiche. - Scraping Multi-Threaded con Pause/Resume:
Scraper.pypermette di interrompere e riprendere il processo di scraping. - Rotazione User-Agent e Rate Limiting: Tecniche per evitare il blocco da parte dei server.
- Pulizia Avanzata dei Dati:
CleanDocuments.pyeDocManipulation.pyper normalizzare il testo, rimuovere artefatti LaTeX, caratteri Unicode problematici e formule matematiche, operando in batch per efficienza.
THESISSIMO/
│
├── Benchmark/ # Sistema di valutazione e benchmark
│ ├── Results/ # Risultati dei benchmark (es. benchmark_results.json) e grafici generati
│ ├── benchmark.py # Script principale per l'esecuzione dei benchmark e generazione grafici
│ └── create_pool.py # Script per creare il pool di documenti per la relevance judgment (ground truth)
│
├── SearchEngine/ # Implementazioni dei motori di ricerca
│ ├── index/ # Directory per gli indici di PyLucene
│ ├── WhooshIndex/ # Directory per gli indici di Whoosh
│ ├── Pylucene.py # Implementazione del motore di ricerca PyLucene
│ ├── Whoosh.py # Implementazione del motore di ricerca Whoosh
│ ├── Postgres.py # Implementazione della ricerca full-text con PostgreSQL
│ └── Queries.py # Utility per la connessione e gestione query al DB PostgreSQL
│
├── WebApp/ # Interfaccia utente web basata su Streamlit
│ ├── mainPage.py # Pagina principale per la selezione del motore di ricerca
│ ├── PyLuceneUI.py # Interfaccia utente per PyLucene
│ ├── WhooshUI.py # Interfaccia utente per Whoosh
│ └── PostgresUI.py # Interfaccia utente per PostgreSQL
│
├── WebScraping/ # Moduli per il web scraping e processamento dati
│ ├── results/ # File JSON contenenti i dati grezzi e puliti
│ │ ├── Docs.json # Documenti grezzi estratti dallo scraping
│ │ ├── Docs_cleaned.json # Documenti puliti pronti per l'indicizzazione
│ │ └── CleanDocuments.py # Script per la pulizia avanzata dei documenti
│ └── src/ # Codice sorgente per lo scraping
│ ├── Scraper.py # Scraper principale con gestione multi-threading e pause/resume
│ ├── DocManipulation.py # Funzioni per la manipolazione e salvataggio dei documenti
│ └── UrlGenerator.py # Generatore di URL per lo scraping
│
├── forces-*/ # File relativi alla documentazione (es. Doxygen)
│ └── doc/doxygen-awesome-css/
│ ├── Doxyfile
│ └── Logo.png
│
├── uin.txt # User Information Needs: query di test per il benchmark
├── requirements.txt # Dipendenze Python del progetto
└── README.md # Questo file
Il progetto THESISSIMO segue un flusso di lavoro strutturato, dalla raccolta dei dati alla loro valutazione.
La fase iniziale consiste nella raccolta dei documenti scientifici.
- Generazione degli URL (
UrlGenerator.py): Questo script è responsabile della creazione della lista di URL target da cui verranno estratti i documenti. - Estrazione dei Contenuti (
Scraper.py):- Utilizza
requestseBeautifulSoupper scaricare e parsare le pagine HTML. - Implementa la rotazione degli User-Agent (
get_random_user_agent) per simulare accessi da browser diversi e ridurre il rischio di blocco. - Introduce pause (
time.sleep(2)) tra le richieste per non sovraccaricare i server. - Supporta la funzionalità di pause e resume tramite un
threading.Event(pause_event), permettendo all'utente di controllare il processo di scraping in tempo reale tramite input da console (monitor_input). - Estrae campi chiave come titolo (da
<h1>), abstract (da<div class_='ltx_abstract'>), corpo del testo (da<p>) e keywords (daltx_keywordsoltx_classification). - Gestisce eccezioni come errori di connessione o status code HTTP problematici (es. 403).
- I risultati grezzi vengono salvati in
WebScraping/results/Docs.jsontramiteDocManipulation.addToJson.
- Utilizza
- Pulizia Avanzata dei Documenti (
CleanDocuments.py):- Legge i documenti da
Docs.jsonin batch utilizzandoijsonper un processamento efficiente in termini di memoria. - La funzione
clean_mathematical_textrimuove:- Artefatti di conversione HTML e messaggi di errore.
- Sequenze specifiche Unicode e caratteri di controllo (
remove_control_characters). - Espressioni LaTeX e formule matematiche (es. testo tra
$ $). - Spazi multipli e parentesi vuote.
- I documenti puliti vengono salvati in
WebScraping/results/Docs_cleaned.json, pronti per l'indicizzazione da parte dei motori di ricerca. - Lo script
Scraper.pyorchestra anche l'importazione dei dati puliti in PostgreSQL tramitejsonToPGdopo aver resettato la tabella conresetTable.
- Legge i documenti da
Una volta puliti, i documenti vengono indicizzati dai tre motori di ricerca implementati.
Basato su Apache Lucene, offre performance elevate e funzionalità di ricerca avanzate.
- Inizializzazione JVM:
initialize_jvm()assicura che la Java Virtual Machine sia avviata correttamente. - Indicizzazione:
create_index(): Crea un nuovo indice inSearchEngine/index/se non esiste, altrimenti apre quello esistente.- Utilizza
StandardAnalyzerper l'analisi del testo. - I documenti da
Docs_cleaned.jsonvengono letti conijsone aggiunti all'indice comeDocumentLucene, con campiStringField(per ID) eTextField(per titolo, abstract, corpus, keywords, url). - Supporta commit periodici durante l'indicizzazione di grandi volumi di dati.
- Ricerca:
search_documents(): Permette la ricerca specificando i campi (titolo, abstract, corpus) e il tipo di ranking.- NLP Query Expansion:
expand_query()arricchisce la query dell'utente utilizzando:- YAKE!: Per estrarre le keyword principali.
- NLTK: Tokenizzazione, POS tagging (
get_wordnet_pos), lemmatizzazione (WordNetLemmatizer) e rimozione di stopwords. - WordNet: Per trovare sinonimi, iperonimi e iponimi, espandendo la portata semantica della ricerca.
- La query espansa viene formattata per Lucene (termini uniti da
OR, keyword originali con boost^2).
- Costruisce una
BooleanQuerycombinando le clausole per i campi selezionati conBooleanClause.Occur.SHOULD.
- Ranking:
- Supporta
BM25Similarity(default) eClassicSimilarity(TF-IDF).
- Supporta
- Metriche:
calculate_precision_recall()calcola precision e recall basandosi su uno score threshold adattivo, eplot_precision_recall_curve()(commentata nel codice fornito, ma l'intenzione c'è) visualizzerebbe questi dati.
Un motore di ricerca interamente scritto in Python, facile da integrare e configurare.
- Setup NLTK:
setup_nltk()scarica le risorse NLTK necessarie (WordNet, tagger, stopwords). - Schema e Indicizzazione:
create_schema(): Definisce la struttura dei documenti nell'indice, utilizzandoStemmingAnalyzerper i campi testuali per migliorare il matching.create_or_get_index(): Gestisce la creazione o l'apertura dell'indice inSearchEngine/WhooshIndex/. Può forzare la ricostruzione dell'indice.index_documents(): Popola l'indice leggendo i dati daDocs_cleaned.jsonin batch (usandoijson) per efficienza.
- Ricerca:
search_documents(): Funzione principale per la ricerca.- NLP Query Expansion:
process_natural_query()espande la query in modo simile a PyLucene, usando YAKE, NLTK (tokenizzazione, POS tagging, lemmatizzazione) e WordNet (sinonimi, iperonimi, iponimi). La query risultante è una stringa di termini uniti daOR. - Query Parsing Avanzato:
parse_advanced_query()gestisce query complesse che includono specificatori di campo (es.title:"deep learning" AND corpus:python) e operatori booleani. Per query semplici senza operatori, utilizzaMultifieldParser. - Utilizza
OrGroupper combinare i termini di ricerca sui campi selezionati.
- Ranking:
- Supporta
BM25F(default, adatto per campi multipli) eTF_IDF.
- Supporta
Sfrutta le capacità di full-text search del database relazionale PostgreSQL.
- Connessione al DB: Utilizza
dbConn()daQueries.pyper stabilire la connessione. - Preparazione Testo per Ricerca: PostgreSQL gestisce internamente la tokenizzazione e lo stemming tramite
tsvectoreto_tsquerycon dizionario 'english'. - Ricerca:
search(): Funzione principale che gestisce due modalità di query:- Query Avanzate con Campi Specifici:
parse_advanced_query()interpreta query cometitle:space AND corpus:python, costruendo la clausolaWHEREappropriata per SQL. - Query Basate su Checkbox e NLP: Se la query è in linguaggio naturale,
extract_keywords()(utilizzando NLTK POS tagging e rimozione di stopwords) estrae i termini significativi.build_search_query()costruisce quindi la query SQL.
- Query Avanzate con Campi Specifici:
- Utilizza
phraseto_tsqueryper ricerche di frasi eto_tsqueryper termini singoli (spesso combinati con&per AND logico).
- Ranking:
- Supporta le funzioni di ranking di PostgreSQL
ts_rankets_rank_cd. - La clausola
ORDER BY rank DESCordina i risultati per rilevanza.
- Supporta le funzioni di ranking di PostgreSQL
Per valutare oggettivamente le performance dei motori di ricerca, è stato implementato un sistema di benchmark.
- User Information Needs (
uin.txt):- Contiene un set di 10 query di test rappresentative di diverse aree scientifiche. Ogni UIN è accompagnata da una query strutturata di esempio (es.
abstract:"symmetry" AND corpus:"field theory").
- Contiene un set di 10 query di test rappresentative di diverse aree scientifiche. Ogni UIN è accompagnata da una query strutturata di esempio (es.
- Creazione del Ground Truth (Processo a Due Fasi):
- Generazione del Pool Iniziale (
create_pool.py):- Implementa il pooling method.
- Carica le query da
uin.txt. - Esegue ogni query su tutti e tre i motori di ricerca (PyLucene, Whoosh, PostgreSQL) utilizzando i loro diversi algoritmi di ranking (es. BM25, TF-IDF per PyLucene/Whoosh; ts_rank, ts_rank_cd per PostgreSQL).
- Colleziona i top N risultati (default
TOP_N_FOR_POOLING = 20) da ogni combinazione motore/ranking. - Unisce tutti i documenti recuperati per una data query in un set unico (
unique_doc_ids_for_query). - Salva questi "pool" di documenti in
GroundTruth/Pool.json. Questo file contiene la lista dei documenti da giudicare.
- Creazione dei Giudizi di Rilevanza (Manuale):
- Il file
GroundTruth/Pool.jsondeve essere revisionato manualmente da un esperto. - Per ogni query nel
Pool.json, l'esperto deve giudicare la rilevanza di ciascun documento associato. - I risultati di questa valutazione manuale devono essere salvati in un nuovo file chiamato
GroundTruth/JudgedPool.json. Questo file conterrà, per ogni query, una mappa di ID documento e il relativo giudizio di rilevanza (es. 1 per rilevante, 0 per non rilevante).
- Il file
- Generazione del Pool Iniziale (
- Esecuzione dei Benchmark (
benchmark.py):- Carica le query da
uin.txte i giudizi di rilevanza dal fileGroundTruth/JudgedPool.json(creato manualmente). - Per ogni query e per ogni motore/algoritmo di ranking:
- Esegue la ricerca.
- Misura il tempo di risposta.
- Calcola le metriche di Information Retrieval:
- Precision@k (P@5, P@10, P@20)
- Recall@k (R@5, R@10, R@20)
- Average Precision (AP) per ogni query.
- Calcola il Mean Average Precision (MAP) per ogni motore/configurazione.
- Salva i risultati aggregati in
Benchmark/Results/benchmark_results.json. - Generazione Grafici:
plot_precision_recall_metrics(): Crea grafici (box plot, bar plot, istogrammi) per P@k, R@k, AP e tempi di risposta per ogni singolo motore, salvandoli inPlots/[EngineName]/.plot_comparative_analysis(): Genera grafici comparativi (bar chart per MAP, P@k, R@k; heatmap) tra tutti i motori, salvandoli inPlots/Comparative/.
- Carica le query da
L'applicazione web, costruita con Streamlit, permette agli utenti di interagire con i motori di ricerca.
mainPage.py: Pagina di ingresso che permette all'utente di selezionare quale motore di ricerca utilizzare (Postgres, Whoosh, PyLucene). Avvia l'interfaccia specifica come subprocess.PostgresUI.py,WhooshUI.py,PyLuceneUI.py:- Forniscono un'interfaccia dedicata per ogni motore.
- Consentono all'utente di inserire una query di ricerca.
- Offrono la possibilità di selezionare il tipo di algoritmo di ranking (es. "TF_IDF" o "BM25" per PyLucene/Whoosh, "ts_rank" o "ts_rank_cd" per PostgreSQL).
- Permettono di filtrare la ricerca per campi specifici (titolo, abstract, corpus) tramite checkbox.
- Visualizzano i risultati della ricerca, includendo titolo, abstract (espandibile), keywords, punteggio di rilevanza e un link al documento originale.
WhooshUI.pyePyLuceneUI.pyincludono (o sono predisposti per includere) la visualizzazione di grafici precision-recall per la query corrente.
- Python 3.8+
- Java 11+ (per PyLucene)
- PostgreSQL 13+ (per il motore di ricerca PostgreSQL)
- Git
git clone https://github.com/dataoys/Thesissimo.git # Sostituisci con il tuo URL effettivo
cd ThesissimoÈ consigliato utilizzare un ambiente virtuale:
python -m venv venv
source venv/bin/activate # Linux/macOS
# venv\Scripts\activate # Windows
pip install -r requirements.txt- Installa PostgreSQL (consulta la documentazione ufficiale per il tuo OS).
- Crea un database e un utente per THESISSIMO:
CREATE DATABASE juriscan; CREATE USER juriscan_user WITH PASSWORD 'password'; -- Scegli una password sicura GRANT ALL PRIVILEGES ON DATABASE juriscan TO juriscan_user;
- Assicurati che le credenziali in
SearchEngine/Queries.py(o dove sono definite) corrispondano.
- Installa un JDK (Java Development Kit), versione 11 o superiore. Assicurati che
JAVA_HOMEsia configurato. - L'installazione di PyLucene tramite
pip install PyLucenedovrebbe funzionare se l'ambiente Java è configurato correttamente. Potrebbero essere necessari passaggi aggiuntivi a seconda del sistema operativo (vedi documentazione PyLucene).
Esegui uno script Python una tantum o integra nel setup:
import nltk
nltk.download('punkt')
nltk.download('averaged_perceptron_tagger') # o 'averaged_perceptron_tagger_eng'
nltk.download('stopwords')
nltk.download('wordnet')
nltk.download('omw-1.4') # Open Multilingual WordNet, spesso richiesto da WordNetGli script SearchEngine/Whoosh.py e SearchEngine/Pylucene.py tentano di scaricare queste risorse se mancanti.
python WebScraping/src/Scraper.pyQuesto script eseguirà lo scraping, la pulizia e l'importazione in PostgreSQL.
- PyLucene:
(Rimuovere il commento da
python SearchEngine/Pylucene.py
if __name__ == "__main__":nel file per eseguirlo) - Whoosh:
(Lo script è già configurato per creare/aggiornare l'indice se eseguito direttamente)
python SearchEngine/Whoosh.py
streamlit run WebApp/mainPage.pyQuesto avvierà la pagina principale da cui potrai selezionare e lanciare le interfacce dei singoli motori di ricerca.
- Crea il Pool Iniziale per il Ground Truth:
Questo genererà
python Benchmark/create_pool.py
GroundTruth/Pool.json. - Crea Manualmente
JudgedPool.json: Dopo aver eseguitocreate_pool.py, apriGroundTruth/Pool.json. Per ogni query, valuta la rilevanza dei documenti elencati. Crea un nuovo file,GroundTruth/JudgedPool.json, e inserisci i tuoi giudizi seguendo il formato:{ "query text from uin.txt": { "doc_id_1": 1, // 1 per rilevante, 0 per non rilevante "doc_id_2": 0 }, "altra query...": { "doc_id_x": 1 } } - Esegui i Benchmark:
Questo script utilizzerà
python Benchmark/benchmark.py
JudgedPool.jsonper calcolare le metriche e genererà i grafici comparativi e specifici per motore inPlots/e i risultati numerici dettagliati (incluse le metriche per query) inBenchmark/Results/benchmark_results.json.
THESISSIMO - Rivoluzionando la ricerca documentale scientifica con AI e tecnologie avanzate 🚀
