Implementering av SVM og Kernel SVM med Pythons Scikit-Learn

Implementering av SVM og Kernel SVM med Pythons Scikit-Learn

Introduksjon

Denne veiledningen er den første delen av tre guider om Support Vector Machines (SVM). I denne serien skal vi jobbe med en brukssak for falske sedler, lære om de enkle SVM, deretter om SVM-hyperparametre og til slutt lære et konsept kalt kjernetriks og utforske andre typer SVM-er.

Hvis du ønsker å lese alle veiledningene eller se hvilke som interesserer deg mest, nedenfor er tabellen over emner som dekkes i hver veiledning:

1. Implementering av SVM og Kernel SVM med Pythons Scikit-Learn

  • Bruksfall: glem sedler
  • Bakgrunn for SVM-er
  • Enkel (lineær) SVM-modell
    • Om datasettet
    • Importerer datasettet
    • Utforsker datasettet
  • Implementering av SVM med Scikit-Learn
    • Dele inn data i tog-/testsett
    • Trening av modellen
    • Gjøre spådommer
    • Evaluering av modellen
    • Tolke resultater

2. Forstå SVM-hyperparametere (kommer snart!)

  • C-hyperparameteren
  • Gamma-hyperparameteren

3. Implementering av andre SVM-smaker med Pythons Scikit-Learn (kommer snart!)

  • Den generelle ideen til SVM-er (en oppsummering)
  • Kjerne (triks) SVM
  • Implementering av ikke-lineær kjerne SVM med Scikit-Learn
  • Importerer biblioteker
    • Importere datasettet
    • Deler inn data i funksjoner (X) og mål (y)
    • Dele inn data i tog-/testsett
    • Trening av algoritmen
  • Polynom kjerne
    • Gjøre spådommer
    • Evaluering av algoritmen
  • Gaussisk kjerne
    • Prediksjon og evaluering
  • Sigmoid kjerne
    • Prediksjon og evaluering
  • Sammenligning av ikke-lineære kjerneytelser

Bruksområde: Forfalskede sedler

Noen ganger finner folk en måte å forfalske sedler på. Hvis det er en person som ser på disse notatene og bekrefter deres gyldighet, kan det være vanskelig å bli lurt av dem.

Men hva skjer når det ikke er en person til å se på hver lapp? Er det en måte å automatisk vite om sedler er forfalsket eller ekte?

Det er mange måter å svare på disse spørsmålene. Ett svar er å fotografere hver mottatt seddel, sammenligne bildet med en forfalsket seddel, og deretter klassifisere den som ekte eller forfalsket. Når det kan være kjedelig eller kritisk å vente på valideringen av notatet, vil det også være interessant å gjøre den sammenligningen raskt.

Siden bilder brukes, kan de komprimeres, reduseres til gråtoner og få målingene ekstrahert eller kvantisert. På denne måten ville sammenligningen vært mellom bildemålinger, i stedet for hvert bildes piksel.

Så langt har vi funnet en måte å behandle og sammenligne sedler på, men hvordan skal de klassifiseres som ekte eller falske? Vi kan bruke maskinlæring for å gjøre den klassifiseringen. Det er en klassifiseringsalgoritme som kalles Støtt vektormaskin, hovedsakelig kjent ved sin forkortede form: svm.

Bakgrunn for SVM-er

SVM-er ble først introdusert i 1968, av Vladmir Vapnik og Alexey Chervonenkis. På den tiden var algoritmen deres begrenset til klassifiseringen av data som kunne separeres med bare én rett linje, eller data som var lineært separerbare. Vi kan se hvordan den separasjonen vil se ut:

Implementering av SVM og Kernel SVM med Pythons Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

I bildet ovenfor har vi en linje i midten, hvor noen punkter er til venstre, og andre er til høyre for den linjen. Legg merke til at begge gruppene med punkter er perfekt atskilt, det er ingen punkter i mellom eller i nærheten av linjen. Det ser ut til å være en margin mellom lignende punkter og linjen som deler dem, den margen kalles separasjonsmargin. Funksjonen til separasjonsmarginen er å gjøre mellomrommet mellom de like punktene og linjen som deler dem større. SVM gjør det ved å bruke noen punkter og beregner sine vinkelrette vektorer for å støtte avgjørelsen for linjens margin. Det er de støttevektorer som er en del av navnet på algoritmen. Vi vil forstå mer om dem senere. Og den rette linjen som vi ser i midten er funnet ved metoder som maksimere det mellomrommet mellom linjen og punktene, eller som maksimerer separasjonsmarginen. Disse metodene stammer fra feltet av Optimaliseringsteori.

