Rilevare automaticamente errori di etichettatura nei dataset con CleanLab

Rilevare errori di etichettatura con CleanLab

Una Storia di AI e leggi federali brasiliane classificate in modo errato

Foto di Gustavo Leighton su Unsplash

Introduzione

Qualche settimana fa, mentre cercavo solito dataset per sviluppare i miei progetti personali, ho incrociato il Portale dei Dati Aperti della Camera dei Deputati brasiliana, che contiene molti dati – inclusi i costi dei deputati, i metadati dei partiti, ecc – tutto disponibile tramite un’API ben fatta.

Dopo alcune ore di ricerca e ispezione, qualcosa di molto interessante ha attirato la mia attenzione: la raccolta di tutte le leggi proposte dai parlamentari con le loro ’ementas’ (riassunto conciso), autore, anno e, più importante, i loro temi (salute, sicurezza, finanza, ecc…) – categorizzati dal Centro di Documentazione e Informazione della Camera (Centro de Documentação e Informação da Câmara, traduzione letterale).

Una scintilla ha illuminato il mio cervello – “Creerò un flusso di lavoro di classificazione supervisionata per predire il tema di una legge utilizzando il suo riassunto, esplorando alcuni aspetti infrastrutturali dell’apprendimento automatico, come la versione dei dati con DVC o qualcosa del genere.” Ho scritto velocemente uno script e ho raccolto un ampio dataset che comprende oltre 60.000 leggi, che spaziano dal 1990 al 2022.

Ho già lavorato un po’ con dati giudiziari e legislativi, quindi avevo la sensazione che questo compito non sarebbe stato difficile. Ma, per rendere le cose ancora più facili, ho scelto di classificare solo se una proposta di legge (PL) riguarda “Tributi e date commemorative” o meno (classificazione binaria). In teoria, dovrebbe essere facile, poiché i testi sono molto semplici:

Riassunti originali e una traduzione letterale di ChatGPT - I. Immagine dell'autore.

Ma, non importa cosa abbia cercato di fare, le mie prestazioni non sono mai salite sopra il punteggio f1 di ~0,80, con un richiamo (per la classe positiva) relativamente basso di 0,5-0,7.

Ovviamente, il mio dataset è altamente sbilanciato, con questa classe che rappresenta meno del 5% delle dimensioni del dataset, ma c’è qualcosa di più.

Dopo alcune indagini, ispezionando i dati con query basate su espressioni regolari e osservando i record classificati in modo errato, ho trovato diversi esempi etichettati in modo errato. Con il mio approccio rudimentale, ho trovato circa 200 falsi negativi, che rappresentano circa il 7,5% dei “veri” positivi e lo 0,33% di tutto il mio dataset, senza contare i falsi positivi. Ecco alcuni esempi:

Esempi classificati in modo errato. Immagine dell'autore.

Questi esempi stavano rovinando le mie metriche di validazione – “Quanti di essi potrebbero esistere? Dovrò cercare gli errori manualmente?”

Ma quindi Confident Learning si è materializzato come il pacchetto python Clean Lab, venendo in mio soccorso.

Logo Clean Lab. Immagine da GitHub.

Cos’è Confident Learning?

Etichettare correttamente i dati è uno dei passaggi più dispendiosi in termini di tempo e costi in qualsiasi progetto di apprendimento automatico supervisionato. Tecniche come il crowdsourcing, l’apprendimento semi-supervisionato, il fine-tuning e molte altre cercano di ridurre il costo di raccolta delle etichette o la necessità di tali etichette nell’addestramento del modello.

Fortunatamente, siamo già un passo avanti a questo problema. Abbiamo etichette fornite da professionisti, probabilmente lavoratori governativi con conoscenze adeguate. Ma i miei occhi non professionali con il mio approccio rudimentale basato su espressioni regolari potevano individuare errori non appena superavano le mie aspettative di prestazioni.

Il punto è: quanti errori sono ancora presenti nei dati?

Non è ragionevole ispezionare ogni singola legge — È necessario un modo automatico per rilevare etichette errate, ed è proprio quello che fa Confident Learning.

In sintesi, utilizza statistiche raccolte dalle previsioni di probabilità del modello per stimare gli errori nel dataset. Può rilevare rumore, outlier e — l’argomento principale di questo post — errori di etichetta.

