Approfondimento su PFI per l’interpretabilità dei modelli

PFI per l'interpretabilità dei modelli

Un altro strumento di interpretabilità per la tua cassetta degli attrezzi

Foto di fabio su Unsplash

Sapere come valutare il tuo modello è essenziale per il tuo lavoro come data scientist. Nessuno approverà la tua soluzione se non sei in grado di comprenderla appieno e comunicarla ai tuoi stakeholder. Ecco perché conoscere i metodi di interpretazione è così importante.

La mancanza di interpretabilità può compromettere un ottimo modello. Non ho mai sviluppato un modello in cui i miei stakeholder non fossero interessati a capire come venissero effettuate le previsioni. Pertanto, saper interpretare un modello e comunicarlo al business è una capacità essenziale per un data scientist.

In questo post, esploreremo l’Importanza delle Caratteristiche per Permutazione (PFI), una metodologia indipendente dal modello che può aiutarci a identificare quali sono le caratteristiche più importanti del nostro modello e quindi comunicare meglio quali sono le considerazioni del modello durante le sue previsioni.

Cos’è l’Importanza delle Caratteristiche per Permutazione

Il metodo PFI cerca di stimare quanto una caratteristica sia importante per i risultati del modello in base a ciò che accade al modello quando modifichiamo la caratteristica collegata alla variabile target.

Per fare ciò, per ogni caratteristica di cui vogliamo analizzare l’importanza, la mescoliamo casualmente mantenendo invariati tutte le altre caratteristiche e la variabile target.

Ciò rende la caratteristica inutile per prevedere la variabile target poiché abbiamo interrotto la relazione tra di loro modificando la loro distribuzione congiunta.

Successivamente, possiamo utilizzare il nostro modello per prevedere il nostro dataset mescolato. La riduzione delle prestazioni nel nostro modello indicherà quanto è importante quella caratteristica.

L’algoritmo sarà quindi simile al seguente:

  • Alleniamo un modello su un dataset di allenamento e valutiamo le sue prestazioni sia sul dataset di allenamento che su quello di test
  • Per ogni caratteristica, creiamo un nuovo dataset in cui la caratteristica è mescolata
  • Successivamente, utilizziamo il modello addestrato per prevedere l’output del nuovo dataset
  • Il rapporto tra la nuova misura delle prestazioni e quella precedente ci fornisce l’importanza della caratteristica

Si noti che se una caratteristica non è importante, le prestazioni del modello non dovrebbero variare molto. Se invece è importante, allora le prestazioni devono subire una forte riduzione.

Interpretazione del PFI

Ora che sappiamo come calcolare il PFI, come lo interpretiamo?

Dipende da quale insieme stiamo applicando il PFI. Di solito abbiamo due opzioni: applicarlo al dataset di allenamento o a quello di test.

Interpretazione dell’allenamento

Durante l’allenamento, il nostro modello apprende i pattern dei dati e cerca di rappresentarli. Ovviamente, durante l’allenamento, non abbiamo idea di quanto bene il nostro modello generalizzi ai dati non visti in precedenza.

Pertanto, applicando il PFI al dataset di allenamento, vedremo quali caratteristiche sono state le più rilevanti per l’apprendimento della rappresentazione dei dati da parte del modello.

In termini di business, ciò indica quali caratteristiche sono state le più importanti per la costruzione del modello.

Interpretazione del test

Ora, se applichiamo il metodo al dataset di test, vedremo l’impatto delle caratteristiche sulla generalizzazione del modello.

Pensiamoci. Se vediamo le prestazioni del modello diminuire nel set di test dopo aver mescolato una caratteristica, significa che quella caratteristica era importante per le prestazioni su quel set. Dal momento che il set di test è ciò che utilizziamo per testare la generalizzazione (se stai facendo tutto correttamente), possiamo dire che è importante per la generalizzazione.

I problemi con il PFI

Il PFI analizza l’effetto di una caratteristica sulle prestazioni del tuo modello, quindi non afferma nulla sui dati grezzi. Se le prestazioni del tuo modello sono scarse, allora qualsiasi relazione che trovi con il PFI sarà insignificante.

Ciò è vero per entrambi i set, se il tuo modello è sottostimato (bassa capacità predittiva sul set di allenamento) o sovrastimato (bassa capacità predittiva sul set di test), allora non puoi trarre informazioni da questo metodo.

Inoltre, quando due caratteristiche sono altamente correlate, il PFI può ingannare la tua interpretazione. Se mescoli una caratteristica ma le informazioni necessarie sono codificate in un’altra, le prestazioni potrebbero non subire alcuna perdita, facendoti pensare che la caratteristica sia inutile, il che potrebbe non essere vero.

Implementazione del PFI in Python