I eksemplet vi nettopp har sett, kan begge gruppene med punkter lett skilles, siden hvert enkelt punkt er nær hverandre til sine like punkter, og de to gruppene er langt fra hverandre.

Men hva skjer hvis det ikke er en måte å skille dataene ved hjelp av én rett linje? Hvis det er rotete malplasserte punkter, eller om det trengs en kurve?

For å løse det problemet ble SVM senere foredlet på 1990-tallet for også å kunne klassifisere data som hadde punkter som var langt fra den sentrale tendensen, for eksempel uteliggere, eller mer komplekse problemer som hadde mer enn to dimensjoner og ikke var lineært separerbare .

Det som er merkelig er at bare de siste årene har SVM-er blitt allment adoptert, hovedsakelig på grunn av deres evne til å oppnå noen ganger mer enn 90 % av riktige svar eller nøyaktighet, for vanskelige problemer.

SVM-er implementeres på en unik måte sammenlignet med andre maskinlæringsalgoritmer, når de først er basert på statistiske forklaringer på hva læring er, eller på Statistisk læringsteori.

I denne artikkelen skal vi se hva Support Vector Machines-algoritmer er, den korte teorien bak en støttevektormaskin og implementeringen av dem i Pythons Scikit-Learn-bibliotek. Vi vil da bevege oss mot et annet SVM-konsept, kjent som Kjerne SVMeller Kjernetriks, og vil også implementere det ved hjelp av Scikit-Learn.

Enkel (lineær) SVM-modell

Om datasettet

Etter eksempelet gitt i innledningen, vil vi bruke et datasett som har mål på ekte og forfalskede sedlerbilder.

Når vi ser på to notater, skanner øynene våre dem vanligvis fra venstre til høyre og sjekker hvor det kan være likheter eller ulikheter. Vi ser etter en svart prikk som kommer foran en grønn prikk, eller et skinnende merke som er over en illustrasjon. Det betyr at det er en rekkefølge vi ser på notatene. Hvis vi visste at det var grønne og svarte prikker, men ikke om den grønne prikken kom før den svarte, eller hvis den svarte kom før den grønne, ville det være vanskeligere å skille mellom toner.

Det er en lignende metode som den vi nettopp har beskrevet som kan brukes på seddelbildene. Generelt sett består denne metoden i å oversette bildets piksler til et signal, og deretter ta i betraktning rekkefølgen som hvert forskjellig signal skjer i bildet ved å transformere det til små bølger, eller bølger. Etter å ha oppnådd wavelets, er det en måte å vite rekkefølgen som et signal skjer før et annet, eller tid, men ikke akkurat hvilket signal. For å vite det, må bildets frekvenser innhentes. De oppnås ved en metode som gjør dekomponeringen av hvert signal, kalt Fouriermetoden.

Når tidsdimensjonen er oppnådd gjennom wavelets, og frekvensdimensjonen gjennom Fourier-metoden, lages en overlagring av tid og frekvens for å se når begge har en match, dette er konvolusjon analyse. Konvolusjonen får en passform som matcher bølgene med bildets frekvenser og finner ut hvilke frekvenser som er mer fremtredende.

Denne metoden som går ut på å finne bølgene, deres frekvenser og deretter tilpasse dem begge, kalles Wavelet transformasjon. Wavelet-transformasjonen har koeffisienter, og disse koeffisientene ble brukt for å oppnå målingene vi har i datasettet.

Importerer datasettet

Seddeldatasettet som vi skal bruke i denne delen er det samme som ble brukt i klassifiseringsdelen av veiledning for beslutningstre.

OBS: Du kan laste ned datasettet her..

La oss importere dataene til en panda dataframe struktur, og ta en titt på de fem første radene med head() metoden.