Non entrerò nei dettagli di CL, ma c’è un articolo molto interessante che ne copre i punti principali e un video di YouTube del creatore di CleanLab che parla della sua ricerca in questo campo.

Vediamo come funziona nella pratica.

I dati

I dati sono stati raccolti dal Portale dei Dati Aperti della Camera dei Deputati brasiliana e contengono proposte di legge (LP) dal 1990 al 2022. Il dataset finale contiene circa 60.000 LP.

Una singola LP può avere più temi associati, come Salute e Finanza, e queste informazioni sono disponibili anche nel Portale dei Dati Aperti. Per rendere più facile la gestione, ho codificato le informazioni sui temi binarizzando ciascun tema individuale in una colonna separata.

Come già accennato, il tema utilizzato in questo post è “Omaggi e date commemorative”. L’ho scelto perché le sue emente sono molto brevi e semplici, quindi gli errori di etichetta sono facili da identificare.

I dati e il codice sono disponibili nel repository GitHub del progetto.

L’implementazione

Il nostro obiettivo è correggere automaticamente ogni singolo errore di etichetta in “Omaggi e date commemorative” e concludere questo post con un Dataset bello e pulito pronto per essere utilizzato in un problema di Machine Learning.

Configurare l’ambiente

Tutto ciò di cui hai bisogno per eseguire questo progetto sono i classici pacchetti Python per ML/Data Science (Pandas, Numpy & Scikit-Learn) + il pacchetto CleanLab.

cleanlab==2.4.0scikit-learn==1.2.2pandas>=2.0.1numpy>=1.20.3

Basta installare questi requisiti e siamo pronti.

Rilevare gli errori di etichetta con CL

Il pacchetto CleanLab ha nativamente la capacità di identificare molti tipi di problemi nei dataset, come outlier e voci duplicate/quasi-duplicate, ma saremo interessati solo agli errori di etichetta.

CleanLab utilizza le probabilità generate da un modello di Machine Learning che rappresenta la sua confidenza nell’essere una certa etichetta. Se il dataset ha n voci e m classi, questo sarà rappresentato da una matrice n per m P, in cui P[i, j] rappresenta la probabilità che la riga i sia della classe j.

Queste probabilità e le etichette “vere” vengono utilizzate internamente in CleanLab per stimare gli errori.

Eserciamoci:

Importazione dei pacchetti

import numpy as npimport pandas as pdfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.model_selection import train_test_split, cross_val_score, cross_val_predictfrom sklearn.model_selection import GridSearchCV, StratifiedKFoldfrom sklearn.pipeline import Pipelinefrom sklearn.metrics import accuracy_score, precision_score, recall_score, f1_scorefrom sklearn.metrics import confusion_matrix, classification_reportfrom cleanlab import DatalabRANDOM_SEED = 214np.random.seed(RANDOM_SEED)

caricamento dei dati…

df_pls_theme = pd.read_parquet(    '../../data/proposicoes_temas_one_hot_encoding.parquet')#              "Omaggi e date commemorative"BINARY_CLASS = "Homenagens e Datas Comemorativas"IN_BINARY_CLASS = "in_" + BINARY_CLASS.lower().replace(" ", "_")df_pls_theme = df_pls_theme.drop_duplicates(subset=["ementa"])df_pls_theme = df_pls_theme[["ementa", BINARY_CLASS]]df_pls_theme = df_pls_theme.rename(    columns={BINARY_CLASS: IN_BINARY_CLASS})

Innanzitutto, generiamo le probabilità.

Come menzionato nella documentazione di CleanLab, per ottenere migliori performance è cruciale che le probabilità siano generate su record “non di training” (dati esterni al training). Questo è importante in quanto i modelli tendono naturalmente ad essere troppo fiduciosi quando predicono le probabilità sui dati di training. Il modo più comune per generare probabilità “non di training” in un dataset è utilizzare una strategia K-Fold, come mostrato di seguito:

y_proba = cross_val_predict(    clean_pipeline,     df_pls_theme['ementa'],     df_pls_theme[IN_BINARY_CLASS],    cv=StratifiedKFold(n_splits=5, shuffle=True, random_state=RANDOM_SEED),     method='predict_proba',     verbose=2,    n_jobs=-1)

NOTA: È importante essere consapevoli della distribuzione delle classi – quindi l’oggetto StratifiedKFold. La classe scelta rappresenta meno del 5% del dataset, un approccio di campionamento ingenuo potrebbe facilmente portare a probabilità di scarsa qualità generate da modelli addestrati su dataset sbilanciati in modo errato.

