Implementarea SVM și Kernel SVM cu Scikit-Learn de la Python

Implementarea SVM și Kernel SVM cu Scikit-Learn de la Python

Introducere

Acest ghid este prima parte a trei ghiduri despre suport Vector Machines (SVMs). În această serie, vom lucra la un caz de utilizare a bancnotelor falsificate, vom afla despre SVM-ul simplu, apoi despre hiperparametrii SVM și, în final, vom afla un concept numit trucul nucleului și explorați alte tipuri de SVM-uri.

Dacă doriți să citiți toate ghidurile sau să vedeți care vă interesează cel mai mult, mai jos este tabelul cu subiectele abordate în fiecare ghid:

1. Implementarea SVM și Kernel SVM cu Scikit-Learn de la Python

  • Caz de utilizare: uitați bancnotele
  • Contextul SVM-urilor
  • Model SVM simplu (liniar).
    • Despre setul de date
    • Importul setului de date
    • Explorarea setului de date
  • Implementarea SVM cu Scikit-Learn
    • Împărțirea datelor în seturi de tren/test
    • Instruirea modelului
    • Realizarea previziunilor
    • Evaluarea modelului
    • Interpretarea rezultatelor

2. Înțelegerea hiperparametrilor SVM (in curand!)

  • Hiperparametrul C
  • Hiperparametrul Gamma

3. Implementarea altor variante SVM cu Scikit-Learn de la Python (in curand!)

  • Ideea generală a SVM-urilor (o recapitulare)
  • Kernel (truc) SVM
  • Implementarea SVM a nucleului neliniar cu Scikit-Learn
  • Importul bibliotecilor
    • Importul setului de date
    • Împărțirea datelor în caracteristici (X) și țintă (y)
    • Împărțirea datelor în seturi de tren/test
    • Antrenarea algoritmului
  • Nucleu polinom
    • Realizarea previziunilor
    • Evaluarea algoritmului
  • Miez gaussian
    • Predicție și evaluare
  • Nuezul sigmoid
    • Predicție și evaluare
  • Comparația performanțelor kernelului neliniar

Caz de utilizare: bancnote falsificate

Uneori oamenii găsesc o modalitate de a falsifica bancnote. Dacă există o persoană care se uită la acele note și le verifică validitatea, ar putea fi greu să fii înșelat de ele.

Dar ce se întâmplă când nu există o persoană care să se uite la fiecare bilet? Există o modalitate de a ști automat dacă bancnotele sunt falsificate sau reale?

Există multe moduri de a răspunde la aceste întrebări. Un răspuns este să fotografiați fiecare notă primită, să comparați imaginea acesteia cu imaginea unei note falsificate și apoi să o clasificați ca fiind reală sau falsificată. Odată ce ar putea fi obositor sau critic să așteptați validarea notei, ar fi, de asemenea, interesant să faceți rapid această comparație.

Deoarece imaginile sunt folosite, acestea pot fi compactate, reduse la tonuri de gri și pot fi extrase sau cuantificate măsurătorile. În acest fel, comparația ar fi între măsurătorile imaginilor, în loc de pixelul fiecărei imagini.

Până acum, am găsit o modalitate de a procesa și compara bancnotele, dar cum vor fi ele clasificate în reale sau falsificate? Putem folosi învățarea automată pentru a face această clasificare. Există un algoritm de clasificare numit Suport Vector Machine, cunoscut în principal prin forma sa prescurtată: SVM.

Contextul SVM-urilor

SVM-urile au fost introduse inițial în 1968, de către Vladmir Vapnik și Alexey Chervonenkis. La acel moment, algoritmul lor era limitat la clasificarea datelor care puteau fi separate folosind doar o singură linie dreaptă sau date care erau separabil liniar. Putem vedea cum ar arăta acea separare:

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

În imaginea de mai sus avem o linie în mijloc, la care unele puncte sunt la stânga, iar altele sunt la dreapta acelei linii. Observați că ambele grupuri de puncte sunt perfect separate, nu există puncte între sau chiar aproape de linie. Se pare că există o marjă între puncte similare și linia care le împarte, acea marjă se numește marja de separare. Funcția marginii de separare este de a mări spațiul dintre punctele similare și linia care le împarte. SVM face asta folosind unele puncte și calculează vectorii perpendiculari pentru a sprijini decizia pentru marginea dreptei. Acestea sunt vectori suport care fac parte din numele algoritmului. Vom înțelege mai multe despre ele mai târziu. Iar linia dreaptă pe care o vedem în mijloc se găsește prin metode care maximaliza acel spațiu dintre linie și puncte sau care maximizează marja de separare. Aceste metode provin din domeniul Teoria optimizării.