Legg merke til at dataene er lagret i en txt (tekst) filformat, atskilt med komma, og det er uten overskrift. Vi kan rekonstruere den som en tabell ved å lese den som en csv, som spesifiserer separator som komma, og legge til kolonnenavnene med names argument.

La oss følge disse tre trinnene samtidig, og så se på de første fem radene med dataene:

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

Dette resulterer i:

	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

OBS: Du kan også lagre dataene lokalt og erstatte dem data_link forum data_path, og send inn banen til din lokale fil.

Vi kan se at det er fem kolonner i datasettet vårt, nemlig variance, skewness, curtosis, entropyog class. I de fem radene er de fire første kolonnene fylt med tall som 3.62160, 8.6661, -2.8073 eller kontinuerlig verdier, og den siste class kolonnen har de fem første radene fylt med 0-er, eller en diskret verdi.

Siden målet vårt er å forutsi om en bankvalutaseddel er autentisk eller ikke, kan vi gjøre det basert på de fire attributtene til seddelen:

  • variance av Wavelet Transformert bilde. Vanligvis er variansen en kontinuerlig verdi som måler hvor mye datapunktene er nær eller langt fra dataens gjennomsnittsverdi. Hvis punktene er nærmere dataens gjennomsnittsverdi, er fordelingen nærmere en normalfordeling, noe som vanligvis betyr at verdiene er bedre fordelt og noe lettere å forutsi. I den nåværende bildekonteksten er dette variansen til koeffisientene som resulterer fra wavelet-transformasjonen. Jo mindre varians, desto nærmere var koeffisientene å oversette det faktiske bildet.

  • skewness av Wavelet Transformert bilde. Skjevheten er en kontinuerlig verdi som indikerer asymmetrien til en fordeling. Hvis det er flere verdier til venstre for gjennomsnittet, er fordelingen negativt skjev, hvis det er flere verdier til høyre for gjennomsnittet, er fordelingen positivt skjevt, og hvis gjennomsnitt, modus og median er det samme, er fordelingen det symmetrisk. Jo mer symmetrisk en fordeling er, desto nærmere er den en normalfordeling, og verdiene har også bedre fordeling. I den foreliggende sammenheng er dette skjevheten til koeffisientene som resulterer fra wavelet-transformasjonen. Jo mer symmetrisk, jo nærmere koeffisientene er vivariance, skewness, curtosis, entropyre til å oversette det faktiske bildet.

Implementering av SVM og Kernel SVM med Pythons Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

  • curtosis (eller kurtosis) av Wavelet Transformert bilde. Kurtosen er en kontinuerlig verdi som i likhet med skjevhet også beskriver formen på en fordeling. Avhengig av kurtosis-koeffisienten (k), kan en fordeling - sammenlignet med normalfordelingen være mer eller mindre flat - eller ha mer eller mindre data i ekstremitetene eller halene. Når fordelingen er mer spredt og flatere, kalles det platykurtisk; når den er mindre spredt og mer konsentrert i midten, mesokurtisk; og når fordelingen er nesten helt konsentrert i midten, kalles den leptokurtisk. Dette er det samme tilfellet som tidligere tilfeller av varians og skjevhet, jo mer mesokurtisk fordelingen er, desto nærmere var koeffisientene å oversette det faktiske bildet.

Implementering av SVM og Kernel SVM med Pythons Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

  • entropy av bildet. Entropien er også en kontinuerlig verdi, den måler vanligvis tilfeldigheten eller uorden i et system. I sammenheng med et bilde, måler entropi forskjellen mellom en piksel og dens nabopiksler. For vår kontekst, jo mer entropi koeffisientene har, jo mer tap var det ved transformering av bildet – og jo mindre entropi, jo mindre informasjonstap.

Implementering av SVM og Kernel SVM med Pythons Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Den femte variabelen var class variabel, som sannsynligvis har 0 og 1 verdier, som sier om seddelen var ekte eller forfalsket.

Vi kan sjekke om den femte kolonnen inneholder nuller og enere med Pandas' unique() metode:

bankdata['class'].unique()

Metoden ovenfor returnerer:

array([0, 1]) 

Metoden ovenfor returnerer en matrise med 0 og 1 verdier. Dette betyr at de eneste verdiene i klasseradene våre er nuller og enere. Den er klar til å brukes som mål i vår veiledede læring.

  • class av bildet. Dette er en heltallsverdi, den er 0 når bildet er forfalsket, og 1 når bildet er ekte.