CleanLab utilizza una classe chiamata Datalab per gestire i suoi task di rilevamento degli errori. Riceve il DataFrame contenente i nostri dati e il nome della colonna delle etichette.

lab = Datalab(    data=df_pls_theme,    label_name=IN_BINARY_CLASS,)

Ora, dobbiamo solo passare le probabilità calcolate in precedenza …

lab.find_issues(pred_probs=y_proba)

… per iniziare a trovare problemi

lab.get_issue_summary("label")

E’ semplice come quello.

La funzione get_issues(“label”) restituisce un DataFrame con le metriche e gli indicatori calcolati da CleanLab per ogni record. Le colonne più importanti sono ‘is_label_issue’ e ‘predicted_label’, che rappresentano rispettivamente se un record ha un problema di etichetta e l’etichetta corretta possibile per esso.

lab.get_issues("label")

Possiamo unire queste informazioni nel DataFrame originale per ispezionare quali esempi sono problematici.

# Getting the predicted errorsy_clean_labels = lab.get_issues("label")[['predicted_label', 'is_label_issue']]# adding them to the original datasetdf_ples_theme_clean = df_pls_theme.copy().reset_index(drop=True)df_ples_theme_clean['predicted_label'] = y_clean_labels['predicted_label']df_ples_theme_clean['is_label_issue'] = y_clean_labels['is_label_issue']

Controlliamo alcuni esempi:

Per me, queste leggi sono chiaramente associate a Tributi e Date Commemorative; tuttavia, non sono categorizzate correttamente come tali.

Bene! – CleanLab è stato in grado di trovare 312 errori di etichetta nel nostro dataset, ma cosa fare ora?

Questi errori potrebbero essere oggetto di un’ispezione manuale per la correzione (in modo attivo) o corretti istantaneamente (supponendo che CleanLab abbia fatto il suo lavoro correttamente). Il primo metodo richiede più tempo ma potrebbe portare a risultati migliori, mentre il secondo è più veloce ma potrebbe generare più errori.

Indipendentemente dal percorso scelto, CleanLab ha ridotto il lavoro da 60.000 record a qualche centinaio – nel caso peggiore.

Ma c’è un problema.

Come possiamo essere sicuri che CleanLab abbia trovato tutti gli errori nel dataset?

In realtà, se eseguiamo la pipeline sopra ma con gli errori corretti come ground truth, CleanLab troverà più errori…

Più errori, ma si spera meno errori rispetto alla prima esecuzione.

E possiamo ripetere questa logica quante volte vogliamo: Trova errori, correggi errori, addestra nuovamente il modello con le etichette considerate di migliore qualità, trova nuovamente errori…

Fixing errors iteratively. Image by Author.

Con la speranza che dopo alcune iterazioni il numero di errori sarà zero.

Correzione iterativa degli errori con CleanLab

Per implementare questa idea, tutto ciò che dobbiamo fare è ripetere il processo sopra in un ciclo, il codice di seguito fa proprio questo:

Analizziamolo.

In ogni iterazione, le probabilità OOS vengono generate proprio come mostrato in precedenza: utilizzando il metodo cross_val_predict con StratifiedKFold. L’attuale insieme di probabilità (in ogni iterazione) viene utilizzato per costruire un nuovo oggetto Datalab e trovare i nuovi problemi di etichettatura.

I problemi trovati vengono uniti all’insieme di dati corrente e risolti.

Ho scelto la strategia di aggiungere le etichette corrette come una nuova colonna anziché sostituire quella originale.

Aggiunta delle etichette corrette. Immagine dell'autore.

LABEL_COLUMN_0 è l’etichetta originale, LABEL_COLUMN_1 è la colonna delle etichette corrette 1 volta, LABEL_COLUMN_2 è la colonna delle etichette corrette 2 volte, e così via…

In aggiunta a questo processo, vengono calcolate e memorizzate anche le solite metriche di classificazione per ispezioni successive.

Dopo 8 iterazioni (~16 minuti) il processo è completo.

I Risultati

La tabella sottostante mostra le metriche di performance calcolate durante il processo.

Sono stati trovati un totale di 393 errori di etichettatura nel dataset nelle 8 iterazioni. Come previsto, il numero di errori trovati è diminuito ad ogni iterazione.