În exemplul pe care tocmai l-am văzut, ambele grupuri de puncte pot fi separate cu ușurință, deoarece fiecare punct individual este aproape unul de altul de punctele sale similare, iar cele două grupuri sunt departe unul de celălalt.

Dar ce se întâmplă dacă nu există o modalitate de a separa datele folosind o linie dreaptă? Dacă există puncte dezordonate în afara locului sau dacă este nevoie de o curbă?

Pentru a rezolva această problemă, SVM a fost ulterior rafinat în anii 1990 pentru a putea clasifica și datele care aveau puncte care erau departe de tendința sa centrală, cum ar fi valorile aberante sau probleme mai complexe care aveau mai mult de două dimensiuni și nu erau separabile liniar. .

Ceea ce este curios este că doar în ultimii ani SVM-urile au fost adoptate pe scară largă, în principal datorită capacității lor de a obține uneori mai mult de 90% din răspunsurile corecte sau precizie, pentru probleme dificile.

SVM-urile sunt implementate într-un mod unic în comparație cu alți algoritmi de învățare automată, odată ce se bazează pe explicații statistice despre ceea ce este învățarea sau pe Teoria învățării statistice.

În acest articol, vom vedea ce sunt algoritmii Support Vector Machines, scurta teorie din spatele unei mașini de suport vector și implementarea lor în biblioteca Scikit-Learn de la Python. Ne vom îndrepta apoi către un alt concept SVM, cunoscut ca Kernel SVM, Sau Trucul nucleuluiși îl va implementa, de asemenea, cu ajutorul Scikit-Learn.

Model SVM simplu (liniar).

Despre setul de date

Urmând exemplul dat în introducere, vom folosi un set de date care are măsurători de imagini de bancnote reale și falsificate.

Când privim două note, ochii noștri le scanează de obicei de la stânga la dreapta și verifică unde ar putea exista asemănări sau neasemănări. Căutăm un punct negru care vine înaintea unui punct verde sau un semn strălucitor care este deasupra unei ilustrații. Aceasta înseamnă că există o ordine în care ne uităm la notele. Dacă am ști că există puncte verzi și negre, dar nu dacă punctul verde vine înaintea negrului sau dacă negrul vine înaintea verdelui, ar fi mai greu să facem distincție între note.

Există o metodă similară cu cea pe care tocmai am descris-o, care poate fi aplicată imaginilor bancnotelor. În termeni generali, această metodă constă în translatarea pixelilor imaginii într-un semnal, luând apoi în considerare ordinea în care fiecare semnal diferit apare în imagine prin transformarea acestuia în unde mici, sau undelete. După obținerea waveletelor, există o modalitate de a cunoaște ordinea în care un semnal are loc înaintea altuia, sau timp, dar nu exact ce semnal. Pentru a ști asta, trebuie obținute frecvențele imaginii. Ele sunt obținute printr-o metodă care face descompunerea fiecărui semnal, numită Metoda Fourier.

Odată ce dimensiunea timpului este obținută prin wavelets și dimensiunea frecvenței prin metoda Fourier, se face o suprapunere a timpului și frecvenței pentru a vedea când ambele au o potrivire, aceasta este convoluţie analiză. Convoluția obține o potrivire care potrivește undeletele cu frecvențele imaginii și descoperă care frecvențe sunt mai proeminente.

Această metodă care implică găsirea undeletelor, frecvențele lor și apoi potrivirea ambelor, se numește Transformarea wavelet. Transformarea wavelet are coeficienți, iar acești coeficienți au fost utilizați pentru a obține măsurătorile pe care le avem în setul de date.

Importul setului de date

Setul de date de bancnote pe care îl vom folosi în această secțiune este același cu cel folosit în secțiunea de clasificare a tutorial pentru arborele de decizie.

Notă: Puteți descărca setul de date aici.

Să importăm datele într-un panda dataframe structura și aruncați o privire asupra primelor sale cinci rânduri cu head() metodă.

Observați că datele sunt salvate într-un txt format de fișier (text), separat prin virgule și nu are antet. Îl putem reconstrui ca un tabel citindu-l ca a csv, specificând separator sub formă de virgulă și adăugând numele coloanelor cu names a susținut.

