Implementazione di SVM e Kernel SVM con Scikit-Learn di Python

Implementazione di SVM e Kernel SVM con Scikit-Learn di Python

Introduzione

Questa guida è la prima parte di tre guide sulle Support Vector Machines (SVM). In questa serie, lavoreremo su un caso d'uso di banconote contraffatte, conosceremo i semplici SVM, quindi gli iperparametri SVM e, infine, impareremo un concetto chiamato trucco del kernel ed esplorare altri tipi di SVM.

Se desideri leggere tutte le guide o vedere quali ti interessano di più, di seguito la tabella degli argomenti trattati in ciascuna guida:

1. Implementazione di SVM e Kernel SVM con Scikit-Learn di Python

  • Caso d'uso: dimentica le banconote
  • Sfondo di SVM
  • Modello SVM semplice (lineare).
    • Informazioni sul set di dati
    • Importazione del set di dati
    • Esplorazione del set di dati
  • Implementazione di SVM con Scikit-Learn
    • Divisione dei dati in set di treni/test
    • Formazione del modello
    • Fare previsioni
    • Valutazione del modello
    • Interpretazione dei risultati

2. Comprensione degli iperparametri SVM (Prossimamente!)

  • L'iperparametro C
  • L'iperparametro Gamma

3. Implementazione di altre versioni SVM con Scikit-Learn di Python (Prossimamente!)

  • L'idea generale delle SVM (un riepilogo)
  • Kernel (trucco) SVM
  • Implementazione del kernel SVM non lineare con Scikit-Learn
  • Importazione di librerie
    • Importazione del set di dati
    • Suddivisione dei dati in feature (X) e target (y)
    • Divisione dei dati in set di treni/test
    • Allenare l'algoritmo
  • Nucleo polinomiale
    • Fare previsioni
    • Valutazione dell'algoritmo
  • kernel gaussiano
    • Previsione e valutazione
  • Kernel sigmoideo
    • Previsione e valutazione
  • Confronto delle prestazioni del kernel non lineare

Caso d'uso: banconote contraffatte

A volte le persone trovano un modo per falsificare banconote. Se c'è una persona che guarda quelle note e ne verifica la validità, potrebbe essere difficile essere ingannati da loro.

Ma cosa succede quando non c'è una persona che guardi ogni nota? C'è un modo per sapere automaticamente se le banconote sono false o vere?

Ci sono molti modi per rispondere a queste domande. Una risposta è fotografare ogni banconota ricevuta, confrontarne l'immagine con l'immagine di una banconota contraffatta e quindi classificarla come vera o contraffatta. Una volta che potrebbe essere noioso o critico attendere la convalida della nota, sarebbe anche interessante fare rapidamente quel confronto.

Poiché le immagini vengono utilizzate, possono essere compattate, ridotte in scala di grigi e le loro misurazioni vengono estratte o quantizzate. In questo modo, il confronto avverrebbe tra le misure delle immagini, invece che tra i pixel di ciascuna immagine.

Finora abbiamo trovato un modo per elaborare e confrontare le banconote, ma come verranno classificate in vere o contraffatte? Possiamo usare l'apprendimento automatico per fare quella classificazione. Esiste un algoritmo di classificazione chiamato Supporta la macchina vettoriale, principalmente noto con la sua forma abbreviata: SVM.

Sfondo di SVM

Gli SVM furono introdotti inizialmente nel 1968, da Vladmir Vapnik e Alexey Chervonenkis. A quel tempo, il loro algoritmo era limitato alla classificazione dei dati che potevano essere separati utilizzando una sola linea retta, o dati che lo erano linearmente separabile. Possiamo vedere come sarebbe questa separazione:

Implementazione di SVM e Kernel SVM con Scikit-Learn PlatoBlockchain Data Intelligence di Python. Ricerca verticale. Ai.

Nell'immagine sopra abbiamo una linea nel mezzo, rispetto alla quale alcuni punti sono a sinistra, e altri sono a destra di quella linea. Si noti che entrambi i gruppi di punti sono perfettamente separati, non ci sono punti intermedi o vicini alla linea. Sembra esserci un margine tra punti simili e la linea che li divide, quel margine si chiama margine di separazione. La funzione del margine di separazione è quella di allargare lo spazio tra i punti simili e la linea che li divide. SVM lo fa utilizzando alcuni punti e calcola i suoi vettori perpendicolari per supportare la decisione per il margine della linea. Quelli sono i vettori di supporto che fanno parte del nome dell'algoritmo. Ne capiremo di più in seguito. E la linea retta che vediamo nel mezzo si trova con metodi che massimizzare quello spazio tra la linea e i punti, o che massimizza il margine di separazione. Tali metodi provengono dal campo di Teoria dell'ottimizzazione.