Siden vi har en spalte med merknader av ekte og glem bilder, betyr dette at vår type læring er overvåket.

Råd: for å vite mer om begrunnelsen bak Wavelet Transform på seddelbildene og bruken av SVM, les forfatternes publiserte papir.

Vi kan også se hvor mange poster, eller bilder vi har, ved å se på antall rader i dataene via shape eiendom:

bankdata.shape

Dette gir utganger:

(1372, 5)

Linjen ovenfor betyr at det er 1,372 rader med transformerte sedlerbilder og 5 kolonner. Dette er dataene vi skal analysere.

Vi har importert datasettet vårt og gjort noen få kontroller. Nå kan vi utforske dataene våre for å forstå dem bedre.

Utforsker datasettet

Vi har nettopp sett at det bare er nuller og enere i klassekolonnen, men vi kan også vite hvor stor andel de er – med andre ord – om det er flere nuller enn enere, flere enere enn nuller, eller om tallene på nuller er det samme som antall enere, noe som betyr at de er det balanserte.

For å vite andelen kan vi telle hver av null- og en-verdiene i dataene med value_counts() metode:

bankdata['class'].value_counts()

Dette gir utganger:

0 762
1 610
Name: class, dtype: int64

I resultatet ovenfor kan vi se at det er 762 nuller og 610 enere, eller 152 flere nuller enn enere. Dette betyr at vi har litt mer smidde de ekte bildene, og hvis avviket var større, for eksempel 5500 nuller og 610 enere, kan det påvirke resultatene våre negativt. Når vi først prøver å bruke disse eksemplene i modellen vår – jo flere eksempler det er, betyr vanligvis at jo mer informasjon modellen må velge mellom forfalskede eller ekte sedler – hvis det er få eksempler på ekte sedler, er modellen tilbøyelig til å bli feil når du prøver å gjenkjenne dem.

Vi vet allerede at det er 152 flere forfalskede sedler, men kan vi være sikre på at det er nok eksempler til at modellen kan lære? Å vite hvor mange eksempler som trengs for læring er et veldig vanskelig spørsmål å svare på, i stedet kan vi prøve å forstå, prosentvis, hvor stor forskjellen mellom klassene er.

Det første trinnet er å bruke pandaer value_counts() metoden igjen, men la oss nå se prosenten ved å inkludere argumentet normalize=True:

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

De normalize=True beregner prosentandelen av dataene for hver klasse. Så langt er prosentandelen av smidde (0) og reelle data (1):

0 0.555394
1 0.444606
Name: class, dtype: float64

Dette betyr at omtrent (~) 56 % av datasettet vårt er forfalsket og 44 % av det er ekte. Dette gir oss et forhold på 56%-44%, som er det samme som en forskjell på 12%. Dette anses statistisk som en liten forskjell, fordi den er litt over 10 %, så dataene anses som balanserte. Hvis det i stedet for en 56:44-andel var en 80:20- eller 70:30-andel, ville dataene våre bli ansett som ubalanserte, og vi ville trenge en ubalansebehandling, men dette er heldigvis ikke tilfelle.

Vi kan også se denne forskjellen visuelt, ved å ta en titt på klassens eller målets fordeling med et Panda-belagt histogram, ved å bruke:

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

Dette plotter et histogram ved å bruke datarammestrukturen direkte, i kombinasjon med matplotlib bibliotek som er bak kulissene.

Implementering av SVM og Kernel SVM med Pythons Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Ved å se på histogrammet kan vi være sikre på at målverdiene våre er enten 0 eller 1 og at dataene er balansert.

Dette var en analyse av kolonnen som vi prøvde å forutsi, men hva med å analysere de andre kolonnene med dataene våre?

Vi kan ta en titt på de statistiske målingene med describe() datarammemetode. Vi kan også bruke .T av transponere – for å invertere kolonner og rader, noe som gjør det mer direkte å sammenligne på tvers av verdier:

Sjekk ut vår praktiske, praktiske guide for å lære Git, med beste praksis, bransjeaksepterte standarder og inkludert jukseark. Slutt å google Git-kommandoer og faktisk lære den!

bankdata.describe().T