Să urmăm cei trei pași simultan și apoi să ne uităm la primele cinci rânduri de date:

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()

Rezultă:

	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

Notă: De asemenea, puteți salva datele local și le puteți înlocui data_link pentru data_path, și trimiteți calea către fișierul dvs. local.

Putem vedea că există cinci coloane în setul nostru de date, și anume, variance, skewness, curtosis, entropy, și class. În cele cinci rânduri, primele patru coloane sunt umplute cu numere precum 3.62160, 8.6661, -2.8073 sau continuu valori, iar ultima class coloana are primele cinci rânduri umplute cu 0 sau a distinct valoare.

Deoarece obiectivul nostru este de a prezice dacă o bancnotă este autentică sau nu, putem face acest lucru pe baza celor patru atribute ale bancnotei:

  • variance de imagine Wavelet Transformed. În general, varianța este o valoare continuă care măsoară cât de mult punctele de date sunt aproape sau departe de valoarea medie a datelor. Dacă punctele sunt mai aproape de valoarea medie a datelor, distribuția este mai aproape de o distribuție normală, ceea ce înseamnă de obicei că valorile sale sunt mai bine distribuite și oarecum mai ușor de prezis. În contextul actual al imaginii, aceasta este varianța coeficienților care rezultă din transformarea wavelet. Cu cât variația este mai mică, cu atât coeficienții erau mai aproape de traducerea imaginii reale.

  • skewness de imagine Wavelet Transformed. Asimetria este o valoare continuă care indică asimetria unei distribuții. Dacă sunt mai multe valori în stânga mediei, distribuția este denaturată negativ, dacă sunt mai multe valori în dreapta mediei, distribuția este denaturată pozitiv, iar dacă media, modul și mediana sunt aceleași, distribuția este simetric. Cu cât o distribuție este mai simetrică, cu atât este mai aproape de o distribuție normală, având și valorile mai bine distribuite. În contextul prezent, aceasta este asimetria coeficienților care rezultă din transformarea wavelet. Cu cât sunt mai simetrici, cu atât coeficienții suntem mai apropiațivariance, skewness, curtosis, entropyreferitor la traducerea imaginii reale.

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

  • curtosis (sau curtoza) a imaginii Wavelet Transformed. Curtosis este o valoare continuă care, ca și asimetria, descrie și forma unei distribuții. În funcție de coeficientul de curtoză (k), o distribuție – în comparație cu distribuția normală poate fi mai mult sau mai puțin plată – sau poate avea mai multe sau mai puține date în extremitățile sau cozile sale. Când distribuția este mai răspândită și mai plată, se numește platykurtic; când este mai puțin răspândit și mai concentrat la mijloc, mezokurtic; iar când distribuția este aproape în întregime concentrată la mijloc, se numește leptokurtic. Acesta este același caz ca și cazurile anterioare de varianță și asimetrie, cu cât distribuția este mai mezokurtică, cu atât coeficienții erau mai aproape de traducerea imaginii reale.

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

  • entropy de imagine. Entropia este, de asemenea, o valoare continuă, de obicei măsoară aleatoritatea sau dezordinea dintr-un sistem. În contextul unei imagini, entropia măsoară diferența dintre un pixel și pixelii săi vecini. Pentru contextul nostru, cu cât coeficienții au mai multă entropie, cu atât a fost mai mare pierdere la transformarea imaginii – și cu cât entropia este mai mică, cu atât pierderea de informații este mai mică.

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

A cincea variabilă a fost class variabilă, care are probabil valori 0 și 1, care spun dacă nota a fost reală sau falsificată.

Putem verifica dacă a cincea coloană conține zerouri și unu cu Pandas unique() metodă:

bankdata['class'].unique()

Metoda de mai sus returnează:

array([0, 1]) 

Metoda de mai sus returnează o matrice cu valori 0 și 1. Aceasta înseamnă că singurele valori conținute în rândurile clasei noastre sunt zerouri și unu. Este gata pentru a fi folosit ca ţintă în învăţarea noastră supravegheată.

  • class de imagine. Aceasta este o valoare întreagă, este 0 când imaginea este falsificată și 1 când imaginea este reală.

Deoarece avem o coloană cu adnotările imaginilor reale și uitați, aceasta înseamnă că tipul nostru de învățare este supravegheat.