Nell'esempio che abbiamo appena visto, entrambi i gruppi di punti possono essere facilmente separati, poiché ogni singolo punto è vicino ai suoi punti simili, ei due gruppi sono lontani l'uno dall'altro.

Ma cosa succede se non c'è un modo per separare i dati utilizzando una linea retta? Se ci sono punti fuori posto disordinati o se è necessaria una curva?

Per risolvere questo problema, SVM è stato successivamente perfezionato negli anni '1990 per poter classificare anche i dati che avevano punti che erano lontani dalla sua tendenza centrale, come valori anomali o problemi più complessi che avevano più di due dimensioni e non erano linearmente separabili .

Ciò che è curioso è che solo negli ultimi anni le SVM sono state ampiamente adottate, principalmente per la loro capacità di ottenere talvolta più del 90% di risposte corrette o precisione, per problemi difficili.

Gli SVM sono implementati in un modo unico rispetto ad altri algoritmi di apprendimento automatico, una volta che si basano su spiegazioni statistiche di cosa sia l'apprendimento o su Teoria dell'apprendimento statistico.

In questo articolo vedremo quali sono gli algoritmi delle Support Vector Machines, la breve teoria dietro una support vector machine e la loro implementazione nella libreria Scikit-Learn di Python. Ci sposteremo quindi verso un altro concetto SVM, noto come SVM del kernel, o Trucco del noccioloe lo implementerà anche con l'aiuto di Scikit-Learn.

Modello SVM semplice (lineare).

Informazioni sul set di dati

Seguendo l'esempio fornito nell'introduzione, utilizzeremo un set di dati che contiene misurazioni di immagini di banconote reali e contraffatte.

Quando guardiamo due note, i nostri occhi di solito le scansionano da sinistra a destra e controllano dove potrebbero esserci somiglianze o differenze. Cerchiamo un punto nero che precede un punto verde o un segno lucido che si trova sopra un'illustrazione. Ciò significa che esiste un ordine in cui guardiamo le note. Se sapessimo che ci sono punti verdi e neri, ma non se il punto verde viene prima del nero, o se il nero viene prima del verde, sarebbe più difficile discriminare tra le note.

Esiste un metodo simile a quello appena descritto che può essere applicato alle immagini delle banconote. In termini generali, questo metodo consiste nel tradurre i pixel dell'immagine in un segnale, prendendo poi in considerazione l'ordine in cui ogni diverso segnale si presenta nell'immagine trasformandolo in piccole onde, oppure piccole onde. Dopo aver ottenuto le wavelet, c'è un modo per conoscere l'ordine in cui un segnale si verifica prima di un altro, o il tempo, ma non esattamente quale segnale. Per saperlo, è necessario ottenere le frequenze dell'immagine. Sono ottenuti con un metodo che esegue la scomposizione di ciascun segnale, chiamato Metodo di Fourier.

Una volta ottenuta la dimensione del tempo tramite le wavelet, e la dimensione della frequenza tramite il metodo di Fourier, si fa una sovrapposizione di tempo e frequenza per vedere quando entrambi hanno una corrispondenza, questa è la circonvoluzione analisi. La convoluzione ottiene un adattamento che abbina le wavelet alle frequenze dell'immagine e scopre quali frequenze sono più prominenti.

Viene chiamato questo metodo che prevede di trovare le wavelet, le loro frequenze e quindi adattarle entrambe Trasformata wavelet. La trasformata wavelet ha coefficienti e quei coefficienti sono stati usati per ottenere le misurazioni che abbiamo nel set di dati.

Importazione del set di dati

Il set di dati sulle banconote che utilizzeremo in questa sezione è lo stesso utilizzato nella sezione di classificazione del Tutorial sull'albero delle decisioni.

Nota: Puoi scaricare il set di dati qui.

Importiamo i dati in un panda dataframe struttura e dai un'occhiata alle sue prime cinque righe con il head() metodo.

Si noti che i dati vengono salvati in a txt (testo) formato di file, separato da virgole, ed è senza intestazione. Possiamo ricostruirlo come tabella leggendolo come a csv, specificando il separator come virgola e aggiungendo i nomi delle colonne con il names discussione.

Seguiamo questi tre passaggi contemporaneamente, quindi osserviamo le prime cinque righe di dati:

import pandas as pd data_link = "https://archive.ics.uci.edu/ml/machine-learning-databases/00267/data_banknote_authentication.txt"
col_names = ["variance", "skewness", "curtosis", "entropy", "class"] bankdata = pd.read_csv(data_link, names=col_names, sep=",", header=None)
bankdata.head()

Questo risulta in:

	variance skewness curtosis entropy class
0 3.62160 8.6661 -2.8073 -0.44699 0
1 4.54590 8.1674 -2.4586 -1.46210 0
2 3.86600 -2.6383 1.9242 0.10645 0
3 3.45660 9.5228 -4.0112 -3.59440 0
4 0.32924 -4.4552 4.5718 -0.98880 0