Dette resulterer i:

 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

Legg merke til at skjevhet og kurtosekolonner har middelverdier som er langt fra standardavviksverdiene, dette indikerer at de verdiene som er lenger unna dataens sentrale tendens, eller har større variabilitet.

Vi kan også ta en titt på hver funksjons distribusjon visuelt ved å plotte hver funksjons histogram inne i en for-løkke. I tillegg til å se på fordelingen, ville det være interessant å se på hvordan poengene til hver klasse er atskilt angående hver funksjon. For å gjøre det kan vi plotte et spredningsplott og lage en kombinasjon av funksjoner mellom dem, og tilordne forskjellige farger til hvert punkt med hensyn til klassen.

La oss starte med hver funksjons fordeling, og plotte histogrammet for hver datakolonne bortsett fra class kolonne. De class kolonnen vil ikke bli tatt i betraktning av sin plassering i bankdata-kolonnene. Alle kolonner vil bli valgt bortsett fra den siste med columns[:-1]:

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

Etter å ha kjørt koden ovenfor, kan vi se at begge deler skewness og entropy datafordelinger er negativt skjeve og curtosis er positivt skjev. Alle fordelinger er symmetriske, og variance er den eneste fordelingen som er nær normalen.

Vi kan nå gå videre til den andre delen, og plotte spredningsplottet til hver variabel. For å gjøre dette kan vi også velge alle kolonner bortsett fra klassen, med columns[:-1], bruk Seaborn's scatterplot() og to for løkker for å oppnå variasjonene i paring for hver av funksjonene. Vi kan også ekskludere sammenkoblingen av en funksjon med seg selv, ved å teste om den første funksjonen er lik den andre med en 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();

Legg merke til at alle grafer har både reelle og smidde datapunkter som ikke er tydelig atskilt fra hverandre, dette betyr at det er en slags superposisjon av klasser. Siden en SVM-modell bruker en linje for å skille mellom klasser, kan noen av disse gruppene i grafene skilles med bare én linje? Det virker usannsynlig. Slik ser de fleste virkelige data ut. Det nærmeste vi kan komme en separasjon er i kombinasjonen av skewness og varianceeller entropy og variance tomter. Dette er trolig pga variance data som har en distribusjonsform som er nærmere normalen.

Men å se på alle disse grafene i rekkefølge kan være litt vanskelig. Vi har alternativet å se på alle distribusjons- og spredningsplott-grafene sammen ved å bruke Seaborns pairplot().

Begge tidligere for løkker vi hadde gjort kan erstattes med bare denne linjen:

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

Når man ser på parplotten, ser det ut til at curtosis og variance ville være den enkleste kombinasjonen av funksjoner, slik at de forskjellige klassene kan skilles med en linje, eller lineært separerbare.

Hvis de fleste data er langt fra å være lineært separerbare, kan vi prøve å forhåndsbehandle dem, ved å redusere dimensjonene, og også normalisere verdiene for å prøve å gjøre fordelingen nærmere en normal.

For dette tilfellet, la oss bruke dataene som de er, uten ytterligere forhåndsbehandling, og senere kan vi gå tilbake ett trinn, legge til dataforbehandlingen og sammenligne resultatene.

Råd: Når du arbeider med data, går informasjon vanligvis tapt når du transformerer den, fordi vi gjør tilnærminger, i stedet for å samle inn mer data. Å jobbe med de første dataene først slik de er, gir om mulig en grunnlinje før du prøver andre forbehandlingsteknikker. Når du følger denne banen, kan det første resultatet ved bruk av rådata sammenlignes med et annet resultat som bruker forbehandlingsteknikker på dataene.

OBS: Vanligvis i statistikk, når man bygger modeller, er det vanlig å følge en prosedyre avhengig av typen data (diskret, kontinuerlig, kategorisk, numerisk), distribusjonen og modellens forutsetninger. Mens du er i informatikk (CS), er det mer plass til prøving, feiling og nye iterasjoner. I CS er det vanlig å ha en baseline å sammenligne mot. I Scikit-learn er det en implementering av dummy-modeller (eller dummy-estimatorer), noen er ikke bedre enn å kaste en mynt, og bare svare ja (eller 1) 50 % av tiden. Det er interessant å bruke dummy-modeller som en baseline for selve modellen når man sammenligner resultater. Det forventes at de faktiske modellresultatene er bedre enn en tilfeldig gjetning, ellers ville det ikke være nødvendig å bruke en maskinlæringsmodell.