Indicații: pentru a afla mai multe despre raționamentul din spatele Transformării Wavelet pe imaginile bancnotelor și despre utilizarea SVM, citiți lucrarea publicată a autorilor.

De asemenea, putem vedea câte înregistrări sau imagini avem, analizând numărul de rânduri din date prin intermediul shape proprietate:

bankdata.shape

Acest rezultat:

(1372, 5)

Linia de mai sus înseamnă că există 1,372 de rânduri de imagini de bancnote transformate și 5 coloane. Acestea sunt datele pe care le vom analiza.

Ne-am importat setul de date și am efectuat câteva verificări. Acum putem explora datele noastre pentru a le înțelege mai bine.

Explorarea setului de date

Tocmai am văzut că în coloana clasei sunt doar zerouri și unu, dar putem ști și în ce proporție sunt acestea – cu alte cuvinte – dacă sunt mai multe zerouri decât unu, mai multe unu decât zero sau dacă numerele de zerouri este același cu numărul de unu, adică sunt echilibrat.

Pentru a cunoaște proporția putem număra fiecare dintre valorile zero și unu din date cu value_counts() metodă:

bankdata['class'].value_counts()

Acest rezultat:

0 762
1 610
Name: class, dtype: int64

În rezultatul de mai sus, putem vedea că există 762 de zerouri și 610 de unități, sau cu 152 de zerouri mai multe decât unu. Aceasta înseamnă că am falsificat puțin mai mult decât imaginile reale și, dacă această discrepanță ar fi mai mare, de exemplu, 5500 de zerouri și 610 de unități, ar putea avea un impact negativ asupra rezultatelor noastre. Odată ce încercăm să folosim acele exemple în modelul nostru – cu cât există mai multe exemple, înseamnă de obicei că modelul va trebui să decidă între notele falsificate sau reale – dacă există puține exemple de note reale, modelul este predispus să fie greșit când încearcă să le recunoască.

Știm deja că există încă 152 de note falsificate, dar putem fi siguri că acestea sunt suficiente exemple pentru ca modelul să le învețe? A ști de câte exemple sunt necesare pentru învățare este o întrebare foarte greu de răspuns, în schimb, putem încerca să înțelegem, în termeni procentuali, cât de mare este acea diferență între clase.

Primul pas este să folosești panda value_counts() metoda din nou, dar acum să vedem procentul prin includerea argumentului normalize=True:

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

normalize=True calculează procentul de date pentru fiecare clasă. Până acum, procentul de date falsificate (0) și reale (1) este:

0 0.555394
1 0.444606
Name: class, dtype: float64

Aceasta înseamnă că aproximativ (~) 56% din setul nostru de date este falsificat și 44% din acesta este real. Acest lucru ne oferă un raport de 56%-44%, care este același cu o diferență de 12%. Aceasta este considerată statistic o diferență mică, deoarece este puțin peste 10%, deci datele sunt considerate echilibrate. Dacă în loc de o proporție de 56:44, ar exista o proporție de 80:20 sau 70:30, atunci datele noastre ar fi considerate dezechilibrate și ar trebui să facem un tratament de dezechilibru, dar, din fericire, nu este cazul.

De asemenea, putem vedea această diferență vizual, aruncând o privire asupra distribuției clasei sau țintei cu o histogramă impregnată cu Pandas, utilizând:

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

Aceasta trasează o histogramă utilizând direct structura cadrului de date, în combinație cu matplotlib bibliotecă care se află în culise.

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Privind histogramă, putem fi siguri că valorile noastre țintă sunt fie 0, fie 1 și că datele sunt echilibrate.

Aceasta a fost o analiză a coloanei pe care încercam să o prevedem, dar cum rămâne cu analiza celorlalte coloane ale datelor noastre?

Putem arunca o privire asupra măsurătorilor statistice cu describe() metoda cadrelor de date. Putem folosi, de asemenea .T de transpunere – pentru a inversa coloanele și rândurile, făcând compararea mai directă între valori:

Consultați ghidul nostru practic și practic pentru a învăța Git, cu cele mai bune practici, standarde acceptate de industrie și fisa de cheat incluse. Opriți căutarea pe Google a comenzilor Git și de fapt învăţa aceasta!

bankdata.describe().T

Rezultă:

 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

Observați că coloanele de asimetrie și curtoză au valori medii care sunt departe de valorile deviației standard, ceea ce indică faptul că acele valori care sunt mai îndepărtate de tendința centrală a datelor sau au o variabilitate mai mare.