Nota: Puoi anche salvare i dati localmente e sostituirli data_link per data_pathe passa il percorso al tuo file locale.

Possiamo vedere che ci sono cinque colonne nel nostro set di dati, vale a dire, variance, skewness, curtosis, entropye class. Nelle cinque righe, le prime quattro colonne sono riempite con numeri come 3.62160, 8.6661, -2.8073 o continuo valori e l'ultimo class colonna ha le prime cinque righe piene di 0 o a distinto valore.

Poiché il nostro obiettivo è prevedere se una banconota in valuta bancaria è autentica o meno, possiamo farlo in base ai quattro attributi della banconota:

  • variance dell'immagine trasformata Wavelet. Generalmente, la varianza è un valore continuo che misura quanto i punti dati sono vicini o lontani dal valore medio dei dati. Se i punti sono più vicini al valore medio dei dati, la distribuzione è più vicina a una distribuzione normale, il che di solito significa che i suoi valori sono più ben distribuiti e in qualche modo più facili da prevedere. Nel contesto dell'immagine corrente, questa è la varianza dei coefficienti che risultano dalla trasformata wavelet. Minore varianza, più vicini erano i coefficienti alla traduzione dell'immagine reale.

  • skewness dell'immagine trasformata Wavelet. L'asimmetria è un valore continuo che indica l'asimmetria di una distribuzione. Se ci sono più valori a sinistra della media, la distribuzione è distorta negativamente, se ci sono più valori a destra della media, la distribuzione è positivamente sbilanciato, e se la media, la moda e la mediana sono uguali, la distribuzione lo è simmetrico. Più una distribuzione è simmetrica, più si avvicina a una distribuzione normale, avendo anche i suoi valori più ben distribuiti. Nel presente contesto, questa è l'asimmetria dei coefficienti che risultano dalla trasformata wavelet. Più simmetrico, più vicini sono i coefficienti noivariance, skewness, curtosis, entropyre alla traduzione dell'immagine reale.

Implementazione di SVM e Kernel SVM con Scikit-Learn PlatoBlockchain Data Intelligence di Python. Ricerca verticale. Ai.

  • curtosis (o curtosi) dell'immagine trasformata Wavelet. La curtosi è un valore continuo che, come l'asimmetria, descrive anche la forma di una distribuzione. A seconda del coefficiente di curtosi (k), una distribuzione – rispetto alla distribuzione normale può essere più o meno piatta – oppure avere più o meno dati alle estremità o code. Quando la distribuzione è più ampia e piatta, viene chiamata platycurtic; quando è meno disteso e più concentrato al centro, mesokurtico; e quando la distribuzione è quasi interamente concentrata nel mezzo, si chiama leptocurtico. Questo è lo stesso caso dei casi precedenti di varianza e asimmetria, più la distribuzione è mesokurtica, più i coefficienti erano vicini alla traduzione dell'immagine reale.

Implementazione di SVM e Kernel SVM con Scikit-Learn PlatoBlockchain Data Intelligence di Python. Ricerca verticale. Ai.

  • entropy di immagine. L'entropia è anche un valore continuo, di solito misura la casualità o il disordine in un sistema. Nel contesto di un'immagine, l'entropia misura la differenza tra un pixel e i pixel vicini. Per il nostro contesto, maggiore è l'entropia dei coefficienti, maggiore è stata la perdita durante la trasformazione dell'immagine e minore è l'entropia, minore è la perdita di informazioni.

Implementazione di SVM e Kernel SVM con Scikit-Learn PlatoBlockchain Data Intelligence di Python. Ricerca verticale. Ai.

La quinta variabile era il class variabile, che probabilmente ha valori 0 e 1, che indicano se la banconota era reale o contraffatta.

Possiamo verificare se la quinta colonna contiene zeri e uno con Panda unique() Metodo:

bankdata['class'].unique()

Il metodo precedente restituisce:

array([0, 1]) 

Il metodo precedente restituisce un array con valori 0 e 1. Ciò significa che gli unici valori contenuti nelle nostre righe di classe sono zero e uno. È pronto per essere utilizzato come bersaglio nel nostro apprendimento supervisionato.

  • class di immagine. Questo è un valore intero, è 0 quando l'immagine è contraffatta e 1 quando l'immagine è reale.

Poiché abbiamo una colonna con le annotazioni di immagini reali e dimenticate, questo significa che il nostro tipo di apprendimento è supervisionato.

Consigli: per saperne di più sul ragionamento alla base della Wavelet Transform sulle immagini delle banconote e sull'uso di SVM, leggi l' articolo pubblicato dagli autori.

Possiamo anche vedere quanti record o immagini abbiamo, osservando il numero di righe nei dati tramite il file shape proprietà:

bankdata.shape

Questo produce:

(1372, 5)

