Corso
Gli algoritmi di machine learning (ML) sono sempre più usati per automatizzare attività ripetitive e individuare pattern nascosti nei dati. Ma sono intrinsecamente probabilistici, quindi le loro previsioni non sono sempre corrette. Per questo serve un modo per stimare la validità del tuo modello di ML e instaurare fiducia in questi sistemi.
Metriche di valutazione come accuracy, precision, recall, mean squared error (MSE), mean absolute percentage error (MAPE) e simili sono comunemente usate per misurare le prestazioni del modello. Metriche diverse ti aiutano a misurare le performance da prospettive e secondo criteri differenti.
Queste metriche servono anche ad assicurare che il modello migliori costantemente nell’apprendimento del compito previsto. In fin dei conti, se non puoi misurare, non puoi migliorare le prestazioni del sistema di ML.
L’accuracy è una di queste metriche: è facile da capire e funziona bene con dataset bilanciati, cioè quelli in cui tutte le classi sono rappresentate in modo uguale. Tuttavia, i fenomeni del mondo reale non sono distribuiti equamente; perciò è difficile trovare dataset davvero bilanciati. L’accuracy riguarda soprattutto il verificare se la maggioranza delle istanze è identificata correttamente, a prescindere dalla classe di appartenenza. Per eventi rari ma importanti, come una transazione fraudolenta o un click su un’impression pubblicitaria, l’accuracy rappresenta in modo fuorviante un modello che predice tutto come classe negativa, cioè nessuna frode o nessun click. A causa di questi limiti, l’accuracy non è la metrica più adatta. Quindi, quale metrica dovremmo usare invece per misurare le prestazioni dei nostri modelli?
Precision e recall sono metriche ampiamente usate per valutare le prestazioni di un modello di classificazione sbilanciato, ad esempio per prevedere il churn dei clienti.
Precision e Recall, spiegate
La precision indica con quanta sicurezza una classe positiva viene predetta come positiva, mentre il recall misura quanto bene il modello identifica il numero di istanze della classe positiva nel dataset. Nota che la classe positiva è la classe di interesse.
Empiricamente, precision e recall si comprendono al meglio con l’aiuto della matrice di confusione, che contiene quattro termini chiave:
- True Positive (TP): numero di istanze della classe positiva identificate correttamente
- False Positive (FP): numero di istanze della classe negativa identificate erroneamente come positive
- True Negative (TN): numero di istanze della classe negativa identificate correttamente
- False Negative (FN): numero di istanze della classe positiva identificate erroneamente come negative

Rappresentazione creata dall’autore
Precision e recall sono un’espressione matematica di questi quattro termini, in cui:
La precision è la proporzione di TP su tutte le istanze delle predizioni positive (TP+FP). Il recall è la proporzione di TP su tutte le istanze positive (TP+FN).
Si può ulteriormente semplificare usando la seguente notazione che evidenzia la differenza tra le due. In sostanza, entrambe le metriche hanno lo stesso numeratore, che è l’intersezione tra le istanze positive reali e quelle predette come positive, cioè TP.

Immagine di Shruti Saxena
Il discriminante sta al denominatore: la precision considera tutte le istanze predette come positive (TP+FP), mentre il recall considera le istanze effettivamente positive (TP+FN).
Intuizione dietro Precision e Recall
C’è un motivo se la matrice di confusione si chiama così: è davvero fonte di confusione quando cerchi di comprenderla per la prima volta.
Facciamo quindi nostro il concetto con un esempio. Diciamo che possiedi un’acciaieria in cui si estrae ferro dal minerale di ferro e lo si mescola con altri minerali ed elementi (a volte involontariamente). Concentrandoci sulla fase di estrazione, hai alcune scelte riguardo alla purezza del metallo estratto e agli scarti prodotti durante il processo, come indicato di seguito:
Scenario 1: vuoi solo dare priorità alla purezza del ferro estratto, a prescindere da quanto metallo venga sprecato nel processo.
Scenario 2: vuoi massimizzare l’efficienza, cioè la quantità di ferro estratto per unità di minerale, senza considerare la purezza del metallo estratto.
Scenario 3: vuoi il meglio di entrambi i mondi, mantenendo la purezza del metallo estratto il più alta possibile riducendo gli scarti (massimizzando il ferro estratto per unità di minerale).
Pensa all’altoforno o al forno elettrico ad arco come alle opzioni di modellazione che forniscono risultati diversi (purezza del ferro e scarti). Supponiamo che uno dei metodi di estrazione fornisca ferro puro al 97,5% e perda il 4% del ferro nei fanghi. Possiamo quindi definire la nostra precision come la frazione di ferro puro nel metallo estratto, cioè 97,5%, mentre il recall è la quantità di ferro estratto su tutto il ferro disponibile nel minerale, cioè 96% (il 4% di tutto il ferro viene sprecato).

