scikit-learn

scikit-learn e i classificatori di Machine Learning

In questo nuovo capitolo di Machine Learning utilizziamo la libreria scikit-learn grazie alla quale abbiamo a disposizione un’interfaccia di facile utilizzo per l’impiego dei più comuni algoritmi di intelligenza artificiale. Per testarla e per capirne meglio il funzionamento utilizziamo il dataset Iris, messo a disposizione dalla stessa libreria, per attività, principalmente, di collaudo e di sperimentazione.

Dopo una breve introduzione, vediamo, in maniera pratica come utilizzare questa libreria.

Ormai conosciamo bene il concetto di Perceptron e di Adaline. Per addestrare il primo tipo di classificatore dobbiamo procedere con l’assegnare alla matrice X la lunghezza e la larghezza del petalo. Le corrispondenti etichette di classificazione delle specie di fiori, invece, le assegnamo al vettore y.

				
					from sklearn import datasets
import numpy as np

iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target

print('Class labels:', np.unique(y))
				
			

Eseguendo la funzione np.unique(y) possiamo vedere la classificazione sottoforma di [0, 1, 2] delle classi dei fiori Setosa – Versicolor – Virginica. Tutto ciò permette una migliore gestione offrendo prestazioni ottimali per quanto riguarda l’esecuzione dell’algoritmo.

Valutazione della qualità

Per la valutazione della qualità di un modello che opera su dati sconosciuti è cosigliato suddividere il dataset in due parti:

  • addestramento
  • test
				
					from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=0)
				
			

Tramite l’utilizzo della funzione train_test_split messa a disposizione dal modulo model_selection di scikit-learn andiamo a suddividere casualmente la matrice X e il vettore y in un 30% di dati di test e 70% di dati di addestramento.

Riduzione di scala

Molti algoritmi, come abbiamo visto nei capitoli precedenti, richiedono una riduzione di scala per garantire delle prestazioni ottimali. Per questo motivo procederemo con la standardizzazione delle caratteristiche utilizzando la classe StandardScaler del modulo preprocessing.

				
					from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
				
			

Utilizzando il metodo fit sulla variabile sc dove abbiamo creato un nuovo oggetto StandardScaler andiamo ad eseguire la stima dei parametri ƴ  e δ corrispondenti alla media del campione e alla deviazione standard. Tramite il metodo transform abbiamo standardizzato i dati di addestramento utilizzando proprio ƴ  e δ.

Abbiamo strandardizzaro tramite lo stesso metodo sia i dati di test che di addestramento in modo che essi possano essere confrontati.

Addestriamo il Perceptron

				
					from sklearn.linear_model import Perceptron

ppn = Perceptron(n_iter_no_change=40, eta0=0.1, random_state=0)
ppn.fit(X_train_std, y_train)
				
			

Dopo aver creato un nuovo oggetto Perceptron andiamo ad addestrarlo tramite metodo fit. I parametri all’interno dell’oggetto Perceptron sono, rispettivamente, il numero di epoch, il tasso di appredimento e random_state utile alla riproducibilità del mescolamento iniziale del dataset di addestramento dopo ogni epoch.

Come ben sappiamo dobbiamo sperimentare l’algoritmo in modo da trovare un tasso di apprendimento appropriato. Se il tasso è eccessivo, l’algoritmo mancherà il minimo globale mentre se è troppo ridotto richiederà troppi epoch prima di convergere.

				
					y_pred = ppn.predict(X_test_std)
print('Misclassified samples: %d' % (y_test != y_pred).sum())
				
			

Il metodo predict permette di eseguire delle previsioni e, eseguendolo, notiamo che abbiamo 4 campioni di fiori nei quali il Perceptron fallisce nel classificare.

Tracciamo le regioni decisionali con scikit-learn

				
					from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import warnings


def versiontuple(v):
    return tuple(map(int, (v.split("."))))


def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):

    # setup marker generator and color map
    markers = ('s', 'x', 'o', '^', 'v')
    colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])

    # plot the decision surface
    x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1
    x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1
    xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),
                           np.arange(x2_min, x2_max, resolution))
    Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)
    Z = Z.reshape(xx1.shape)
    plt.contourf(xx1, xx2, Z, alpha=0.4, cmap=cmap)
    plt.xlim(xx1.min(), xx1.max())
    plt.ylim(xx2.min(), xx2.max())

    for idx, cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y == cl, 0], 
                    y=X[y == cl, 1],
                    alpha=0.6, 
                    c=cmap(idx),
                    edgecolor='black',
                    marker=markers[idx], 
                    label=cl)

    # highlight test samples
    if test_idx:
        # plot all samples
        if not versiontuple(np.__version__) >= versiontuple('1.9.0'):
            X_test, y_test = X[list(test_idx), :], y[list(test_idx)]
            warnings.warn('Please update to NumPy 1.9.0 or newer')
        else:
            X_test, y_test = X[test_idx, :], y[test_idx]

        plt.scatter(X_test[:, 0],
                    X_test[:, 1],
                    c='',
                    alpha=1.0,
                    edgecolor='black',
                    linewidths=1,
                    marker='o',
                    s=55, label='test set')
				
			

Attraverso le funzioni di scikit-learn e il codice appena realizzato andiamo a rappresentare la qualità con cui il Perceptron separa i vari campioni di fiori. Evidenziamo i campioni del dataset di test tramite piccoli cerchi.

				
					X_combined_std = np.vstack((X_train_std, X_test_std))
y_combined = np.hstack((y_train, y_test))

plot_decision_regions(X=X_combined_std, y=y_combined,
                      classifier=ppn, test_idx=range(105, 150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')

plt.tight_layout()

plt.show()
				
			
scikit-learn

Come possiamo vedere le tre classi di fiori non riescono ad essere separate perfettamente dai confini decisionali puramente lineari. Questo perchè, come abbiamo studiato nei capitoli precedenti, l’algoritmo Perceptron non converge mai su dataset che non sono separabili in maniera lineare. Vedremo che scikit-learn mette a disposizione altre funzioni e studieremo altri tipi di algoritmi che convergono a costo minimo anche nel caso le classi non siano perfettamente lineari.

Condividi il post

Condividi su facebook
Condividi su google
Condividi su twitter
Condividi su email
Condividi su whatsapp