La riga sopra indica che ci sono 1,372 righe di immagini di banconote trasformate e 5 colonne. Questi sono i dati che andremo ad analizzare.

Abbiamo importato il nostro set di dati e fatto alcuni controlli. Ora possiamo esplorare i nostri dati per capirli meglio.

Esplorazione del set di dati

Abbiamo appena visto che ci sono solo zeri e uno nella colonna della classe, ma possiamo anche sapere in che proporzione sono – in altre parole – se ci sono più zeri che uno, più uno che zeri, o se i numeri di zeri è uguale al numero di uno, nel senso che lo sono balanced.

Per conoscere la proporzione possiamo contare ciascuno dei valori zero e uno nei dati con value_counts() Metodo:

bankdata['class'].value_counts()

Questo produce:

0 762
1 610
Name: class, dtype: int64

Nel risultato sopra, possiamo vedere che ci sono 762 zeri e 610 uno, o 152 zeri in più rispetto agli uno. Ciò significa che abbiamo immagini un po' più contraffatte rispetto a quelle reali e se tale discrepanza fosse maggiore, ad esempio 5500 zeri e 610 unità, potrebbe avere un impatto negativo sui nostri risultati. Una volta che stiamo provando a utilizzare quegli esempi nel nostro modello - più esempi ci sono, di solito significa che più informazioni il modello dovrà decidere tra banconote false o reali - se ci sono pochi esempi di note reali, il modello è incline a essere sbagliato quando si cerca di riconoscerli.

Sappiamo già che ci sono altre 152 note contraffatte, ma possiamo essere sicuri che questi siano esempi sufficienti per il modello da apprendere? Sapere quanti esempi sono necessari per l'apprendimento è una domanda molto difficile a cui rispondere, invece, possiamo provare a capire, in termini percentuali, quanto è questa differenza tra le classi.

Il primo passo è usare i panda value_counts() metodo di nuovo, ma ora vediamo la percentuale includendo l'argomento normalize=True:

bankdata['class'].value_counts(normalize=True)

Il normalize=True calcola la percentuale dei dati per ogni classe. Finora, la percentuale di dati contraffatti (0) e reali (1) è:

0 0.555394
1 0.444606
Name: class, dtype: float64

Ciò significa che circa (~) il 56% del nostro set di dati è contraffatto e il 44% è reale. Questo ci dà un rapporto del 56%-44%, che equivale a una differenza del 12%. Questa è statisticamente considerata una piccola differenza, perché è di poco superiore al 10%, quindi i dati sono considerati equilibrati. Se invece di una proporzione di 56:44, ci fosse una proporzione di 80:20 o 70:30, allora i nostri dati sarebbero considerati squilibrati e avremmo bisogno di un trattamento per lo squilibrio, ma, fortunatamente, non è così.

Possiamo anche vedere questa differenza visivamente, dando un'occhiata alla distribuzione della classe o del target con un istogramma intriso di Pandas, usando:

bankdata['class'].plot.hist();

Questo traccia un istogramma utilizzando direttamente la struttura del dataframe, in combinazione con il file matplotlib libreria che sta dietro le quinte.

Implementazione di SVM e Kernel SVM con Scikit-Learn PlatoBlockchain Data Intelligence di Python. Ricerca verticale. Ai.

Osservando l'istogramma, possiamo essere sicuri che i nostri valori target siano 0 o 1 e che i dati siano bilanciati.

Questa era un'analisi della colonna che stavamo cercando di prevedere, ma per quanto riguarda l'analisi delle altre colonne dei nostri dati?

Possiamo dare un'occhiata alle misurazioni statistiche con il describe() metodo dataframe. Possiamo anche usare .T di trasposizione – per invertire colonne e righe, rendendo più diretto il confronto tra valori:

Dai un'occhiata alla nostra guida pratica e pratica per l'apprendimento di Git, con le migliori pratiche, gli standard accettati dal settore e il cheat sheet incluso. Smetti di cercare su Google i comandi Git e in realtà imparare esso!

bankdata.describe().T

Questo risulta in:

 count mean std min 25% 50% 75% max
variance 1372.0 0.433735 2.842763 -7.0421 -1.773000 0.49618 2.821475 6.8248
skewness 1372.0 1.922353 5.869047 -13.7731 -1.708200 2.31965 6.814625 12.9516
curtosis 1372.0 1.397627 4.310030 -5.2861 -1.574975 0.61663 3.179250 17.9274
entropy 1372.0 -1.191657 2.101013 -8.5482 -2.413450 -0.58665 0.394810 2.4495
class 1372.0 0.444606 0.497103 0.0000 0.000000 0.00000 1.000000 1.0000

Si noti che le colonne di skewness e curtosis hanno valori medi che sono lontani dai valori di deviazione standard, questo indica che quei valori che sono più lontani dalla tendenza centrale dei dati o hanno una maggiore variabilità.