Illustrazione creata dall’autore
Poniamo che tu scelga il secondo metodo perché vuoi un ferro più puro dal forno, il che però comporta più scarti nel processo di estrazione. Supponiamo che aumentando la purezza del ferro dello 0,5% fino al 98%, gli scarti di metallo aumentino dell’11%. Ciò significa che il valore di recall corrispondente a una precision del 98% diventa 85%. Questo baratto del recall in cambio di una precision più alta e viceversa mostra la relazione inversa tra precision e recall.
Non sarebbe fantastico conoscere tutti i valori di precision e i corrispondenti valori di recall, così da poter prendere una decisione che si adatti al meglio al tuo obiettivo?
La curva precision-recall aiuta a fare proprio questa scelta, e la capirai a fondo nelle sezioni seguenti. Ma prima, comprendiamo un concetto importante, la soglia (threshold), che è alla base della PR curve.
Il concetto di soglia (threshold)
Prendiamo l’esempio dell’identificazione di transazioni fraudolente per capire come funziona una soglia (o cutoff). La tabella qui sotto riporta quattro transazioni con ID da 1 a 4; una transazione può essere fraudolenta o regolare. Il modello di rilevamento delle frodi restituisce la probabilità che una transazione sia fraudolenta (evidenziata in giallo), che intrinsecamente fornisce anche la probabilità che sia regolare.
Una transazione si considera predetta come fraudolenta se la probabilità in output è maggiore della soglia scelta nella colonna Probability of Fraud transaction, altrimenti è dichiarata regolare.
|
Transaction ID |
Probability of Fraud transaction |
Probability of regular transaction |
Is fraudulent? (Threshold = 0.9) |
Is fraudulent? (Threshold = 0.5) |
Is fraudulent? (Threshold = 0.4) |
|
1 |
0.3 |
0.7 |
No |
No |
No |
|
2 |
0.4 |
0.6 |
No |
No |
Yes |
|
3 |
0.6 |
0.4 |
No |
Yes |
Yes |
|
4 |
0.95 |
0.05 |
Yes |
Yes |
Yes |
Quando si applica una soglia rigorosa come 0,9, le prime tre transazioni vengono contrassegnate come regolari, mentre l’ultima viene contrassegnata come fraudolenta. Una soglia così alta trasmette fiducia nelle previsioni, portando a uno scenario di alta precision. In cambio, stai sacrificando il recall del modello perché ti perdi alcune transazioni fraudolente.
Uno scenario del genere non è desiderabile nonostante l’alta precision. Riesci a immaginare il perché?
Perché l’azienda finisce per sostenere un costo più alto nel mancato riconoscimento delle frodi, che è lo scopo stesso di costruire un modello del genere. Nota che il costo di una transazione fraudolenta è molto più alto del costo legato a transazioni regolari ma bloccate, cioè gli FP.
Ora, considera l’altro estremo con una soglia bassa di 0,4 che contrassegna come fraudolente le ultime tre transazioni. Una soglia così permissiva bloccherà la maggior parte delle transazioni, cosa che può infastidire molti clienti. Senza dimenticare l’onere aggiuntivo sulle risorse umane per analizzare le transazioni segnalate e identificare le vere frodi.
Pertanto, l’azienda deve definire metriche target e i relativi valori desiderati per ottenere il meglio di entrambi i mondi, tenendo in considerazione i seguenti costi:
- Il costo di identificare una transazione fraudolenta come regolare (falsi negativi)
- Il costo di identificare una transazione regolare come fraudolenta (falsi positivi)
Tornando alla definizione di precision, noterai che i falsi positivi sono al denominatore dell’espressione matematica, il che significa che minimizzare i falsi positivi massimizza la precision. Allo stesso modo, minimizzare i falsi negativi massimizza il recall del modello.
Dunque, se una transazione sia predetta come fraudolenta o regolare dipende in larga misura dal valore della soglia.
Che cos’è una curva Precision-Recall?
Una curva precision-recall ti aiuta a decidere una soglia in base ai valori desiderabili di precision e recall. È utile anche per confrontare le prestazioni di modelli diversi calcolando l“Area Under the Precision-Recall Curve”, abbreviata in AUC.
Come spiegato tramite la matrice di confusione, un modello di classificazione binaria produrrà TP, FP, TN e FN per vari valori di soglia; ogni valore di soglia restituisce una coppia corrispondente di valori di precision e recall.
Tracciare i valori di recall sull’asse x e i corrispondenti valori di precision sull’asse y genera una PR curve che mostra una funzione a pendenza negativa. Rappresenta il trade-off tra precision (riduzione degli FP) e recall (riduzione degli FN) per un dato modello. Considerando la relazione inversa tra precision e recall, la curva è generalmente non lineare, il che implica che aumentare una metrica riduce l’altra, ma la riduzione potrebbe non essere proporzionale.