Implementering av SVM med Scikit-Learn

Før vi går mer inn på teorien om hvordan SVM fungerer, kan vi bygge vår første grunnlinjemodell med dataene, og Scikit-Learns Støtte Vector Classifier or SVC klasse.

Vår modell vil motta wavelet-koeffisientene og prøve å klassifisere dem basert på klassen. Det første trinnet i denne prosessen er å skille koeffisientene eller egenskaper fra klassen eller mål. Etter det trinnet er det andre trinnet å videre dele dataene inn i et sett som skal brukes til modellens læring eller togsett og en annen som skal brukes til modellens evaluering eller testsett.

OBS: Nomenklaturen for test og evaluering kan være litt forvirrende, fordi du også kan dele dataene dine mellom tog, evaluering og testsett. På denne måten, i stedet for å ha to sett, ville du ha et mellomsett bare for å bruke og se om modellens ytelse forbedres. Dette betyr at modellen vil bli trent med togsettet, forbedret med evalueringssettet, og oppnå en endelig metrikk med testsettet.

Noen sier at evalueringen er det mellomliggende settet, andre vil si at testsettet er det mellomliggende settet, og at evalueringssettet er det endelige settet. Dette er en annen måte å prøve å garantere at modellen ikke ser det samme eksemplet på noen måte, eller at en slags datalekkasje ikke skjer, og at det er en modellgeneralisering ved forbedring av de siste angitte beregningene. Hvis du ønsker å følge den tilnærmingen, kan du dele dataene ytterligere en gang til som beskrevet i denne Scikit-Learns train_test_split() – Trenings-, test- og valideringssett guide.

Dele inn data i tog-/testsett

I forrige økt forsto og utforsket vi dataene. Nå kan vi dele dataene våre i to arrays – en for de fire funksjonene, og en annen for den femte, eller målfunksjonen. Siden vi ønsker å forutsi klassen avhengig av wavelets koeffisientene, vår y vil være class kolonne og vår X vil den variance, skewness, curtosisog entropy kolonner.

For å skille målet og funksjonene kan vi bare tilskrive class kolonne til y, senere slippe den fra datarammen for å tilskrive de resterende kolonnene X med .drop() metode:

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

Når dataene er delt inn i attributter og etiketter, kan vi videre dele dem inn i tog- og testsett. Dette kan gjøres for hånd, men det model_selection biblioteket til Scikit-Learn inneholder train_test_split() metode som lar oss dele data tilfeldig inn i tog- og testsett.

For å bruke det, kan vi importere biblioteket, ring train_test_split() metode, gi inn X og y data, og definer en test_size å passere som et argument. I dette tilfellet vil vi definere det som 0.20– dette betyr at 20 % av dataene vil bli brukt til testing, og de andre 80 % til trening.

Denne metoden tar tilfeldig prøver som respekterer prosentandelen vi har definert, men respekterer Xy-parene, for ikke å blande sammen forholdet totalt.

Siden prøvetakingsprosessen er iboende tilfeldig, vil vi alltid ha forskjellige resultater når vi kjører metoden. For å kunne ha de samme resultatene, eller reproduserbare resultater, kan vi definere en konstant kalt SEED med verdien 42.

Du kan kjøre følgende skript for å gjøre det:

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)

Legg merke til at train_test_split() metoden returnerer allerede X_train, X_test, y_train, y_test setter i denne rekkefølgen. Vi kan skrive ut antall prøver separert for tog og test ved å få det første (0) elementet i shape eiendom returnert tuppel:

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

Dette viser at det er 1097 prøver til trening og 275 til testing.

Trening av modellen

Vi har delt inn data i tog- og testsett. Nå er det på tide å lage og trene en SVM-modell på togdataene. For å gjøre det kan vi importere Scikit-Learn svm bibliotek sammen med Støtte Vector Classifier klasse, eller SVC klasse.