De asemenea, putem arunca o privire la distribuția fiecărei caracteristici vizual, prin trasarea histogramei fiecărei caracteristici în interiorul unei bucle for. Pe lângă faptul că ne uităm la distribuție, ar fi interesant să ne uităm la modul în care punctele fiecărei clase sunt separate în ceea ce privește fiecare caracteristică. Pentru a face acest lucru, putem trasa o diagramă de dispersie făcând o combinație de caracteristici între ele și să atribuim culori diferite fiecărui punct în funcție de clasa sa.

Să începem cu distribuția fiecărei caracteristici și să trasăm histograma fiecărei coloane de date, cu excepția class coloană. The class coloana nu va fi luată în considerare de poziția sa în matricea coloanelor de date bancare. Toate coloanele vor fi selectate cu excepția ultimei cu columns[:-1]:

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

După rularea codului de mai sus, putem vedea că ambele skewness și entropy distribuțiile datelor sunt denaturate negativ și curtosis este denaturată pozitiv. Toate distribuțiile sunt simetrice și variance este singura distribuție care este aproape de normal.

Acum putem trece la a doua parte și putem reprezenta graficul de dispersie al fiecărei variabile. Pentru a face acest lucru, putem selecta și toate coloanele, cu excepția clasei, cu columns[:-1], folosește Seaborn's scatterplot() și două bucle pentru a obține variațiile de împerechere pentru fiecare dintre caracteristici. De asemenea, putem exclude împerecherea unei caracteristici cu ea însăși, testând dacă prima caracteristică este egală cu a doua cu 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();

Observați că toate graficele au atât puncte de date reale, cât și cele falsificate, care nu sunt separate clar unele de altele, aceasta înseamnă că există un fel de suprapunere a claselor. Deoarece un model SVM folosește o linie pentru a separa clasele, ar putea oricare dintre acele grupuri din grafice să fie separate folosind o singură linie? Pare puțin probabil. Așa arată majoritatea datelor reale. Cel mai aproape ne putem apropia de o separare este în combinația de skewness și variance, Sau entropy și variance parcele. Acest lucru se datorează probabil variance date având o formă de distribuție mai apropiată de normal.

Dar privirea la toate aceste grafice în secvență poate fi puțin dificilă. Avem alternativa de a privi împreună toate graficele de distribuție și diagrame de dispersie folosind Seaborn pairplot().

Ambele bucle for anterioare pe care le-am făcut pot fi înlocuite doar cu această linie:

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

Privind complotul perechi, se pare că, de fapt, curtosis și variance ar fi cea mai ușoară combinație de caracteristici, astfel încât diferitele clase ar putea fi separate printr-o linie sau separabil liniar.

Dacă majoritatea datelor sunt departe de a fi separabile liniar, putem încerca să le preprocesăm, reducându-le dimensiunile și, de asemenea, să le normalizăm valorile pentru a încerca să facem distribuția mai aproape de o normală.

În acest caz, să folosim datele așa cum sunt, fără preprocesare ulterioară, iar mai târziu, putem să ne întoarcem cu un pas înapoi, să adăugăm la preprocesarea datelor și să comparăm rezultatele.

Indicații: Când lucrați cu date, informațiile se pierd de obicei la transformarea lor, deoarece facem aproximări, în loc să colectăm mai multe date. Lucrul cu datele inițiale mai întâi așa cum este, dacă este posibil, oferă o linie de bază înainte de a încerca alte tehnici de preprocesare. Când urmează această cale, rezultatul inițial folosind date brute poate fi comparat cu un alt rezultat care utilizează tehnici de preprocesare a datelor.

Notă: De obicei, în Statistică, atunci când se construiesc modele, este obișnuit să se urmeze o procedură în funcție de tipul de date (discrete, continue, categoriale, numerice), distribuția acesteia și ipotezele modelului. În timp ce în Informatică (CS), există mai mult spațiu pentru încercare, eroare și noi iterații. În CS este obișnuit să existe o linie de bază cu care să se compare. În Scikit-learn, există o implementare de modele inactiv (sau estimatori inactivi), unii nu sunt mai buni decât să arunce o monedă și doar să răspundă da (sau 1) 50% din timp. Este interesant să se utilizeze modele inactiv ca bază pentru modelul real atunci când se compară rezultatele. Este de așteptat ca rezultatele reale ale modelului să fie mai bune decât o presupunere aleatorie, altfel, utilizarea unui model de învățare automată nu ar fi necesară.

