Come sviluppare e valutare strategie di classificazione ingenua utilizzando la probabilità
Un classificatore naive è un semplice modello di classificazione che presuppone poco o nulla riguardo al problema e le cui prestazioni forniscono una linea di base con cui è possibile confrontare tutti gli altri modelli valutati su un set di dati.
Esistono diverse strategie che possono essere utilizzate per un classificatore ingenuo e alcune sono migliori di altre, a seconda del set di dati e della scelta delle misure di prestazione. La misura delle prestazioni più comune è l'accuratezza della classificazione e le comuni strategie di classificazione ingenua, tra cui l'ipotesi casuale delle etichette delle classi, la scelta casuale delle etichette da un set di dati di addestramento e l'utilizzo di un'etichetta della classe maggioritaria.
È utile sviluppare un piccolo quadro di probabilità per calcolare la prestazione attesa di una data strategia di classificazione ingenua ed eseguire esperimenti per confermare le aspettative teoriche. Questi esercizi forniscono un'intuizione sia sul comportamento degli algoritmi di classificazione ingenui in generale, sia sull'importanza di stabilire una linea di base delle prestazioni per un compito di classificazione.
In questo tutorial scoprirai come sviluppare e valutare strategie di classificazione ingenua per l'apprendimento automatico.
Dopo aver completato questo tutorial, saprai:
- Le prestazioni dei modelli di classificazione ingenui forniscono una base in base alla quale tutti gli altri modelli possono essere ritenuti abili o meno.
- Il classificatore di classe maggioritaria raggiunge una precisione migliore rispetto ad altri modelli di classificatore ingenuo come l'ipotesi casuale e la previsione di un'etichetta di classe osservata selezionata casualmente.
- Le strategie di classificazione ingenua possono essere utilizzate su progetti di modellazione predittiva tramite la classe DummyClassifier nella libreria scikit-learn.
Avvia il tuo progetto con il mio nuovo libro Probability for Machine Learning, che include tutorial passo passo e i file codice sorgente Python per tutti esempi.
Cominciamo.
Panoramica dell'esercitazione
Questo tutorial è diviso in cinque parti; sono:
- Classificatore ingenuo
- Prevedere un'ipotesi casuale
- Prevedere una classe selezionata casualmente
- Prevedere la classe di maggioranza
- Classificatori ingenui in scikit-learn
Classificatore ingenuo
I problemi di modellazione predittiva di classificazione implicano la previsione di un'etichetta di classe dato un input al modello.
I modelli di classificazione vengono adattati a un set di dati di addestramento e valutati su un set di dati di test e le prestazioni vengono spesso riportate come una frazione del numero di previsioni corrette rispetto al numero totale di previsioni effettuate, denominata accuratezza.
Dato un modello di classificazione, come fai a sapere se il modello ha abilità o no?
Questa è una domanda comune in ogni progetto di modellazione predittiva di classificazione. La risposta è confrontare i risultati di un determinato modello di classificazione con un modello di classificazione di base o ingenuo.
Un modello di classificazione ingenuo è quello che non utilizza alcuna sofisticazione per fare una previsione, in genere facendo una previsione casuale o costante. Tali modelli sono ingenui perché non utilizzano alcuna conoscenza del dominio o alcun apprendimento per fare una previsione.
Le prestazioni di un classificatore di base in un'attività di classificazione forniscono un limite inferiore alle prestazioni previste di tutti gli altri modelli relativi al problema. Ad esempio, se un modello di classificazione funziona meglio di un classificatore ingenuo, allora ha una certa abilità. Se un modello di classificatore ha prestazioni peggiori del classificatore ingenuo, non ha alcuna abilità.
Quale classificatore dovrebbe essere utilizzato come classificatore ingenuo?
Questa è un'area comune di confusione per i principianti e vengono adottati diversi classificatori ingenui.
Alcune scelte comuni includono:
- Prevedere una classe casuale.
- Prevedere una classe selezionata casualmente dal set di dati di training.
- Prevedere la classe maggioritaria dal set di dati di addestramento.
Il problema è che non tutti i classificatori ingenui sono uguali e alcuni funzionano meglio di altri. Pertanto, dovremmo utilizzare il classificatore ingenuo con le migliori prestazioni in tutti i nostri progetti di modellazione predittiva di classificazione.
Possiamo utilizzare la probabilità semplice per valutare le prestazioni di diversi modelli di classificatore ingenuo e confermare l'unica strategia che dovrebbe sempre essere utilizzata come classificatore nativo.
Prima di iniziare a valutare diverse strategie, definiamo un problema di classificazione artificioso a due classi. Per renderlo interessante, assumeremo che il numero di osservazioni non sia uguale per ciascuna classe (ad esempio, il problema è sbilanciato) con 25 esempi per la classe 0 e 75 esempi per la classe 1.
Possiamo rendere concreto questo con un piccolo esempio in Python, elencato di seguito.
# summarize a test dataset
# define dataset
class0 = [0 for _ in range(25)]
class1 = [1 for _ in range(75)]
y = class0 + class1
# summarize distribution
print('Class 0: %.3f' % (len(class0) / len(y) * 100))
print('Class 1: %.3f' % (len(class1) / len(y) * 100))
L'esecuzione dell'esempio crea il set di dati e riassume la frazione di esempi che appartengono a ciascuna classe, mostrando il 25% e il 75% per la classe 0 e la classe 1 come potremmo intuitivamente aspettarci.
Class 0: 25.000
Class 1: 75.000
Infine, possiamo definire un modello probabilistico per valutare le strategie di classificazione naive.
In questo caso, siamo interessati a calcolare l'accuratezza della classificazione di un dato modello di classificazione binaria.
- P(yhat=y)
Questo può essere calcolato come la probabilità che il modello preveda il valore di ciascuna classe moltiplicata per la probabilità di osservare il verificarsi di ciascuna classe.
- P(yhat=y)=P(yhat=0) * P(y=0) + P(yhat=1) * P(y=1)
Questo calcola le prestazioni previste di un modello su un set di dati. Fornisce un modello probabilistico molto semplice che possiamo utilizzare per calcolare le prestazioni attese di un modello di classificazione ingenuo in generale.
Successivamente, utilizzeremo questo problema di previsione artificiosa per esplorare diverse strategie per un classificatore ingenuo.
Prevedere un'ipotesi casuale
Forse la strategia più semplice consiste nell'indovinare casualmente una delle classi disponibili per ciascuna previsione richiesta.
La chiameremo strategia dell’ipotesi casuale.
Utilizzando il nostro modello probabilistico, possiamo calcolare quanto bene ci si aspetta che questo modello funzioni in media sul nostro set di dati artificioso.
Un'ipotesi casuale per ciascuna classe è una distribuzione di probabilità uniforme su ciascuna possibile etichetta di classe o, nel caso di un problema a due classi, una probabilità di 0,5 per ciascuna classe. Inoltre, conosciamo la probabilità prevista dei valori per la classe 0 e la classe 1 per il nostro set di dati perché abbiamo inventato il problema; sono rispettivamente 0,25 e 0,75. Pertanto, calcoliamo la performance media di questa strategia come segue:
- P(yhat=y)=P(yhat=0) * P(y=0) + P(yhat=1) * P(y=1)
- P(yhat=y)=0,5 * 0,25 + 0,5 * 0,75
- P(yhat=y)=0,125 + 0,375
- P(yhat=y)=0,5
Questo calcolo suggerisce che la prestazione nel prevedere un'etichetta di classe uniformemente casuale sul nostro problema inventato è un'accuratezza di classificazione dello 0,5 o del 50%.
Ciò potrebbe sorprendere, il che è positivo in quanto evidenzia il vantaggio di calcolare sistematicamente la performance attesa di una strategia ingenua.
Possiamo confermare che questa stima è corretta con un piccolo esperimento.
La strategia può essere implementata come una funzione che seleziona casualmente uno 0 o un 1 per ogni previsione richiesta.
# guess random class
def random_guess():
if random() < 0.5:
return 0
return 1
Questo può quindi essere richiamato per ogni previsione richiesta nel set di dati e la precisione può essere valutata
...
yhat = [random_guess() for _ in range(len(y))]
acc = accuracy_score(y, yhat)
Si tratta di una singola prova, ma la precisione sarà diversa ogni volta che viene utilizzata la strategia.
Per contrastare questo problema, possiamo ripetere l’esperimento 1.000 volte e riportare la performance media della strategia. Ci aspetteremmo che la prestazione media corrisponda alla nostra prestazione prevista calcolata sopra.
L'esempio completo è elencato di seguito.
# example of a random guess naive classifier
from numpy import mean
from numpy.random import random
from sklearn.metrics import accuracy_score
# guess random class
def random_guess():
if random() < 0.5:
return 0
return 1
# define dataset
class0 = [0 for _ in range(25)]
class1 = [1 for _ in range(75)]
y = class0 + class1
# average performance over many repeats
results = list()
for _ in range(1000):
yhat = [random_guess() for _ in range(len(y))]
acc = accuracy_score(y, yhat)
results.append(acc)
print('Mean: %.3f' % mean(results))
L'esecuzione dell'esempio esegue 1.000 prove del nostro esperimento e riporta l'accuratezza media della strategia.
Il tuo risultato specifico varierà data la natura stocastica dell'algoritmo.
In questo caso, possiamo vedere che la prestazione attesa corrisponde molto da vicino alla prestazione calcolata. Data la legge dei grandi numeri, più prove eseguiamo di questo esperimento, più la nostra stima si avvicinerà al valore teorico che abbiamo calcolato.
Mean: 0.499
Questo è un buon inizio, ma cosa succederebbe se utilizzassimo alcune informazioni di base sulla composizione del set di dati di addestramento nella strategia? Lo esploreremo in seguito.
Prevedere una classe selezionata casualmente
Un altro approccio di classificazione ingenuo consiste nell'utilizzare in qualche modo il set di dati di addestramento.
Forse l'approccio più semplice sarebbe utilizzare le osservazioni nel set di dati di addestramento come previsioni. Nello specifico, possiamo selezionare in modo casuale le osservazioni nel set di addestramento e restituirle per ciascuna previsione richiesta.
Ciò ha senso e possiamo aspettarci che questo uso primitivo del set di dati di addestramento si traduca in una precisione ingenua leggermente migliore rispetto all'ipotesi casuale.
Possiamo scoprirlo calcolando la prestazione attesa dell’approccio utilizzando il nostro quadro probabilistico.
Se selezioniamo esempi dal set di dati di addestramento con una distribuzione di probabilità uniforme, disegneremo esempi da ciascuna classe con la stessa probabilità che si verifichino nel set di dati di addestramento. Cioè, disegneremo esempi di classe 0 con una probabilità del 25% e di classe 1 con una probabilità del 75%. Anche questa sarà la probabilità delle previsioni indipendenti del modello.
Con questa conoscenza, possiamo inserire questi valori nel modello probabilistico.
- P(yhat=y)=P(yhat=0) * P(y=0) + P(yhat=1) * P(y=1)
- P(yhat=y)=0,25 * 0,25 + 0,75 * 0,75
- P(yhat=y)=0,0625 + 0,5625
- P(yhat=y)=0,625
Il risultato suggerisce che l'utilizzo di una classe selezionata in modo uniforme e casuale dal set di dati di addestramento come previsione si traduce in un classificatore ingenuo migliore rispetto alla semplice previsione di una classe uniformemente casuale su questo set di dati, mostrando il 62,5% anziché il 50%, ovvero un aumento del 12,2%.
Non male!
Confermiamo nuovamente i nostri calcoli con una piccola simulazione.
La funzione random_class() di seguito implementa questa strategia di classificazione ingenua selezionando e restituendo un'etichetta di classe casuale dal set di dati di addestramento.
# predict a randomly selected class
def random_class(y):
return y[randint(len(y))]
Possiamo quindi utilizzare lo stesso framework della sezione precedente per valutare il modello 1.000 volte e riportare l'accuratezza media della classificazione in tali prove. Ci aspetteremmo che questa stima empirica corrisponda al nostro valore atteso o sia molto vicina ad esso.
L'esempio completo è elencato di seguito.
# example of selecting a random class naive classifier
from numpy import mean
from numpy.random import randint
from sklearn.metrics import accuracy_score
# predict a randomly selected class
def random_class(y):
return y[randint(len(y))]
# define dataset
class0 = [0 for _ in range(25)]
class1 = [1 for _ in range(75)]
y = class0 + class1
# average over many repeats
results = list()
for _ in range(1000):
yhat = [random_class(y) for _ in range(len(y))]
acc = accuracy_score(y, yhat)
results.append(acc)
print('Mean: %.3f' % mean(results))
L'esecuzione dell'esempio esegue 1.000 prove del nostro esperimento e riporta l'accuratezza media della strategia.
Il tuo risultato specifico varierà data la natura stocastica dell'algoritmo.
Anche in questo caso possiamo vedere che la prestazione attesa corrisponde molto da vicino alla prestazione calcolata: 62,4% nella simulazione contro 62,5% calcolato sopra.
Mean: 0.624
Forse possiamo fare di meglio di una distribuzione uniforme nel prevedere un’etichetta di classe. Esploreremo questo aspetto nella prossima sezione.
Prevedere la classe di maggioranza
Nella sezione precedente abbiamo esplorato una strategia che selezionava un'etichetta di classe in base a una distribuzione di probabilità uniforme sull'etichetta osservata nel set di dati di training.
Ciò ha consentito alla distribuzione di probabilità prevista di corrispondere alla distribuzione di probabilità osservata per ciascuna classe e di migliorare rispetto a una distribuzione uniforme delle etichette di classe. Uno svantaggio di questo set di dati sbilanciato, in particolare, è che ci si aspetta che una classe sia superiore all’altra in misura maggiore e la previsione casuale delle classi, anche in modo distorto, porta a troppe previsioni errate.
Possiamo invece prevedere la classe maggioritaria ed essere certi di ottenere un'accuratezza almeno pari a quella della composizione della classe maggioritaria nel set di dati di addestramento.
Cioè, se il 75% degli esempi nel set di addestramento sono di classe 1 e prevedessimo la classe 1 per tutti gli esempi, allora sappiamo che otterremmo almeno una precisione del 75%, un miglioramento rispetto alla selezione casuale di una classe come abbiamo fatto nella sezione precedente.
Possiamo confermarlo calcolando la prestazione attesa dell'approccio utilizzando il nostro modello di probabilità.
La probabilità che questa strategia di classificazione ingenua preveda la classe 0 sarebbe 0,0 (impossibile) e la probabilità di prevedere la classe 1 è 1,0 (certa). Perciò:
- P(yhat=y)=P(yhat=0) * P(y=0) + P(yhat=1) * P(y=1)
- P(yhat=y)=0,0 * 0,25 + 1,0 * 0,75
- P(yhat=y)=0,0 + 0,75
- P(yhat=y)=0,75
Ciò conferma le nostre aspettative e suggerisce che questa strategia fornirebbe un ulteriore incremento del 12,5% rispetto alla strategia precedente su questo specifico set di dati.
Ancora una volta, possiamo confermare questo approccio con una simulazione.
La classe maggioritaria può essere calcolata statisticamente utilizzando la modalità; cioè, l'osservazione più comune in una distribuzione.
È possibile utilizzare la funzione SciPy mode(). Restituisce due valori, il primo dei quali è la modalità che possiamo restituire. La funzione majority_class() di seguito implementa questo classificatore ingenuo.
# predict the majority class
def majority_class(y):
return mode(y)[0]
Possiamo quindi valutare la strategia sul set di dati artificioso. Non è necessario ripetere l'esperimento più volte poiché non esiste una componente casuale nella strategia e l'algoritmo fornirà ogni volta le stesse prestazioni sullo stesso set di dati.
L'esempio completo è elencato di seguito.
# example of a majority class naive classifier
from scipy.stats import mode
from sklearn.metrics import accuracy_score
# predict the majority class
def majority_class(y):
return mode(y)[0]
# define dataset
class0 = [0 for _ in range(25)]
class1 = [1 for _ in range(75)]
y = class0 + class1
# make predictions
yhat = [majority_class(y) for _ in range(len(y))]
# calculate accuracy
accuracy = accuracy_score(y, yhat)
print('Accuracy: %.3f' % accuracy)
L'esecuzione dell'esempio segnala l'accuratezza del classificatore ingenuo della classe maggioritaria sul set di dati.
L'accuratezza corrisponde al valore atteso calcolato dal quadro di probabilità del 75% e dalla composizione del set di dati di addestramento.
Accuracy: 0.750
Questo classificatore ingenuo della classe maggioritaria è il metodo da utilizzare per calcolare una prestazione di base sui problemi di modellazione predittiva di classificazione.
Funziona altrettanto bene per quei set di dati con un numero uguale di etichette di classe e per problemi con più di due etichette di classe, ad es. Problemi di classificazione multiclasse.
Ora che abbiamo scoperto il modello di classificazione naive con le migliori prestazioni, possiamo vedere come potremmo utilizzarlo nel nostro prossimo progetto.
Classificatori ingenui in scikit-learn
La libreria di machine learning scikit-learn fornisce un'implementazione dell'algoritmo di classificazione naive della classe di maggioranza che puoi utilizzare nel tuo prossimo progetto di modellazione predittiva di classificazione.
Viene fornito come parte della classe DummyClassifier.
Per utilizzare il classificatore ingenuo, la classe deve essere definita e l'argomento "strategia" impostato su "most_frequent" per garantire che venga prevista la classe maggioritaria. La classe può quindi essere adattata a un set di dati di training e utilizzata per fare previsioni su un set di dati di test o su un'altra strategia di valutazione del modello di ricampionamento.
...
# define model
model = DummyClassifier(strategy='most_frequent')
# fit model
model.fit(X, y)
# make predictions
yhat = model.predict(X)
In effetti, DummyClassifier è flessibile e consente di utilizzare gli altri due classificatori ingenui.
Nello specifico, impostando "strategia" su "uniforme" verrà eseguita la strategia di ipotesi casuale che abbiamo testato per prima e impostando "strategia" su "<stratificato” eseguirà la strategia di classe selezionata casualmente che abbiamo testato per seconda.
- Indovina casuale: imposta l'argomento "strategia" su "uniforme".
- Seleziona classe casuale: imposta l'argomento "strategia" su "stratificato".
- Classe di maggioranza: imposta l'argomento "strategia" su "più_frequente".
Possiamo confermare che DummyClassifier funziona come previsto con la strategia di classificazione ingenua della classe maggioritaria testandolo sul nostro set di dati artificioso.
L'esempio completo è elencato di seguito.
# example of the majority class naive classifier in scikit-learn
from numpy import asarray
from sklearn.dummy import DummyClassifier
from sklearn.metrics import accuracy_score
# define dataset
X = asarray([0 for _ in range(100)])
class0 = [0 for _ in range(25)]
class1 = [1 for _ in range(75)]
y = asarray(class0 + class1)
# reshape data for sklearn
X = X.reshape((len(X), 1))
# define model
model = DummyClassifier(strategy='most_frequent')
# fit model
model.fit(X, y)
# make predictions
yhat = model.predict(X)
# calculate accuracy
accuracy = accuracy_score(y, yhat)
print('Accuracy: %.3f' % accuracy)
L'esecuzione dell'esempio prepara il set di dati, quindi definisce e adatta DummyClassifier al set di dati utilizzando la strategia della classe di maggioranza.
La valutazione dell'accuratezza della classificazione delle previsioni del modello conferma che il modello funziona come previsto, ottenendo un punteggio del 75%.
Accuracy: 0.750
Questo esempio fornisce un punto di partenza per calcolare le prestazioni di base del classificatore naive sui propri progetti di modellazione predittiva di classificazione in futuro.
Ulteriori letture
Questa sezione fornisce più risorse sull'argomento se desideri approfondire.
- Qual è il livello di accuratezza casuale nei problemi di classificazione sbilanciati?
- Non utilizzare ipotesi casuali come classificatore di base
- API sklearn.dummy.DummyClassifier
Riepilogo
In questo tutorial hai scoperto come sviluppare e valutare strategie di classificazione ingenua per l'apprendimento automatico.
Nello specifico, hai imparato:
- Le prestazioni dei modelli di classificazione ingenui forniscono una base in base alla quale tutti gli altri modelli possono essere ritenuti abili o meno.
- Il classificatore di classe maggioritaria raggiunge una precisione migliore rispetto ad altri modelli di classificatore ingenuo, come l'ipotesi casuale e la previsione di un'etichetta di classe osservata selezionata casualmente.
- Le strategie di classificazione ingenua possono essere utilizzate su progetti di modellazione predittiva tramite la classe DummyClassifier nella libreria scikit-learn.
Hai qualche domanda?
Poni le tue domande nei commenti qui sotto e farò del mio meglio per rispondere.