Immagine da StackExchange
Supponiamo che un’organizzazione scelga un valore minimo accettabile di recall del 98%. La precision si attesta al 30% nel punto di incrocio rappresentato dalla stella etichettata “Low Threshold, Low Precision, High Recall”.
Gli altri due punti estremi rappresentano i casi in cui la soglia è:
- Troppo bassa porta ad alto recall – costo del capitale umano e clienti infastiditi
- Troppo alta porta ad alta precision – costo delle transazioni fraudolente e perdita di reputazione.
Usare una PR curve
Oltre a decidere il cutoff giusto in linea con la metrica di business, l’area sotto la curva delle precision-recall di più modelli o algoritmi può essere usata per confrontarne le prestazioni. È particolarmente utile confrontare i modelli usando le PR curve piuttosto che metriche singole come precision, recall o anche l’F1 score (che è la media armonica di precision e recall).

Immagine da Stackoverflow
Tali metriche dipendono dalla soglia, per cui una variazione della soglia cambia la distribuzione di TP, FP e FN. Due modelli diversi possono comportarsi in modo diverso per una data soglia, il che rende la PR curve una scelta robusta per il confronto tra modelli. Il grafico sopra illustra due PR curve di due algoritmi diversi su un dato dataset: l’AUC dell’algoritmo due è maggiore dell’AUC dell’algoritmo uno, rendendolo la scelta migliore per il problema in questione.
Implementare la curva Precision-Recall in Python
Ora che sappiamo cosa sono le curve precision-recall e a cosa servono, vediamo come crearne una in Python.
Passo 1: Importare i pacchetti Python necessari
Consideriamo il dataset per il rilevamento del tumore al seno, dove “classe 1” rappresenta la diagnosi di cancro e “classe 0” rappresenta l’assenza di cancro.
Il primo import carica il dataset da “sklearn.datasets”, che include le variabili indipendenti e la variabile target. Poiché si tratta di un dataset che può essere appreso facilmente dalla maggior parte degli algoritmi, abbiamo scelto l’algoritmo Naive Bayes importato come “GaussianNB” da sklearn.
L’import successivo di “Precision_Recall_curve” restituisce diverse soglie e i relativi valori di precision e recall.
from sklearn.datasets import load_breast_cancer
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import precision_recall_curve
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
Passo 2: Preparare i dati di train e test
Le variabili indipendenti sono memorizzate nella chiave “data” e la variabile target nella chiave “target” all’interno del dizionario “data”. I dati vengono poi divisi in train e test passando l’argomento test_size con valore 0,3.
# Load model breast cancer data
data = load_breast_cancer()
X = data['data']
y = data['target']
Diamo un’occhiata alla distribuzione della classe positiva e negativa, cioè casi di tumore al seno e non tumore al seno.
import numpy as np
unique, counts = np.unique(y, return_counts=True)
plt.pie(counts, labels=unique, autopct='%.0f%%');