Implementarea SVM cu Scikit-Learn

Înainte de a intra mai mult în teoria modului în care funcționează SVM, putem construi primul nostru model de bază cu date și Scikit-Learn. Suport Vector Clasifier or SVC clasă.

Modelul nostru va primi coeficienții wavelet și va încerca să-i clasifice în funcție de clasă. Primul pas în acest proces este separarea coeficienților sau caracteristici din clasa sau ţintă. După acest pas, al doilea pas este împărțirea în continuare a datelor într-un set care va fi folosit pentru învățarea modelului sau set de trenuri si alta care va fi folosita la evaluarea modelului sau set de testare.

Notă: Nomenclatura testului și evaluării poate fi puțin confuză, deoarece vă puteți împărți datele între tren, evaluare și seturi de testare. În acest fel, în loc să ai două seturi, ai avea un set intermediar doar pentru a-l folosi și a vedea dacă performanța modelului tău se îmbunătățește. Aceasta înseamnă că modelul va fi antrenat cu setul de tren, îmbunătățit cu setul de evaluare și obținerea unei metrici finale cu setul de testare.

Unii oameni spun că evaluarea este acel set intermediar, alții vor spune că setul de testare este setul intermediar și că setul de evaluare este setul final. Acesta este un alt mod de a încerca să garanteze că modelul nu vede același exemplu în niciun fel sau că un fel de scurgeri de date nu se întâmplă și că există o generalizare a modelului prin îmbunătățirea ultimelor valori setate. Dacă doriți să urmați această abordare, puteți împărți datele încă o dată, așa cum este descris mai jos Train_test_split() de la Scikit-Learn – Seturi de instruire, testare și validare ghid.

Împărțirea datelor în seturi de tren/test

În sesiunea anterioară, am înțeles și am explorat datele. Acum, ne putem împărți datele în două matrice - unul pentru cele patru caracteristici și altul pentru a cincea, sau caracteristica țintă. Deoarece vrem să prezicăm clasa în funcție de coeficienții wavelets, nostru y va fi class coloana si a noastra X va variance, skewness, curtosis, și entropy coloane.

Pentru a separa ținta și caracteristicile, putem atribui doar class coloana către y, pisându-l ulterior din cadrul de date pentru a atribui coloanele rămase X cu .drop() metodă:

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

Odată ce datele sunt împărțite în atribute și etichete, le putem împărți în continuare în seturi de tren și de testare. Acest lucru ar putea fi făcut manual, dar model_selection biblioteca Scikit-Learn conține train_test_split() metodă care ne permite să împărțim aleatoriu datele în seturi de tren și de testare.

Pentru ao folosi, putem importa biblioteca, apelăm la train_test_split() metoda, trece X și y date și definiți a test_size a trece drept argument. În acest caz, îl vom defini ca 0.20– asta înseamnă că 20% din date vor fi folosite pentru testare, iar celelalte 80% pentru antrenament.

Această metodă preia aleatoriu mostre respectând procentul pe care l-am definit, dar respectă perechile Xy, ca nu cumva eșantionarea ar amesteca total relația.

Deoarece procesul de eșantionare este în mod inerent aleatoriu, vom avea întotdeauna rezultate diferite atunci când rulăm metoda. Pentru a putea avea aceleași rezultate, sau rezultate reproductibile, putem defini o constantă numită SEED cu valoarea 42.

Puteți executa următorul script pentru a face acest lucru:

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)

Observați că train_test_split() metoda returnează deja X_train, X_test, y_train, y_test setează în această ordine. Putem tipări numărul de mostre separate pentru tren și testare obținând primul (0) element al shape tuplu returnat de proprietate:

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.')

Aceasta arată că există 1097 de eșantioane pentru antrenament și 275 pentru testare.

Instruirea modelului

Am împărțit datele în seturi de tren și de testare. Acum este timpul să creați și să antrenați un model SVM pe datele trenului. Pentru a face asta, putem importa Scikit-Learn's svm bibliotecă împreună cu Suport Vector Clasifier clasa, sau SVC clasă.

După importarea clasei, putem crea o instanță a acesteia - deoarece creăm un model SVM simplu, încercăm să ne separăm datele liniar, astfel încât să putem trasa o linie pentru a ne împărți datele - care este același lucru cu utilizarea unui funcție liniară – prin definire kernel='linear' ca argument pentru clasificator:

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