È interessante notare che questo processo è stato in grado di “convergere” verso una “soluzione” con solo 6 iterazioni, rimanendo a 0 errori nelle ultime 2. Questo è un buon segno che, in questo caso, l’implementazione CleanLab è robusta e non ha trovato altri errori per ‘caso’ che potrebbero portare a oscillazioni.

Anche se il numero di errori rappresenta solo lo 0,6% del dataset, lo score f1 è aumentato da 0,81 a 0,90, circa l’11%. Questo è probabilmente dovuto alle classi che sono fortemente sbilanciate, in quanto le nuove 322 etichette positive rappresentano circa il 12% del numero di esempi positivi originali.

Ma CleanLab è stato davvero in grado di trovare errori significativi? Controlliamo alcuni esempi per vedere se hanno senso.

Falsi negativi corretti

Sommari originali e una traduzione letterale di ChatGPT - II. Immagine dell'autore.

I testi sopra assomigliano effettivamente a “tributi e date commemorative”, suggerendo che dovrebbero essere categorizzati correttamente come tali – Punto per CleanLab

Falsi positivi corretti

Sommari originali e una traduzione letterale di ChatGPT - III. Immagine dell'autore.

In questo caso abbiamo alcuni errori, le leggi 2 e 4 non sono falsi positivi. Non così buono, ma comunque accettabile.

Ho ripetuto questa ispezione campionando nuove leggi ‘corrette’ diverse volte e, in generale, CleanLab ha una performance quasi perfetta nel rilevare falsi negativi ma si confonde un po’ con i falsi positivi.

Ora, anche se probabilmente non abbiamo un dataset perfettamente etichettato, mi sento molto più fiducioso nel formare un modello di apprendimento automatico su di esso.

Conclusione

Per molto tempo l’area dell’apprendimento automatico ha sofferto di modelli di scarsa qualità e mancanza di potenza di calcolo, ma questo tempo è passato. Ora, il vero collo di bottiglia per la maggior parte delle applicazioni di ML è il dato. Ma non il dato grezzo, il dato raffinato, con buone etichette, ben formattato, senza troppi rumori o outlier.

Perché non importa quanto grande e potente sia un modello, quanta statistica e matematica mescoli nel tuo flusso di lavoro, nulla di tutto questo ti salverà dalla legge più elementare dell’informatica: spazzatura in, spazzatura fuori.

E questo progetto è stato testimone di questo principio: ho testato diversi modelli, architetture di Deep Learning, tecniche di campionamento e metodi di vettorizzazione per scoprire, alla fine, che il problema era nelle basi: i miei dati erano errati.

In uno scenario del genere, investire in tecniche di qualità dei dati è diventato un aspetto critico per creare progetti di ML di successo.

In questo post, abbiamo esplorato CleanLab, un pacchetto che ci ha aiutato a individuare e correggere etichette errate nel dataset. Non solo ci ha permesso di migliorare significativamente la qualità del nostro dataset, ma lo ha fatto in modo automatico, riproducibile ed economico, senza intervento umano.

Spero che questo progetto ti abbia aiutato a capire un po’ di più su Confident Learning e sul pacchetto CleanLab. Come sempre, non sono un esperto di nessuna delle materie affrontate in questo post e consiglio vivamente di approfondire leggendo ulteriori riferimenti.

Grazie per aver letto! 😉

Riferimenti

Tutto il codice è disponibile in questo repository GitHub. Dati utilizzati – Portale Dati Aperti Camera dei Deputati Federali. [Open-Data – Legge nº 12.527]Tutte le immagini sono create dall’Autore, salvo diversa specificazione.

[1] Cleanlab. (s.d.). GitHub – cleanlab/cleanlab: Il pacchetto standard di intelligenza artificiale centrato sui dati per la qualità dei dati e l’apprendimento automatico con dati e etichette reali e disordinati. GitHub. [2] Calcolo delle probabilità previste fuori campione con la cross-validation – cleanlab. (s.d.). [3] Databricks. (2022, 19 luglio). CleanLab: AI per individuare e correggere errori nei dataset di ML [Video]. YouTube. [4] FAQ – cleanlab. (s.d.). [5] Mall, S. (2023, 25 maggio). Gli errori delle etichette sono imperativi? È utile il confident learning? VoAGI. [6] Northcutt, C. G. (2021). Confident Learning: Stima dell’incertezza nelle etichette del dataset. arXiv.org.