Dividi i dati in train e test usando il metodo train_test_split dal modulo model_selection di sklearn.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
Passo 3: Addestramento del modello
I dati di training vengono passati come argomenti a GaussianNB() per avviare l’addestramento del modello. L’oggetto del modello addestrato viene poi usato per ottenere le predizioni sotto forma di probabilità sul dataset di train e di test.
# Fit a Naive Bayes model
clf = GaussianNB().fit(X_train, y_train)
Passo 4: Generare le predizioni
Genera le probabilità di predizione usando i dataset di training e testing, che verranno usate per ottenere precision e recall a diversi valori di soglia.
# Predict probability
y_prob_train = clf.predict_proba(X_train)[:,1]
y_prob_test = clf.predict_proba(X_test)[:,1]
Passo 5: Tracciare la PR curve
Il metodo Precision_Recall_curve() accetta due input – le probabilità dal dataset di train, cioè y_prob_train, e i valori di verità a terra, e restituisce tre valori: precision, recall e thresholds.
precision, recall, thresholds = precision_recall_curve(y_train, y_prob_train)
plt.fill_between(recall, precision)
plt.ylabel("Precision")
plt.xlabel("Recall")
plt.title("Train Precision-Recall curve");
I vettori di precision e recall sono usati per tracciare la PR curve a soglie variabili come mostrato di seguito:

PR Curve generata dall’autore
La curva Precision-Recall è migliore della ROC?
Una curva ROC è simile alla PR curve ma traccia il True Positive Rate (TPR) rispetto al False Positive Rate (FPR) per soglie diverse. Conosciamo già il TPR, è solo un altro nome per il recall. Quindi concentriamoci sull’FPR, che indica il numero di misclassificazioni dalla classe negativa. Continuando con l’esempio della frode, rappresenta la percentuale di transazioni regolari contrassegnate come fraudolente.

Immagine di Albert Um
Ormai abbiamo capito che il recall, alias TPR, è comune tra PR curve e ROC curve; la differenza principale è tra precision e FPR rispettivamente. Vediamo perché una PR curve è relativamente più informativa.
Questo perché la PR curve fornisce informazioni più significative sulla classe di interesse rispetto alla ROC curve. Riprendiamo la previsione di una transazione fraudolenta. I True Negatives (TN) nei casi di dataset sbilanciati tendono ad essere molto numerosi, rendendo l’FPR un valore minuscolo. Ma questo dice qualcosa sulle prestazioni del modello nel predire una transazione come fraudolenta?
No! D’altra parte, usare la precision come una delle metriche descrive le prestazioni del modello sulla classe positiva (transazioni fraudolente). Questo indica se il modello è conservativo o permissivo nel contrassegnare transazioni come fraudolente.
Il secondo grande limite della ROC curve è la sua insensibilità ai dati sbilanciati. Dalla figura sopra, puoi vedere che l’FPR è una metrica solo della classe negativa, il che significa che il cambiamento di FP dovrebbe essere proporzionale al cambiamento di FP+TN (tutte le istanze negative). Pertanto, se cambia la distribuzione dei dati sottostanti, la ROC non cambia in modo significativo. Questa insensibilità alla distribuzione delle classi rende la PR curve una scelta migliore rispetto alla ROC curve.
Considerazioni finali
Precision e recall sono metriche fondamentali di valutazione per misurare le prestazioni dei modelli di classificazione di machine learning. Tuttavia, il trade-off tra le due dipende dalle priorità di business e si gestisce al meglio tramite la PR curve. L’articolo ha spiegato come interpretare la PR curve e scegliere la soglia giusta per raggiungere l’obiettivo di business. Inoltre, il post ha illustrato passo dopo passo come tracciarla in Python. Abbiamo anche discusso perché la PR curve è più informativa della ROC curve.

