Machine Learning – Alberi di decisione

Ultimo aggiornamento: 05-09-2016

Google Developers sul suo profilo Youtube sta pubblicando delle  video-tutorial sul machine learning. I primi due video parlano degli alberi di decisione (linko wikipedia inglese perchè è più completa).
Vedendo i video mi è tornata in mente la mia tesi, in cui ho analizzato le firme grafometriche e dove ho usato un albero di decisione “fatto a mano” per classificare. Così mi son messo a scrivere un pò di codice python per far pratica con i metodi automatici.

Prima di tutto ci serve python e le librarie NumPy  e Sklearn, per fare le cose veloci potete scaricare la distribuzione all-in-one Anacoda. Fase due: vedere i video. Fatto ciò, potete scaricare questo zip che contiene i dati di tre persone: per ogni persona ci sono i confronti tra 10 firme originali e  di 5 false con delle originali.

Facciamo uno script python e in cima inseriamo le dipendenze delle funzioni e delle classi che useremo:

from sklearn.cross_validation import StratifiedKFold
import numpy as np
from scipy.stats import itemfreq
from sklearn import tree
from sklearn.metrics import confusion_matrix
from sklearn.metrics import f1_score

Poi scriviamo il codice che carica i dati di una firma:

signComp =  np.loadtxt("sign1.csv", delimiter=",", skiprows=1, usecols = list(range(1,4)))

Ogni file ha 60 righe, in gergo “sample”, 45 sample sono della classe dei confronti tra firme vere e gli altri sample appartengono alla classe dei confronti delle firme farse con le vere. Ogni sample ha le colonne che sarebbero le sue feature (le caratteristiche) che lo caratterizzano (si veda la 3° video-lezione).

Torno al codice, indichiamo le classi dei sample:

labels = np.zeros(60)
labels[45:] = 1 #classe 1 sono i confronti con le firme farse, gli altri confronti sono di classe 0

A questo punto possiamo fare un pò di CrossValidation (wiki la traduce in italiano, ma è preferibile usare la terminologia inglese), per fare il tuning dei parametri da passare al classificatore e vedere dai risultati quali sono i migliori; in questo caso si veda la documentazione di DecisionTreeClassifier. Nel codice di sotto non vario i parametri, è solo il template base per la crossValidation.
Per calcolare i Fold per il training ho utilizzato StratifiedKFold(labels, n_folds=3, shuffle=False, random_state=None) che dato i labels, fa n_folds e tra i fold mantiene il rapporto di sample tra le classi.

skf = StratifiedKFold(labels, 4, shuffle=True)
for train, test in skf:
	train_target = labels[train]
	train_data = signComp [train]
	print("Dimensione TrainSet:", train_target.shape)
	test_target = labels[test]
	test_data = signComp[test]
	print("Dim TestSet:", test_target.shape)

	clf = tree.DecisionTreeClassifier() #inizializzo il classificatore con i parametri predefiniti
	clf.fit(train_data, train_target) #creo l'albero di decisione

	y_pred = clf.predict(test_data) #faccio il testing
	print confusion_matrix(test_target, y_pred)
	print f1_score(test_target, y_pred)
	print ""

Cosa fa il codice? Per ogni predizione stampa la Matrice di Confusione che mostra quanti sample veri l’albero ha classificato come tali o quante classificazioni ha sbagliato (es: erano veri e non li ho classificati come tali). Mostro anche il F1 Score , utilizzato nella classificazione tra due classi (come in questo caso) al posto della sola accuratezza.

Visto come metter le mani sui dati, non vi resta che darvi alla pazza gioia con i vostri esperimenti =)