Classificatore binario con Weka [Alberi di decisione J48]

Ciao a tutti,
parte dell'esame di Intelligenza Artificiale consisteva nel presentare un progettino nel quale, attraverso il programma Weka, dovevo ritrovare dei dati nello spirito di un articolo scientifico.
Non sarò qua a mostrarvi i risultati che ho ottenuto perchè, giustamente, non frega una cippa a nessuno. Sfrutterò questo articolo per raccontare un po' come ci si muove in Weka per quello che avevo da fare.Comincio con il dire che uno degli obiettivi era quello di creare un albero di decisione in un certo modo con l'algoritmo J48 di Weka (che sarebbe l'implementazione Java open source del C4.5) da un training set dato.
Il training set nel mio caso era costituito da una sfilza di geni che venivano classificati come essenziali o non essenziali e lo scopo dell'algoritmo era quello di creare un albero di decisione (binario quindi) che mi classificasse questa feature su geni non ancora studiati.

File .ARFF

I file utilizzati sono in formato .ARFF vediamo brevemente la sintassi e la semantica.

Questo è un piccolo estratto:

A parte l'header, indicato con la parola chiave @relation, il file si suddivide in due parti:

  1. la dichiarazione degli attributi.

    Per dichiararne uno si usa la parola chiave @attribute seguito dal nome dell'attributo (o feature) e di seguito una il tipo dell'attributo ({0,1} vuol dire che l'attributo può assumere il valore 0 o 1, numeric un valore reale ecc..)
  2. la dichiarazione dei dati.
    Si concatenano una serie di valori separati da virgola. L'ordine è importante perchè il primo dato della riga corrisponde al primo attributo,  il secondo della riga al secondo attributo e così via.
    C'è la possibilità che alcuni attributi per qualche istanza non siano specificati, in tal caso il valore sarà indicato con il carattere ? (eventualità che può essere trattata dal C4.5)

Per ulteriori informazioni sul formato ARFF date un occhio qui

Come operare

La cosa che mi ha creato un po' più di difficoltà è stata quella di orientarmi all'interno di un programma che offre tante funzionalità e impostazioni.
In questo articolo ci limiteremo a capire che cosa va toccato, quali manopole girare e come.

Iniziamo semplicemente con aprire il programma (gli screen fanno riferimento alla versione 3.7.6) e entrare nella sezione Explorer.
Si aprirà una finestra sulla sezione di Preprocess.
Procediamo col premere il pulsante Open file... e a selezionare il nostro training set (il formato è l' arff).
Caricato il file, l'interfaccia si riempirà dei dati del file. Nella sezione attributes troveremo tutti gli attributi del set descritti dalla parola chiave  @attribute del file arff.
Sulla destra quadrettato in rosso viene selezionato l'ultimo attributo (che in questo caso è anche l'attributo su cui devo costruire il classificatore).

Selezionando un attributo nella lista degli attributi, sulla destra si visualizzerà un istogramma che ci descrive quale è la relazione tra le istanze con quell'attributo e il e l'attributo SGD-ess.

Cliccando su Visualize All si può avere una panoramica sui dati da trattare.

La feature SGD-ess rappresenta l’essenzialità ed è 0 se l’esempio è non essenziale (nella Figura sopra in blu) e 1 se invece è essenziale (nella  Figura sopra in rosso).

Ora passiamo alla sezione Classify in alto nella schermata accanto a Preprocess.
É qui che viene creato l'albero di decisione.
Cliccare quindi su Choose per andare a scegliere l'algoritmo che vogliamo utilizzare per la creazione del classificatore binario.
Nel nostro caso ci interessa il C4.5 quindi andremo a selezionare weka->classifiers->trees->J48 come mostrato in figura.

Ora la parte più interessante: cliccando sulla barra adiacente al pulsante Choose si aprirà una nuova schermata.

Queste sono le manopole da girare a cui avevo accennato prima.
Vediamo un po' quelle più importanti:

  1. unpruned: questa opzione se falsa ci restituisce l’albero di decisione potato secondo il metodo standard del C4.5.
  2. confidenceFactor: questa opzione è importante per determinare quanto dovrebbe essere specifico o generico il modello. Se abbiamo poca fiducia nel nostro training data (il che corrisponde a un basso “fattore di fiducia”), l’errore stimato per ogni nodo cresce, incrementando la probabilità di potatura a favore di un nodo più stabile a monte.
  3. minNumObj: altra opzione per determinare la specificità del modello. Esso indica il minimo numero di istanze per foglia. Più alto è il numero, più generico è l’albero.
  4. reducedErrorPruning è un altro tipo di potatura in sostituzione di quello del C4.5. A questo metodo sono legate anche le opzioni seed e numFolds. Tuttavia per il reducedErrorPruning non è possibile dare una misura che permetta di regolare il grado di potatura dell’albero, quindi questi campi sono stati ignorati.
  5. subTreeRaising: è un secondo metodo di pruning. In questo caso, un nodo può essere spostato in alto verso la radice, rimpiazzando altri nodi lungo il percorso.  Questo metodo ha un effetto trascurabile sugli alberi di decisione. Non si riesce a prevedere l’utilità in modo chiaro di questa opzione. Tuttavia può essere utile disattivarlo se il processo di induzione richiede molto tempo per via del suo alto costo computazionale.
  6. useMDLcorrection: se vera applica l’euristica del Minimum Description Length.

Per ulteriori informazioni sul minNumObj e sul metodo di post pruning rimando a questo articolo.

Si noti che in base ai settaggi, l'area accanto al pulsante Choose cambia.
Questi sono i comandi che è possibile usare da linea di comando (rimando alla documentazione) e possono dare anche un'idea su cosa può essere utilizzato con cosa.

Tornando alla sezione Classify, procediamo con la selezione della 10 folds Cross-validation e con lo scegliere l'attributo su cui creare il classificatore.

Se si vuole creare del codice (condizioni if-then-else) andare su More options... e selezionare l'apposita voce.
Ora premere Start.

Nell'area di destra (Classifier output) ci sono i risultati del J48 tra cui l'albero delle regole e altri dati interessanti che permettono di verificare la bontà del classificatore appena creato.

In particolar modo si notino l'accuratezza della classificazione, la tabella che descrive l'accuratezza nel dettaglio rispetto alla classificazione sul valore 0 e rispetto a 1 e la tabella di contingenza (dall'alto verso il basso).

Qui due indici importanti sono la Precision e la Recall:

  • La Precision (PPV) misura quanti esempi (geni) predetti come positivi (essenziali) sono proprio positivi (essenziali).
    PPV=TP/(TP+FP)
  • La Recall (R) invece misura quanti dei veri positivi (geni essenziali) sono classificati correttamente.
    R=TP/(TP+FN)

La ROC area la vediamo dopo.
Per il particolare tipo di dataset utilizzato i valori di Precision e Recall sono un po' particolari, consiglio quindi di non prenderli in considerazione per confronti con la propria sperimentazione.

In fondo c'è la tabella di contingenza o Confusion Matrix che ci dice quante istanze sono state classificate correttamente e quali no per l'una e per l'altra classe: le colonne si riferiscono a "come sono stati classificati" dall'albero, le righe alla classificazione reale.
Quindi rispetto alla classe 1 (essenzialità del gene) si ha che la Cofusion Matrix è organizzata nel seguente modo:

TrueNegatives FalsePositives
FalseNegatives TruePositives

Graficamente parlando

Ovviamente è possibile visualizzare l'albero di decisione.
Basta cliccare di destro  sulla voce dell'esecuzione nella Result List e andare a scegliere Visulaize Tree

Ci sta benissimo che vi si apra una finestrina e che vi sia tutto un appiccicume.
In questo caso, allargare la finestra dell'albero, cliccare di destro e fare Fit to screen.
Questo sotto è un esempio di visualizzazione di albero.

 

Un'altra cosa importante nello studio di questa roba è la curva ROC.
Questa curva mette a confronto il TP rate (asse delle ordinate) e FP rate (asse delle ascisse); il calcolo della sua sottoarea è utile per valutare l’abilità del classificatore nel separare le istanze positive da quelle negative.
Nel mio esempio è 0.6 circa, il che non è una buona cosa visto che si comincia a parlare di "valore predittivo" sopra lo 0.7. Più la sottoarea è vicina a 1, meglio sarà. Più la sottoarea è vicina a 0.5, peggio sarà.
Per plottare la ROC si fa semplicemente così:

Questa è la finestra che viene fuori.

Per ulteriori informazioni sulla curva ROC.

Come applico l'albero trovato a  un altro data set di esempi non classificati?

Una volta ottenuto l'albero, cliccare su Supplied test set nel Test Options, poi su Set..
Si sceglie quindi il file e poi apri.
Una cosa importante:

  • se il file non contiene l'attributo da classificare allora selezionate nel menù a tendina della finestra Test Instances la voce No class


  • altrimenti selezionate la voce dell'attributo (il quale avrà come valore per ogni istanza il carattere ?).

Dare Start. Se avete il primo punto allora vi dovrebbe apparire una finestra che vi chiede un adattamento al test set. Date Sì.

Ora avete lanciato l'albero su test set.
É normale che nell'area degli output abbiate valori nulli.
Quello che interessa  a noi in realtà è salvare il file ARFF con tutti la classificazione.
Non c'è un modo diretto per farlo (fuorché da linea di comando) però è comunque fattibile.
Cliccare col tasto destro del mouse sull'esecuzione appena terminata sulla result list e andare su Visualize margin curve.

Ora procedere cliccando il tasto Salva nella finestra appena apparsa.
I risultati del file poi potranno essere visualizzati tornando alla sezione Preprocess e caricando il file appena ottenuto.

Spero di essere stato abbastanza chiaro e di utilità per qualcuno.
Se ci sono inesattezza o cose simili lasciatemi un commento 🙂

Vi saluto e alla prossima!

Cheers! 😉

Ingegnere Informatico e Ricercatore se compiace al Prodigioso Spaghetto Volante. Sono uno spartan racer, massimo esperto di serie tv, fotografo amatoriale e appena ne ho l’occasione preparo la valigia e parto

Classificatore binario con Weka [Alberi di decisione J48] ultima modifica: 2012-10-02T08:42:00+01:00 da Andrea Salvi


Advertisment ad adsense adlogger