Possiamo anche dare un'occhiata visivamente alla distribuzione di ogni caratteristica, tracciando l'istogramma di ogni caratteristica all'interno di un ciclo for. Oltre a guardare la distribuzione, sarebbe interessante vedere come sono separati i punti di ogni classe rispetto a ciascuna caratteristica. Per fare ciò, possiamo tracciare un grafico a dispersione creando una combinazione di caratteristiche tra di loro e assegnare colori diversi a ciascun punto rispetto alla sua classe.

Iniziamo con la distribuzione di ciascuna caratteristica e tracciamo l'istogramma di ciascuna colonna di dati ad eccezione di class colonna. Il class la colonna non verrà presa in considerazione dalla sua posizione nell'array delle colonne bankdata. Verranno selezionate tutte le colonne tranne l'ultima con columns[:-1]:

import matplotlib.pyplot as plt for col in bankdata.columns[:-1]: plt.title(col) bankdata[col].plot.hist() plt.show();

Dopo aver eseguito il codice precedente, possiamo vedere che entrambi skewness ed entropy le distribuzioni dei dati sono distorte negativamente e curtosis è positivamente distorto. Tutte le distribuzioni sono simmetriche e variance è l'unica distribuzione vicina alla normalità.

Possiamo ora passare alla seconda parte e tracciare il grafico a dispersione di ciascuna variabile. Per fare ciò, possiamo anche selezionare tutte le colonne ad eccezione della classe, con columns[:-1], usa quello di Seaborn scatterplot() e due cicli for per ottenere le variazioni di abbinamento per ciascuna delle caratteristiche. Possiamo anche escludere l'abbinamento di una caratteristica con se stessa, verificando se la prima caratteristica è uguale alla seconda con un if statement.

import seaborn as sns for feature_1 in bankdata.columns[:-1]: for feature_2 in bankdata.columns[:-1]: if feature_1 != feature_2: print(feature_1, feature_2) sns.scatterplot(x=feature_1, y=feature_2, data=bankdata, hue='class') plt.show();

Si noti che tutti i grafici hanno punti dati reali e contraffatti non chiaramente separati l'uno dall'altro, ciò significa che esiste una sorta di sovrapposizione di classi. Poiché un modello SVM utilizza una linea per separare le classi, uno qualsiasi di questi gruppi nei grafici potrebbe essere separato utilizzando una sola linea? Sembra improbabile. Questo è l'aspetto della maggior parte dei dati reali. Il massimo che possiamo avvicinare a una separazione è nella combinazione di skewness ed variance, o entropy ed variance trame. Ciò è probabilmente dovuto a variance dati con una forma di distribuzione più vicina alla normale.

Ma guardare tutti quei grafici in sequenza può essere un po' difficile. Abbiamo l'alternativa di guardare insieme tutti i grafici di distribuzione e dispersione usando Seaborn's pairplot().

Entrambi i precedenti cicli for che avevamo fatto possono essere sostituiti solo da questa riga:

sns.pairplot(bankdata, hue='class');

Osservando il pairplot, sembra che, in realtà, curtosis ed variance sarebbe la combinazione più semplice di caratteristiche, quindi le diverse classi potrebbero essere separate da una linea, o linearmente separabile.

Se la maggior parte dei dati è lontana dall'essere linearmente separabile, possiamo provare a preelaborarli, riducendone le dimensioni, e anche normalizzarne i valori per cercare di rendere la distribuzione più vicina a una normale.

In questo caso, usiamo i dati così come sono, senza ulteriore pre-elaborazione, e successivamente possiamo tornare indietro di un passaggio, aggiungere alla pre-elaborazione dei dati e confrontare i risultati.

Consigli: Quando si lavora con i dati, le informazioni vengono solitamente perse durante la trasformazione, perché stiamo facendo approssimazioni, invece di raccogliere più dati. Lavorare prima con i dati iniziali così come sono, se possibile, offre una linea di base prima di provare altre tecniche di pre-elaborazione. Seguendo questo percorso, il risultato iniziale che utilizza dati grezzi può essere confrontato con un altro risultato che utilizza tecniche di pre-elaborazione sui dati.

Nota: Solitamente in Statistica, quando si costruiscono modelli, è comune seguire una procedura che dipende dal tipo di dato (discreto, continuo, categoriale, numerico), dalla sua distribuzione e dalle ipotesi del modello. Mentre in Computer Science (CS), c'è più spazio per tentativi, errori e nuove iterazioni. In CS è comune avere una linea di base con cui confrontare. In Scikit-learn, esiste un'implementazione di modelli fittizi (o stimatori fittizi), alcuni non sono migliori del lancio di una moneta e rispondono semplicemente (o 1) il 50% delle volte. È interessante utilizzare modelli fittizi come riferimento per il modello reale quando si confrontano i risultati. Si prevede che i risultati effettivi del modello siano migliori di un'ipotesi casuale, altrimenti non sarebbe necessario utilizzare un modello di apprendimento automatico.