În acest fel, clasificatorul va încerca să găsească o funcție liniară care separă datele noastre. După crearea modelului, să-l antrenăm sau potrivi ea, cu datele trenului, folosind fit() metoda si oferind X_train caracteristici și y_train ţinte ca argumente.

Putem executa următorul cod pentru a antrena modelul:

svc.fit(X_train, y_train)

Exact așa, modelul este antrenat. Până acum, am înțeles datele, le-am împărțit, am creat un model SVM simplu și am adaptat modelul la datele trenului.

Următorul pas este să înțelegem cât de bine a reușit acea potrivire să descrie datele noastre. Cu alte cuvinte, pentru a răspunde dacă un SVM liniar a fost o alegere adecvată.

Realizarea previziunilor

O modalitate de a răspunde dacă modelul a reușit să descrie datele este de a calcula și de a privi o clasificare metrics.

Avand in vedere ca invatarea este supravegheata, putem face predictii cu X_test și comparați acele rezultate ale predicției – pe care le-am putea numi y_pred – cu actualul y_test, Sau adevărul de bază.

Pentru a prezice unele dintre date, cele ale modelului predict() se poate folosi metoda. Această metodă primește caracteristicile de testare, X_test, ca argument și returnează o predicție, fie 0, fie 1, pentru fiecare dintre X_testrândurile lui.

După prezicerea X_test date, rezultatele sunt stocate într-un y_pred variabil. Deci, fiecare dintre clasele prezise cu modelul SVM liniar simplu se află acum în y_pred variabilă.

Acesta este codul de predicție:

y_pred = svc.predict(X_test)

Având în vedere că avem predicțiile, acum le putem compara cu rezultatele reale.

Evaluarea modelului

Există mai multe moduri de a compara predicțiile cu rezultatele reale și măsoară diferite aspecte ale unei clasificări. Unele valori de clasificare cele mai utilizate sunt:

  1. Matricea confuziei: atunci când trebuie să știm pentru câte mostre am primit corect sau greșit fiecare clasă. Se numesc valorile care au fost corecte și prezise corect adevărate pozitive, cele care au fost prezise ca pozitive, dar nu au fost pozitive sunt numite fals pozitive. Aceeași nomenclatură a negative adevărate și false negative este folosit pentru valori negative;

  2. Precizie: când scopul nostru este să înțelegem ce valori corecte de predicție au fost considerate corecte de către clasificatorul nostru. Precizia va împărți acele valori pozitive adevărate la eșantioanele care au fost prezise ca fiind pozitive;

$$
precizie = frac{text{adevărate pozitive}}{text{adevărate pozitive} + text{false pozitive}}
$$

  1. Rechemare: calculat în mod obișnuit împreună cu precizia pentru a înțelege câte dintre elementele pozitive adevărate au fost identificate de clasificatorul nostru. Rechemarea se calculează împărțind adevăratele pozitive la orice ar fi trebuit prezis ca fiind pozitiv.

$$
recall = frac{text{adevărate pozitive}}{text{adevărate pozitive} + text{false negative}}
$$

  1. Scor F1: este echilibrat sau medie armonică de precizie și reamintire. Cea mai mică valoare este 0, iar cea mai mare este 1. Când f1-score este egal cu 1, înseamnă că toate clasele au fost corect prezise – acesta este un scor foarte greu de obținut cu date reale (excepții există aproape întotdeauna).

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

Am fost deja familiarizați cu matricea de confuzie, precizia, reamintirea și măsurile de scor F1. Pentru a le calcula, putem importa Scikit-Learn's metrics bibliotecă. Această bibliotecă conține classification_report și confusion_matrix metode, metoda raportului de clasificare returnează precizia, reamintirea și scorul f1. Ambii classification_report și confusion_matrix poate fi folosit cu ușurință pentru a afla valorile pentru toate aceste valori importante.

Pentru calcularea metricilor, importăm metodele, le apelăm și trecem ca argumente clasificările prezise, y_test, și etichetele de clasificare sau y_true.

Pentru o mai bună vizualizare a matricei de confuzie, o putem reprezenta într-un Seaborn's heatmap împreună cu adnotări de cantitate, iar pentru raportul de clasificare, cel mai bine este să-i tipăriți rezultatul, astfel încât rezultatele să fie formatate. Acesta este următorul cod:

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))

Aceasta afișează:

 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

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