Per implementare il PFI in Python dobbiamo prima importare le librerie necessarie. Per questo, useremo principalmente le librerie numpy, pandas, tqdm e sklearn:

import pandas as pdimport numpy as npimport matplotlib.pyplot as pltfrom tqdm import tqdmfrom sklearn.model_selection import train_test_splitfrom sklearn.datasets import load_diabetes, load_irisfrom sklearn.ensemble import RandomForestRegressor, RandomForestClassifierfrom sklearn.metrics import accuracy_score, r2_score

Ora dobbiamo caricare il nostro dataset, che sarà il dataset Iris. Successivamente, adatteremo un Random Forest ai dati.

X, y = load_iris(return_X_y=True)X_train, X_test, y_train, y_test = train_test_split(  X, y, test_size=0.3, random_state=12, shuffle=True)rf = RandomForestClassifier(  n_estimators=3, random_state=32).fit(X_train, y_train)

Con il nostro modello adattato, analizziamo le sue prestazioni per vedere se possiamo applicare in modo sicuro il PFI per capire come le caratteristiche influenzano il nostro modello:

print(accuracy_score(rf.predict(X_train), y_train))print(accuracy_score(rf.predict(X_test), y_test))

Possiamo vedere che abbiamo ottenuto una precisione del 99% sul set di addestramento e del 95,5% sul set di test. Sembrano buoni finora. Otteniamo i punteggi di errore originali per un confronto successivo:

original_error_train = 1 - accuracy_score(rf.predict(X_train), y_train)original_error_test = 1 - accuracy_score(rf.predict(X_test), y_test)

Ora calcoliamo i punteggi di permutazione. Per fare ciò, è consueto eseguire la permutazione per ogni caratteristica diverse volte per ottenere una statistica dei punteggi delle caratteristiche e evitare coincidenze. Nel nostro caso, facciamo 10 ripetizioni per ogni caratteristica:

n_steps = 10feature_values = {}for feature in range(X.shape[1]):  # Salveremo ogni nuovo punto di prestazione per ogni caratteristica    errors_permuted_train = []    errors_permuted_test = []        for step in range(n_steps):        # Prendiamo di nuovo i dati perché la funzione np.random.shuffle li mischia sul posto        X, y = load_iris(return_X_y=True)        X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=12, shuffle=True)        np.random.shuffle(X_train[:, feature])        np.random.shuffle(X_test[:, feature])            # Applichiamo il nostro modello precedentemente adattato ai nuovi dati per ottenere la prestazione        errors_permuted_train.append(1 - accuracy_score(rf.predict(X_train), y_train))        errors_permuted_test.append(1 - accuracy_score(rf.predict(X_test), y_test))            feature_values[f'{feature}_train'] = errors_permuted_train    feature_values[f'{feature}_test'] = errors_permuted_test

Ora abbiamo un dizionario con le prestazioni per ogni permutazione che abbiamo fatto. Ora generiamo una tabella che mostra, per ogni caratteristica in ogni fold, la media e la deviazione standard delle prestazioni rispetto alle prestazioni originali del nostro modello:

PFI = pd.DataFrame()for feature in feature_values:    if 'train' in feature:        aux = feature_values[feature] / original_error_train        fold = 'train'    elif 'test' in feature:        aux = feature_values[feature] / original_error_test        fold = 'test'        PFI = PFI.append({        'feature': feature.replace(f'_{fold}', ''),        'pfold': fold,        'mean':np.mean(aux),        'std':np.std(aux),    }, ignore_index=True)    PFI = PFI.pivot(index='feature', columns='fold', values=['mean', 'std']).reset_index().sort_values(('mean', 'test'), ascending=False)

Avremo qualcosa del genere:

Possiamo vedere che la caratteristica 2 sembra essere la caratteristica più importante nel nostro dataset per entrambi i fold, seguita dalla caratteristica 3. Poiché non stiamo fissando il seme casuale per la funzione di permutazione di numpy, ci aspettiamo che questo numero vari.

Possiamo quindi rappresentare l’importanza in un grafico per avere una migliore visualizzazione dell’importanza:

Conclusioni

Il PFI è una metodologia semplice che può aiutarti a identificare rapidamente le caratteristiche più importanti. Prova ad applicarlo a un modello che stai sviluppando per vedere come si comporta.

Ma sii anche consapevole dei limiti del metodo. Non conoscere dove un metodo è carente finirà per farti fare un’interpretazione errata.

Inoltre, nota che il PFI mostra l’importanza della caratteristica ma non indica in quale direzione influisce sull’output del modello.

Quindi, dimmi, come lo userai nei tuoi prossimi modelli?

Rimani sintonizzato per ulteriori post su metodi di interpretazione che possono migliorare la tua comprensione complessiva di un modello.