Etter å ha importert klassen, kan vi lage en forekomst av den – siden vi lager en enkel SVM-modell, prøver vi å skille dataene våre lineært, slik at vi kan tegne en linje for å dele dataene våre – som er det samme som å bruke en lineær funksjon – ved å definere kernel='linear' som argument for klassifikatoren:

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

På denne måten vil klassifikatoren prøve å finne en lineær funksjon som skiller dataene våre. Etter å ha laget modellen, la oss trene den, eller passer det, med togdataene, ved å bruke fit() metode og gi X_train Funksjoner og y_train mål som argumenter.

Vi kan utføre følgende kode for å trene modellen:

svc.fit(X_train, y_train)

Akkurat sånn er modellen trent. Så langt har vi forstått dataene, delt dem opp, laget en enkel SVM-modell og tilpasset modellen til togdataene.

Det neste trinnet er å forstå hvor godt den passet klarte å beskrive dataene våre. Med andre ord, for å svare på om en lineær SVM var et tilstrekkelig valg.

Gjøre spådommer

En måte å svare på om modellen klarte å beskrive dataene er å beregne og se på en eller annen klassifisering beregninger.

Tatt i betraktning at læringen er veiledet, kan vi gjøre spådommer med X_test og sammenligne disse prediksjonsresultatene – som vi kan kalle y_pred – med det faktiske y_testeller bakken sannhet.

For å forutsi noen av dataene, modellens predict() metoden kan benyttes. Denne metoden mottar testfunksjonene, X_test, som et argument og returnerer en prediksjon, enten 0 eller 1, for hver av X_testsine rader.

Etter å ha spådd X_test data, er resultatene lagret i en y_pred variabel. Så hver av klassene spådd med den enkle lineære SVM-modellen er nå i y_pred variabel.

Dette er prediksjonskoden:

y_pred = svc.predict(X_test)

Med tanke på at vi har spådommene, kan vi nå sammenligne dem med de faktiske resultatene.

Evaluering av modellen

Det er flere måter å sammenligne prediksjoner med faktiske resultater, og de måler ulike aspekter ved en klassifisering. Noen mest brukte klassifiseringsberegninger er:

  1. Forvirringsmatrise: når vi trenger å vite hvor mange prøver vi fikk rett eller galt for hver klasse. Verdiene som var korrekte og korrekt forutsagt kalles ekte positive, de som ble spådd som positive, men som ikke var positive, kalles falske positive. Den samme nomenklaturen til ekte negativer og falske negativer brukes for negative verdier;

  2. Precision: når målet vårt er å forstå hvilke korrekte prediksjonsverdier som ble ansett som riktige av klassifisereren vår. Presisjon vil dele de sanne positive verdiene med prøvene som ble spådd som positive;

$$
presisjon = frac{tekst{true positives}}{text{true positives} + text{false positives}}
$$

  1. Husker: vanligvis beregnet sammen med presisjon for å forstå hvor mange av de sanne positive som ble identifisert av klassifisereren vår. Tilbakekallingen beregnes ved å dele de sanne positive med alt som burde vært spådd som positivt.

$$
recall = frac{tekst{true positives}}{text{true positives} + text{false negatives}}
$$

  1. F1-poengsum: er den balanserte eller harmonisk middel av presisjon og tilbakekalling. Den laveste verdien er 0 og den høyeste er 1. Når f1-score er lik 1, betyr det at alle klasser ble korrekt spådd – dette er en svært vanskelig poengsum å oppnå med ekte data (unntak finnes nesten alltid).

$$
tekst{f1-score} = 2* frac{tekst{presisjon} * tekst{recall}}{tekst{precision} + tekst{recall}}
$$

Vi har allerede blitt kjent med forvirringsmatrise, presisjon, tilbakekalling og F1-poengmål. For å beregne dem kan vi importere Scikit-Learn metrics bibliotek. Dette biblioteket inneholder classification_report og confusion_matrix metoder, returnerer klassifiseringsrapportmetoden presisjon, tilbakekalling og f1-poengsum. Både classification_report og confusion_matrix kan lett brukes til å finne ut verdiene for alle disse viktige beregningene.

For å beregne beregningene importerer vi metodene, kaller dem og sender de forutsagte klassifiseringene som argumenter, y_test, og klassifiseringsetikettene, eller y_true.