Implementazione di SVM con Scikit-Learn

Prima di approfondire la teoria di come funziona SVM, possiamo costruire il nostro primo modello di base con i dati e Scikit-Learn Classificatore di vettori di supporto or SVC classe.

Il nostro modello riceverà i coefficienti wavelet e proverà a classificarli in base alla classe. Il primo passo in questo processo è separare i coefficienti o Caratteristiche dalla classe o bersaglio. Dopo questo passaggio, il secondo passaggio consiste nel suddividere ulteriormente i dati in un set che verrà utilizzato per l'apprendimento del modello o treno impostato e un altro che verrà utilizzato per la valutazione del modello o set di prova.

Nota: La nomenclatura di test e valutazione può creare un po' di confusione, perché puoi anche suddividere i tuoi dati tra treno, valutazione e serie di test. In questo modo, invece di avere due set, avresti un set intermedio solo da usare e vedere se le prestazioni del tuo modello stanno migliorando. Ciò significa che il modello verrebbe addestrato con il set di treni, migliorato con il set di valutazione e ottenuto una metrica finale con il set di test.

Alcune persone dicono che la valutazione è l'insieme intermedio, altri diranno che l'insieme di test è l'insieme intermedio e che l'insieme di valutazione è l'insieme finale. Questo è un altro modo per cercare di garantire che il modello non veda in alcun modo lo stesso esempio o che in qualche modo perdita di dati non sta accadendo e che esiste una generalizzazione del modello mediante il miglioramento delle ultime metriche impostate. Se vuoi seguire questo approccio, puoi dividere ulteriormente i dati ancora una volta come descritto in questo train_test_split() di Scikit-Learn – Set di addestramento, test e convalida guida.

Divisione dei dati in set di treni/test

Nella sessione precedente, abbiamo compreso ed esplorato i dati. Ora possiamo dividere i nostri dati in due array: uno per le quattro funzionalità e l'altro per la quinta o funzionalità di destinazione. Poiché vogliamo prevedere la classe in base ai coefficienti wavelet, il nostro y sarà il class colonna e il nostro X sarà il variance, skewness, curtosise entropy colonne.

Per separare il target e le caratteristiche, possiamo attribuire solo il class colonna a y, eliminandolo successivamente dal dataframe a cui attribuire le colonne rimanenti X con .drop() Metodo:

y = bankdata['class']
X = bankdata.drop('class', axis=1) 

Una volta che i dati sono divisi in attributi ed etichette, possiamo suddividerli ulteriormente in set di addestramento e test. Questo potrebbe essere fatto a mano, ma il model_selection libreria di Scikit-Learn contiene il file train_test_split() metodo che ci consente di dividere casualmente i dati in set di addestramento e test.

Per usarlo, possiamo importare la libreria, chiamare il file train_test_split() metodo, passare X ed y dati e definire a test_size passare come argomento. In questo caso, lo definiremo come 0.20– ciò significa che il 20% dei dati verrà utilizzato per i test e l'altro 80% per la formazione.

Questo metodo preleva campioni casualmente rispettando la percentuale che abbiamo definito, ma rispetta le coppie Xy, per evitare che il campionamento confonda totalmente la relazione.

Poiché il processo di campionamento è intrinsecamente casuale, avremo sempre risultati diversi durante l'esecuzione del metodo. Per poter avere gli stessi risultati, o risultati riproducibili, possiamo definire una costante chiamata SEED con il valore di 42.

È possibile eseguire il seguente script per farlo:

from sklearn.model_selection import train_test_split SEED = 42 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = SEED)

Si noti che il train_test_split() metodo restituisce già il X_train, X_test, y_train, y_test imposta in questo ordine. Possiamo stampare il numero di campioni separati per train e test ottenendo il primo (0) elemento del file shape proprietà restituita tupla:

xtrain_samples = X_train.shape[0]
xtest_samples = X_test.shape[0] print(f'There are {xtrain_samples} samples for training and {xtest_samples} samples for testing.')

Questo dimostra che ci sono 1097 campioni per l'addestramento e 275 per il test.

Formazione del modello

Abbiamo suddiviso i dati in treni e set di test. Ora è il momento di creare e addestrare un modello SVM sui dati del treno. Per fare ciò, possiamo importare Scikit-Learn svm biblioteca insieme al Classificatore di vettori di supporto classe, o SVC classe.

Dopo aver importato la classe, possiamo crearne un'istanza - poiché stiamo creando un semplice modello SVM, stiamo cercando di separare i nostri dati in modo lineare, quindi possiamo tracciare una linea per dividere i nostri dati - che è lo stesso che usare un funzione lineare – definendo kernel='linear' come argomento per il classificatore:

from sklearn.svm import SVC
svc = SVC(kernel='linear')