În raportul de clasificare, știm că există o precizie de 0.99, rechemare de 0.99 și un scor f1 de 0.99 pentru bancnotele falsificate, sau clasa 0. Aceste măsurători au fost obținute folosind 148 de eșantioane, așa cum se arată în coloana suport. Între timp, pentru clasa 1, sau notele reale, rezultatul a fost cu o unitate mai jos, o precizie de 0.98, 0.98 de reamintire și același scor f1. De această dată, au fost utilizate 127 de măsurători de imagine pentru obținerea acestor rezultate.

Dacă ne uităm la matricea de confuzie, putem observa și că din 148 de eșantioane clasa 0, 146 au fost clasificate corect și au fost 2 fals pozitive, în timp ce pentru 127 eșantioane clasa 1 au fost 2 fals negative și 125 adevărate pozitive.

Putem citi raportul de clasificare și matricea de confuzie, dar ce înseamnă ele?

Interpretarea rezultatelor

Pentru a afla semnificația, să ne uităm la toate valorile combinate.

Aproape toate eșantioanele pentru clasa 1 au fost clasificate corect, au existat 2 greșeli pentru modelul nostru la identificarea bancnotelor reale. Aceasta este aceeași cu 0.98, sau 98%, reamintire. Ceva asemanator se poate spune despre clasa 0, doar 2 probe au fost clasificate incorect, in timp ce 148 sunt adevarate negative, totalizand o precizie de 99%.

Pe lângă aceste rezultate, toate celelalte marchează 0.99, care este aproape 1, o valoare foarte mare. De cele mai multe ori, atunci când o măsurătoare atât de ridicată se întâmplă cu date din viața reală, aceasta ar putea indica un model care este supraajustat la date sau suprainstalat.

Când există o supraadaptare, modelul poate funcționa bine atunci când prezice datele deja cunoscute, dar își pierde capacitatea de a generaliza la date noi, ceea ce este important în scenariile din lumea reală.

Un test rapid pentru a afla dacă are loc o supraadaptare este și cu datele trenului. Dacă modelul a memorat oarecum datele trenului, valorile vor fi foarte aproape de 1 sau 100%. Amintiți-vă că datele trenului sunt mai mari decât datele testului – din acest motiv – încercați să le priviți proporțional, mai multe eșantioane, mai multe șanse de a face greșeli, cu excepția cazului în care a existat o supraadaptare.

Pentru a prezice cu datele trenului, putem repeta ceea ce am făcut pentru datele de testare, dar acum cu 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))

Acest rezultat:

 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

Implementing SVM and Kernel SVM with Python's Scikit-Learn PlatoBlockchain Data Intelligence. Vertical Search. Ai.

Este ușor de observat că pare să existe o supraadaptare, odată ce valorile trenului sunt de 99% când aveți de 4 ori mai multe date. Ce se poate face în acest scenariu?

Pentru a anula supraajustarea, putem adăuga mai multe observații ale trenului, putem folosi o metodă de antrenament cu diferite părți ale setului de date, cum ar fi validare încrucișatăși, de asemenea, modificați parametrii impliciti care există deja înainte de antrenament, la crearea modelului nostru sau hiperparametri. De cele mai multe ori, Scikit-learn setează unii parametri ca implicit, iar acest lucru se poate întâmpla în tăcere dacă nu este mult timp dedicat citirii documentației.

Puteți verifica a doua parte a acestui ghid (in curand!) pentru a vedea cum să implementați validarea încrucișată și să efectuați o reglare a hiperparametrului.

Concluzie

În acest articol am studiat SVM-ul nucleu liniar simplu. Am obținut intuiția din spatele algoritmului SVM, am folosit un set de date real, am explorat datele și am văzut cum aceste date pot fi utilizate împreună cu SVM prin implementarea lor cu biblioteca Scikit-Learn de la Python.

Pentru a continua exersarea, puteți încerca alte seturi de date din lumea reală disponibile în locuri precum Kaggle, UCI, Seturi de date publice Big Query, universități și site-uri web guvernamentale.

De asemenea, aș sugera să explorați matematica reală din spatele modelului SVM. Deși nu veți avea neapărat nevoie de el pentru a utiliza algoritmul SVM, este totuși foarte util să știți ce se întâmplă de fapt în spatele scenei în timp ce algoritmul dvs. găsește limite de decizie.

Timestamp-ul:

Mai mult de la Stackabuse