For en bedre visualisering av forvirringsmatrisen kan vi plotte den i en Seaborn's heatmap sammen med mengdeanmerkninger, og for klassifiseringsrapporten er det best å skrive ut resultatet, slik at resultatene formateres. Dette er følgende kode:

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

Dette viser:

 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

Implementering av SVM og Kernel SVM med Pythons Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

I klassifiseringsrapporten vet vi at det er en presisjon på 0.99, tilbakekalling på 0.99 og en f1-score på 0.99 for de forfalskede sedlene, eller klasse 0. Disse målingene ble oppnådd ved bruk av 148 prøver som vist i støttekolonnen. I mellomtiden, for klasse 1, eller ekte notater, var resultatet én enhet under, 0.98 presisjon, 0.98 tilbakekalling og samme f1-poengsum. Denne gangen ble 127 bildemålinger brukt for å oppnå disse resultatene.

Hvis vi ser på forvirringsmatrisen, kan vi også se at fra 148 klasse 0 prøver var 146 korrekt klassifisert, og det var 2 falske positive, mens for 127 klasse 1 prøver var det 2 falske negative og 125 sanne positive.

Vi kan lese klassifiseringsrapporten og forvirringsmatrisen, men hva betyr de?

Tolke resultater

For å finne ut betydningen, la oss se på alle beregningene kombinert.

Nesten alle prøvene for klasse 1 var riktig klassifisert, det var 2 feil for vår modell ved identifisering av faktiske sedler. Dette er det samme som 0.98, eller 98 %, tilbakekalling. Noe lignende kan sies om klasse 0, bare 2 prøver ble klassifisert feil, mens 148 er sanne negative, totalt en presisjon på 99 %.

I tillegg til disse resultatene merker alle andre 0.99, som er nesten 1, en veldig høy beregning. Mesteparten av tiden, når en så høy beregning skjer med virkelige data, kan dette indikere en modell som er overjustert til dataene, eller overmontert.

Når det er en overfitting, kan modellen fungere bra når den forutsier data som allerede er kjent, men den mister evnen til å generalisere til nye data, noe som er viktig i virkelige scenarier.

En rask test for å finne ut om det skjer en overfitting er også med togdata. Hvis modellen har husket togdataene noe, vil metrikken være veldig nær 1 eller 100 %. Husk at togdataene er større enn testdataene – av denne grunn – prøv å se på det proporsjonalt, flere prøver, flere sjanser for å gjøre feil, med mindre det har vært overfit.

For å forutsi med togdata kan vi gjenta det vi har gjort for testdata, men nå med 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))

Dette gir utganger:

 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

Implementering av SVM og Kernel SVM med Pythons Scikit-Learn PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Det er lett å se at det ser ut til å være overfitting, når togberegningene er 99 % når de har 4 ganger mer data. Hva kan gjøres i dette scenariet?

For å reversere overfitten kan vi legge til flere togobservasjoner, bruke en treningsmetode med ulike deler av datasettet, som f.eks. kryssvalidering, og endre også standardparameterne som allerede eksisterer før trening, når du lager vår modell, eller hyperparametere. Mesteparten av tiden setter Scikit-learn noen parametere som standard, og dette kan skje stille hvis det ikke er mye tid dedikert til å lese dokumentasjonen.

Du kan sjekke den andre delen av denne veiledningen (kommer snart!) for å se hvordan du implementerer kryssvalidering og utfører en hyperparameterinnstilling.

konklusjonen

I denne artikkelen studerte vi den enkle lineære kjernen SVM. Vi fikk intuisjonen bak SVM-algoritmen, brukte et ekte datasett, utforsket dataene og så hvordan disse dataene kan brukes sammen med SVM ved å implementere dem med Pythons Scikit-Learn-bibliotek.

For å fortsette å øve kan du prøve andre datasett fra den virkelige verden som er tilgjengelig på steder som kaggle, UCI, Big Query offentlige datasett, universiteter og offentlige nettsteder.

Jeg vil også foreslå at du utforsker den faktiske matematikken bak SVM-modellen. Selv om du ikke nødvendigvis trenger det for å bruke SVM-algoritmen, er det likevel veldig nyttig å vite hva som faktisk foregår bak kulissene mens algoritmen din finner beslutningsgrenser.

Tidstempel:

Mer fra Stackabuse