In questo modo, il classificatore cercherà di trovare una funzione lineare che separi i nostri dati. Dopo aver creato il modello, addestriamolo o in forma it, con i dati del treno, utilizzando il fit() metodo e dando il X_train caratteristiche e y_train obiettivi come argomenti.

Possiamo eseguire il seguente codice per addestrare il modello:

svc.fit(X_train, y_train)

Proprio così, il modello viene addestrato. Finora abbiamo compreso i dati, li abbiamo divisi, creato un semplice modello SVM e adattato il modello ai dati del treno.

Il prossimo passo è capire quanto bene quell'adattamento è riuscito a descrivere i nostri dati. In altre parole, per rispondere se una SVM lineare fosse una scelta adeguata.

Fare previsioni

Un modo per rispondere se il modello è riuscito a descrivere i dati è calcolare e guardare una classificazione metrica.

Considerando che l'apprendimento è supervisionato, possiamo fare previsioni con X_test e confronta quei risultati di previsione - che potremmo chiamare y_pred – con il reale y_test, o realtà di base.

Per prevedere alcuni dei dati, quelli del modello predict() metodo può essere impiegato. Questo metodo riceve le funzionalità di test, X_test, come argomento e restituisce una previsione, 0 o 1, per ognuno di X_testle righe.

Dopo aver previsto il X_test dati, i risultati vengono memorizzati in a y_pred variabile. Quindi ciascuna delle classi previste con il semplice modello SVM lineare è ora in y_pred variabile.

Questo è il codice di previsione:

y_pred = svc.predict(X_test)

Considerando che abbiamo le previsioni, ora possiamo confrontarle con i risultati effettivi.

Valutazione del modello

Esistono diversi modi per confrontare le previsioni con i risultati effettivi e misurano diversi aspetti di una classificazione. Alcune metriche di classificazione più utilizzate sono:

  1. Matrice di confusione: quando abbiamo bisogno di sapere quanti campioni abbiamo ottenuto giusto o sbagliato ogni classe. Vengono chiamati i valori che erano corretti e correttamente previsti veri positivi, vengono chiamati quelli previsti come positivi ma che non lo erano falsi positivi. La stessa nomenclatura di veri negativi ed falsi negativi è usato per valori negativi;

  2. Precisione: quando il nostro obiettivo è capire quali valori di previsione corretti sono stati considerati corretti dal nostro classificatore. La precisione dividerà quei veri valori positivi per i campioni previsti come positivi;

$$
precisione = frac{testo{veri positivi}}{testo{veri positivi} + testo{falsi positivi}}
$$

  1. Richiamo: comunemente calcolato insieme alla precisione per capire quanti dei veri positivi sono stati individuati dal nostro classificatore. Il richiamo viene calcolato dividendo i veri positivi per tutto ciò che avrebbe dovuto essere previsto come positivo.

$$
recall = frac{testo{veri positivi}}{testo{veri positivi} + testo{falsi negativi}}
$$

  1. punteggio F1: è il bilanciato o media armonica di precisione e di richiamo. Il valore più basso è 0 e il più alto è 1. Quando f1-score è uguale a 1, significa che tutte le classi sono state previste correttamente – questo è un punteggio molto difficile da ottenere con dati reali (le eccezioni esistono quasi sempre).

$$
testo{f1-score} = 2* frac{testo{precision} * testo{recall}}{text{precision} + testo{recall}}
$$

Abbiamo già avuto familiarità con le misure di matrice di confusione, precisione, richiamo e punteggio F1. Per calcolarli, possiamo importare quelli di Scikit-Learn metrics biblioteca. Questa libreria contiene il classification_report ed confusion_matrix metodi, il metodo del rapporto di classificazione restituisce la precisione, il richiamo e il punteggio f1. Entrambi classification_report ed confusion_matrix può essere facilmente utilizzato per scoprire i valori di tutte quelle metriche importanti.

Per calcolare le metriche, importiamo i metodi, li chiamiamo e passiamo come argomenti le classificazioni previste, y_test, e le etichette di classificazione, o y_true.

Per una migliore visualizzazione della matrice di confusione, possiamo tracciarla in un Seaborn's heatmap insieme alle annotazioni di quantità, e per il rapporto di classificazione, è meglio stampare il suo risultato, quindi i suoi risultati sono formattati. Questo è il seguente codice:

from sklearn.metrics import classification_report, confusion_matrix cm = confusion_matrix(y_test,y_pred)
sns.heatmap(cm, annot=True, fmt='d').set_title('Confusion matrix of linear SVM') print(classification_report(y_test,y_pred))

Questo mostra:

 precision recall f1-score support 0 0.99 0.99 0.99 148 1 0.98 0.98 0.98 127 accuracy 0.99 275 macro avg 0.99 0.99 0.99 275
weighted avg 0.99 0.99 0.99 275

Implementazione di SVM e Kernel SVM con Scikit-Learn PlatoBlockchain Data Intelligence di Python. Ricerca verticale. Ai.

Nel rapporto di classificazione, sappiamo che c'è una precisione di 0.99, un richiamo di 0.99 e un punteggio f1 di 0.99 per le banconote contraffatte, o classe 0. Tali misurazioni sono state ottenute utilizzando 148 campioni come mostrato nella colonna di supporto. Nel frattempo, per la classe 1, o note reali, il risultato è stato di un'unità inferiore, 0.98 di precisione, 0.98 di richiamo e lo stesso punteggio f1. Questa volta, per ottenere questi risultati sono state utilizzate 127 misurazioni di immagini.

Se guardiamo alla matrice di confusione, possiamo anche vedere che su 148 campioni di classe 0, 146 sono stati classificati correttamente e c'erano 2 falsi positivi, mentre per 127 campioni di classe 1 c'erano 2 falsi negativi e 125 veri positivi.

Possiamo leggere il rapporto di classificazione e la matrice di confusione, ma cosa significano?

Interpretazione dei risultati

Per scoprire il significato, diamo un'occhiata a tutte le metriche combinate.

Quasi tutti i campioni per la classe 1 sono stati classificati correttamente, ci sono stati 2 errori per il nostro modello nell'identificazione delle banconote effettive. Questo è lo stesso di 0.98, o 98%, di richiamo. Qualcosa di simile si può dire della classe 0, solo 2 campioni sono stati classificati in modo errato, mentre 148 sono veri negativi, totalizzando una precisione del 99%.

Oltre a questi risultati, tutti gli altri segnano 0.99, che è quasi 1, una metrica molto alta. La maggior parte delle volte, quando una metrica così elevata si verifica con i dati della vita reale, ciò potrebbe indicare un modello che è troppo adattato ai dati o sovradimensionato.

Quando c'è un overfit, il modello potrebbe funzionare bene quando prevede i dati che sono già noti, ma perde la capacità di generalizzare a nuovi dati, che è importante negli scenari del mondo reale.

Un rapido test per scoprire se si sta verificando un overfit è anche con i dati del treno. Se il modello ha in qualche modo memorizzato i dati del treno, le metriche saranno molto vicine all'1 o al 100%. Ricorda che i dati del treno sono più grandi dei dati del test – per questo motivo – prova a guardarli in proporzione, più campioni, più possibilità di sbagliare, a meno che non ci sia stato qualche overfit.

Per prevedere con i dati del treno, possiamo ripetere ciò che abbiamo fatto per i dati di prova, ma ora con X_train:

y_pred_train = svc.predict(X_train) cm_train = confusion_matrix(y_train,y_pred_train)
sns.heatmap(cm_train, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with train data') print(classification_report(y_train,y_pred_train))

Questo produce:

 precision recall f1-score support 0 0.99 0.99 0.99 614 1 0.98 0.99 0.99 483 accuracy 0.99 1097 macro avg 0.99 0.99 0.99 1097
weighted avg 0.99 0.99 0.99 1097

Implementazione di SVM e Kernel SVM con Scikit-Learn PlatoBlockchain Data Intelligence di Python. Ricerca verticale. Ai.

È facile vedere che sembra esserci un overfit, una volta che le metriche del treno sono del 99% quando si hanno 4 volte più dati. Cosa si può fare in questo scenario?

Per ripristinare l'overfit, possiamo aggiungere più osservazioni di addestramento, utilizzare un metodo di addestramento con diverse parti del set di dati, ad esempio convalida incrociatae modificare anche i parametri predefiniti che già esistono prima dell'addestramento, durante la creazione del nostro modello, o iperparametri. La maggior parte delle volte, Scikit-learn imposta alcuni parametri come predefiniti, e questo può avvenire silenziosamente se non c'è molto tempo dedicato alla lettura della documentazione.

Puoi consultare la seconda parte di questa guida (Prossimamente!) per vedere come implementare la convalida incrociata ed eseguire un'ottimizzazione degli iperparametri.

Conclusione

In questo articolo abbiamo studiato il semplice kernel lineare SVM. Abbiamo avuto l'intuizione dietro l'algoritmo SVM, utilizzato un set di dati reale, esplorato i dati e visto come questi dati possono essere utilizzati insieme a SVM implementandolo con la libreria Scikit-Learn di Python.

Per continuare a esercitarti, puoi provare altri set di dati del mondo reale disponibili in luoghi come Kaggle, UCI, Set di dati pubblici BigQuery, università e siti web governativi.

Suggerirei anche di esplorare la vera matematica dietro il modello SVM. Sebbene non ne avrai necessariamente bisogno per utilizzare l'algoritmo SVM, è comunque molto utile sapere cosa sta realmente accadendo dietro le quinte mentre il tuo algoritmo sta trovando i limiti decisionali.

Timestamp:

Di più da Impilamento