SVM en Kernel SVM implementeren met Scikit-Learn van Python

SVM en Kernel SVM implementeren met Scikit-Learn van Python

Introductie

Deze handleiding is het eerste deel van drie handleidingen over Support Vector Machines (SVM's). In deze serie werken we aan een use-case van vervalste bankbiljetten, leren we over de simpele SVM, vervolgens over SVM-hyperparameters en, tot slot, leren we een concept genaamd de kernel truc en verken andere soorten SVM's.

Als u alle gidsen wilt lezen of wilt zien welke u het meest interesseren, vindt u hieronder de tabel met onderwerpen die in elke gids worden behandeld:

1. SVM en Kernel SVM implementeren met Scikit-Learn van Python

  • Use case: vergeet bankbiljetten
  • Achtergrond van SVM's
  • Eenvoudig (lineair) SVM-model
    • Over de gegevensset
    • De gegevensset importeren
    • De dataset verkennen
  • SVM implementeren met Scikit-Learn
    • Gegevens verdelen in trein-/testsets
    • Het model trainen
    • Voorspellingen doen
    • Het model evalueren
    • Resultaten interpreteren

2. SVM Hyperparameters begrijpen (binnenkort beschikbaar!)

  • De C-hyperparameter
  • De Gamma-hyperparameter

3. Andere SVM-smaken implementeren met Scikit-Learn van Python (binnenkort beschikbaar!)

  • Het algemene idee van SVM's (een samenvatting)
  • Kernel (truc) SVM
  • Implementatie van niet-lineaire kernel SVM met Scikit-Learn
  • Bibliotheken importeren
    • De dataset importeren
    • Gegevens verdelen in kenmerken (X) en doel (y)
    • Gegevens verdelen in trein-/testsets
    • Het algoritme trainen
  • Polynoom kernel
    • Voorspellingen doen
    • Het algoritme evalueren
  • Gauss-kernel
    • Voorspelling en evaluatie
  • Sigmoรฏde kernel
    • Voorspelling en evaluatie
  • Vergelijking van niet-lineaire kernelprestaties

Use Case: vervalste bankbiljetten

Soms vinden mensen een manier om bankbiljetten te vervalsen. Als er iemand is die naar die aantekeningen kijkt en hun geldigheid verifieert, kan het moeilijk zijn om erdoor misleid te worden.

Maar wat gebeurt er als er niemand is om naar elke noot te kijken? Is er een manier om automatisch te weten of bankbiljetten vals of echt zijn?

Er zijn veel manieren om die vragen te beantwoorden. Een antwoord is om elk ontvangen biljet te fotograferen, de afbeelding ervan te vergelijken met de afbeelding van een vervalst biljet en het vervolgens te classificeren als echt of vervalst. Als het misschien vervelend of kritiek is om te wachten op de validatie van de notitie, zou het ook interessant zijn om die vergelijking snel te maken.

Omdat afbeeldingen worden gebruikt, kunnen ze worden gecomprimeerd, gereduceerd tot grijswaarden en kunnen de metingen worden geรซxtraheerd of gekwantiseerd. Op deze manier zou de vergelijking plaatsvinden tussen afbeeldingsmetingen, in plaats van de pixel van elke afbeelding.

Tot nu toe hebben we een manier gevonden om bankbiljetten te verwerken en te vergelijken, maar hoe worden ze geclassificeerd als echt of vervalst? We kunnen machine learning gebruiken om die classificatie te doen. Er wordt een classificatie-algoritme genoemd Ondersteuning van Vector Machine, vooral bekend onder de verkorte vorm: SVM's.

Achtergrond van SVM's

SVM's werden voor het eerst geรฏntroduceerd in 1968 door Vladmir Vapnik en Alexey Chervonenkis. In die tijd was hun algoritme beperkt tot de classificatie van gegevens die konden worden gescheiden met slechts รฉรฉn rechte lijn, of gegevens die dat wel waren lineair scheidbaar. We kunnen zien hoe die scheiding eruit zou zien:

Implementatie van SVM en Kernel SVM met Python's Scikit-Learn PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

In de bovenstaande afbeelding hebben we een lijn in het midden, waarvan sommige punten zich links en andere rechts van die lijn bevinden. Merk op dat beide groepen punten perfect gescheiden zijn, er zijn geen punten tussen of zelfs dicht bij de lijn. Er lijkt een marge te zijn tussen vergelijkbare punten en de lijn die ze scheidt, die marge wordt genoemd scheidingsmarge. De functie van de scheidingsmarge is om de ruimte tussen de vergelijkbare punten en de lijn die ze scheidt groter te maken. SVM doet dat door enkele punten te gebruiken en zijn loodrechte vectoren te berekenen om de beslissing voor de marge van de lijn te ondersteunen. Dat zijn de ondersteuningsvectoren die deel uitmaken van de naam van het algoritme. We zullen later meer over hen begrijpen. En de rechte lijn die we in het midden zien, wordt gevonden door methoden die maximaliseren die ruimte tussen de lijn en de punten, of die de scheidingsmarge maximaliseren. Die methodes vinden hun oorsprong op het gebied van optimalisatie theorie.

In het voorbeeld dat we zojuist hebben gezien, kunnen beide groepen punten gemakkelijk van elkaar worden gescheiden, aangezien elk individueel punt dicht bij zijn vergelijkbare punten ligt en de twee groepen ver van elkaar verwijderd zijn.

Maar wat gebeurt er als er geen manier is om de gegevens met รฉรฉn rechte lijn te scheiden? Als er rommelige punten zijn die niet op hun plaats liggen, of als er een bocht nodig is?

Om dat probleem op te lossen, werd SVM later in de jaren negentig verfijnd om ook gegevens te kunnen classificeren die punten hadden die ver verwijderd waren van de centrale tendens, zoals uitschieters, of complexere problemen die meer dan twee dimensies hadden en niet lineair te scheiden waren .

Wat merkwaardig is, is dat SVM's pas de laatste jaren wijdverspreid zijn geworden, voornamelijk vanwege hun vermogen om soms meer dan 90% van de juiste antwoorden of nauwkeurigheid, voor moeilijke problemen.

SVM's worden op een unieke manier geรฏmplementeerd in vergelijking met andere machine learning-algoritmen, zodra ze gebaseerd zijn op statistische verklaringen van wat leren is, of op Statistische leerteorie.

In dit artikel zullen we zien wat Support Vector Machines-algoritmen zijn, de korte theorie achter een Support Vector Machine en hun implementatie in de Scikit-Learn-bibliotheek van Python. We gaan dan over op een ander SVM-concept, bekend als Kernel-SVMof Kernel truc, en zal het ook implementeren met behulp van Scikit-Learn.

Eenvoudig (lineair) SVM-model

Over de gegevensset

In navolging van het voorbeeld uit de inleiding zullen we een dataset gebruiken met metingen van afbeeldingen van echte en vervalste bankbiljetten.

Wanneer we naar twee noten kijken, scannen onze ogen ze meestal van links naar rechts en kijken ze waar er overeenkomsten of verschillen zijn. We zoeken naar een zwarte stip die voor een groene stip komt, of naar een glimmende markering boven een illustratie. Dit betekent dat er een volgorde is waarin we naar de noten kijken. Als we wisten dat er groene en zwarte stippen waren, maar niet als de groene stip voor de zwarte kwam, of als de zwarte voor de groene kwam, zou het moeilijker zijn om onderscheid te maken tussen noten.

Er is een methode die vergelijkbaar is met wat we zojuist hebben beschreven en die kan worden toegepast op de afbeeldingen van bankbiljetten. In het algemeen bestaat deze methode uit het vertalen van de beeldpixels in een signaal, waarbij vervolgens rekening wordt gehouden met de volgorde waarin elk verschillend signaal in het beeld voorkomt door het om te zetten in kleine golven, of golfjes. Na het verkrijgen van de wavelets, is er een manier om de volgorde te kennen waarin het ene signaal voor het andere plaatsvindt, of de niet de tijd of, maar niet precies welk signaal. Om dat te weten, moeten de frequenties van het beeld worden verkregen. Ze worden verkregen door een methode die de ontleding van elk signaal doet, genaamd Fourier-methode.

Zodra de tijdsdimensie is verkregen via de wavelets en de frequentiedimensie via de Fourier-methode, wordt een superpositie van tijd en frequentie gemaakt om te zien of ze beide overeenkomen, dit is de kronkeling analyse. De convolutie krijgt een aanpassing die overeenkomt met de golfjes met de frequenties van het beeld en ontdekt welke frequenties prominenter zijn.

Deze methode, waarbij de golfjes en hun frequenties worden gevonden en vervolgens beide worden aangepast, wordt genoemd Wavelet-transformatie. De wavelet-transformatie heeft coรซfficiรซnten en die coรซfficiรซnten werden gebruikt om de metingen te verkrijgen die we in de dataset hebben.

De gegevensset importeren

De gegevensset bankbiljetten die we in deze sectie gaan gebruiken, is dezelfde als die werd gebruikt in de classificatiesectie van de tutorial over de beslissingsboom.

Opmerking: U kunt de dataset downloaden hier.

Laten we de gegevens importeren in een panda's dataframe structuur en bekijk de eerste vijf rijen met de head() methode.

Merk op dat de gegevens worden opgeslagen in een txt (tekst) bestandsformaat, gescheiden door komma's, en het is zonder koptekst. We kunnen het reconstrueren als een tabel door het te lezen als een csv, met vermelding van de separator als een komma, en voeg de kolomnamen toe met de names argument.

Laten we die drie stappen tegelijk volgen en dan kijken naar de eerste vijf rijen met gegevens:

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

Dit resulteert 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

Opmerking: U kunt de gegevens ook lokaal opslaan en vervangen data_link For data_path, en geef het pad door naar uw lokale bestand.

We kunnen zien dat er vijf kolommen in onze dataset zijn, namelijk variance, skewness, curtosis, entropy en class. In de vijf rijen zijn de eerste vier kolommen gevuld met getallen zoals 3.62160, 8.6661, -2.8073 of doorlopend waarden, en de laatste class kolom heeft de eerste vijf rijen gevuld met nullen, of a discreet waarde.

Aangezien het ons doel is om te voorspellen of een bankbiljet authentiek is of niet, kunnen we dat doen op basis van de vier kenmerken van het biljet:

  • variance van Wavelet getransformeerd beeld. Over het algemeen is de variantie een continue waarde die meet hoeveel de gegevenspunten dichtbij of ver verwijderd zijn van de gemiddelde waarde van de gegevens. Als de punten dichter bij de gemiddelde waarde van de gegevens liggen, ligt de verdeling dichter bij een normale verdeling, wat meestal betekent dat de waarden beter verdeeld zijn en iets gemakkelijker te voorspellen. In de huidige afbeeldingscontext is dit de variantie van de coรซfficiรซnten die het resultaat zijn van de wavelet-transformatie. Hoe minder variantie, hoe dichter de coรซfficiรซnten waren bij het vertalen van het daadwerkelijke beeld.

  • skewness van Wavelet getransformeerd beeld. De scheefheid is een continue waarde die de asymmetrie van een verdeling aangeeft. Als er meer waarden links van het gemiddelde zijn, is de verdeling negatief scheef, als er meer waarden rechts van het gemiddelde zijn, is de verdeling positief scheef, en als het gemiddelde, de modus en de mediaan hetzelfde zijn, is de verdeling symmetrisch. Hoe symmetrischer een verdeling is, hoe dichter deze bij een normale verdeling ligt, waarbij de waarden ook beter verdeeld zijn. In de huidige context is dit de scheefheid van de coรซfficiรซnten die het resultaat zijn van de wavelet-transformatie. Hoe meer symmetrisch, hoe dichter de coรซfficiรซnten wevariance, skewness, curtosis, entropyre naar het vertalen van de werkelijke afbeelding.

Implementatie van SVM en Kernel SVM met Python's Scikit-Learn PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

  • curtosis (of kurtosis) van Wavelet Transformed-afbeelding. De kurtosis is een continue waarde die, net als scheefheid, ook de vorm van een verdeling beschrijft. Afhankelijk van de kurtosis-coรซfficiรซnt (k) kan een verdeling - in vergelijking met de normale verdeling min of meer vlak zijn - of meer of minder gegevens in de uiteinden of staarten hebben. Wanneer de verdeling meer verspreid en vlakker is, wordt dit genoemd platikurtisch; wanneer het minder verspreid is en meer geconcentreerd in het midden, mesokurtisch; en wanneer de distributie bijna geheel geconcentreerd is in het midden, wordt deze genoemd leptokurtisch. Dit is hetzelfde geval als de eerdere gevallen van variantie en scheefheid, hoe meer mesokurtisch de verdeling is, hoe dichter de coรซfficiรซnten bij het vertalen van het werkelijke beeld waren.

Implementatie van SVM en Kernel SVM met Python's Scikit-Learn PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

  • entropy van beeld. De entropie is ook een continue waarde, het meet meestal de willekeur of wanorde in een systeem. In de context van een afbeelding meet entropie het verschil tussen een pixel en de aangrenzende pixels. Voor onze context, hoe meer entropie de coรซfficiรซnten hebben, hoe meer verlies er was bij het transformeren van het beeld - en hoe kleiner de entropie, hoe kleiner het informatieverlies.

Implementatie van SVM en Kernel SVM met Python's Scikit-Learn PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

De vijfde variabele was de class variabele, die waarschijnlijk 0 en 1 waarden heeft, die aangeven of het biljet echt of vervalst was.

We kunnen controleren of de vijfde kolom nullen bevat en enen met Panda's' unique() methode:

bankdata['class'].unique()

De bovenstaande methode retourneert:

array([0, 1]) 

De bovenstaande methode retourneert een array met waarden van 0 en 1. Dit betekent dat de enige waarden in onze klassenrijen nullen en enen zijn. Het is klaar om te worden gebruikt als de doel in ons begeleid leren.

  • class van beeld. Dit is een geheel getal, het is 0 wanneer de afbeelding vervalst is en 1 wanneer de afbeelding echt is.

Omdat we een kolom hebben met de annotaties van echte en vergeten afbeeldingen, betekent dit dat ons type leren is toezicht.

Advies: lees het gepubliceerde artikel van de auteurs om meer te weten te komen over de redenering achter de Wavelet-transformatie op de afbeeldingen van bankbiljetten en het gebruik van SVM.

We kunnen ook zien hoeveel records, of afbeeldingen we hebben, door te kijken naar het aantal rijen in de data via de shape eigendom:

bankdata.shape

Dit levert op:

(1372, 5)

De bovenstaande regel betekent dat er 1,372 rijen getransformeerde afbeeldingen van bankbiljetten en 5 kolommen zijn. Dit zijn de gegevens die we gaan analyseren.

We hebben onze dataset geรฏmporteerd en enkele controles uitgevoerd. Nu kunnen we onze gegevens verkennen om het beter te begrijpen.

De dataset verkennen

We hebben zojuist gezien dat er alleen nullen en enen in de klassenkolom staan, maar we kunnen ook weten in welke verhouding ze staan โ€‹โ€‹โ€“ met andere woorden โ€“ of er meer nullen dan enen zijn, meer enen dan nullen, of als de getallen van nullen is hetzelfde als het aantal enen, wat betekent dat ze dat zijn evenwichtige.

Om de verhouding te kennen waarmee we elk van de nul- en รฉรฉn-waarden in de gegevens kunnen tellen value_counts() methode:

bankdata['class'].value_counts()

Dit levert op:

0 762
1 610
Name: class, dtype: int64

In het bovenstaande resultaat kunnen we zien dat er 762 nullen en 610 enen zijn, of 152 meer nullen dan enen. Dit betekent dat we iets meer vervalste dan echte afbeeldingen hebben, en als die discrepantie groter was, bijvoorbeeld 5500 nullen en 610 enen, zou dit een negatieve invloed kunnen hebben op onze resultaten. Zodra we die voorbeelden in ons model proberen te gebruiken - hoe meer voorbeelden er zijn, betekent meestal dat hoe meer informatie het model zal hebben om te beslissen tussen vervalste of echte biljetten - als er weinig voorbeelden van echte biljetten zijn, is het model vatbaar voor vergiste zich toen ze probeerden ze te herkennen.

We weten al dat er nog 152 vervalste bankbiljetten zijn, maar kunnen we er zeker van zijn dat dit genoeg voorbeelden zijn voor het model om te leren? Weten hoeveel voorbeelden er nodig zijn om te leren, is een heel moeilijke vraag om te beantwoorden, in plaats daarvan kunnen we proberen te begrijpen, in procenten, hoeveel dat verschil tussen klassen is.

De eerste stap is het gebruik van panda's value_counts() methode opnieuw, maar laten we nu het percentage bekijken door het argument op te nemen normalize=True:

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

De normalize=True berekent het percentage van de gegevens voor elke klasse. Tot nu toe is het percentage vervalste (0) en echte gegevens (1):

0 0.555394
1 0.444606
Name: class, dtype: float64

Dit betekent dat ongeveer (~) 56% van onze dataset vervalst is en 44% ervan echt is. Dit geeft ons een verhouding van 56%-44%, wat hetzelfde is als een verschil van 12%. Dit wordt statistisch gezien als een klein verschil beschouwd, omdat het net iets meer dan 10% is, dus de gegevens worden als evenwichtig beschouwd. Als er in plaats van een verhouding van 56:44 een verhouding van 80:20 of 70:30 zou zijn, dan zouden onze gegevens als onevenwichtig worden beschouwd en zouden we een onbalansbehandeling moeten uitvoeren, maar gelukkig is dit niet het geval.

We kunnen dit verschil ook visueel zien, door de verdeling van de klasse of het doelwit te bekijken met een door panda's doordrenkt histogram, door gebruik te maken van:

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

Dit plot een histogram met behulp van de dataframe-structuur rechtstreeks, in combinatie met de matplotlib bibliotheek achter de schermen.

Implementatie van SVM en Kernel SVM met Python's Scikit-Learn PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Door naar het histogram te kijken, kunnen we er zeker van zijn dat onze doelwaarden 0 of 1 zijn en dat de gegevens in evenwicht zijn.

Dit was een analyse van de kolom die we probeerden te voorspellen, maar hoe zit het met het analyseren van de andere kolommen van onze gegevens?

We kunnen de statistische metingen bekijken met de describe() dataframe-methode. We kunnen ook gebruiken .T van transponeren - om kolommen en rijen om te keren, waardoor het directer is om waarden te vergelijken:

Bekijk onze praktische, praktische gids voor het leren van Git, met best-practices, door de industrie geaccepteerde normen en bijgevoegd spiekbriefje. Stop met Googlen op Git-commando's en eigenlijk leren het!

bankdata.describe().T

Dit resulteert 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

Merk op dat scheefheid- en curtosis-kolommen gemiddelde waarden hebben die ver van de standaarddeviatiewaarden liggen. Dit geeft aan dat die waarden verder van de centrale tendens van de gegevens liggen, of een grotere variabiliteit hebben.

We kunnen ook visueel een kijkje nemen in de distributie van elk kenmerk, door het histogram van elk kenmerk in een for-lus uit te zetten. Naast het kijken naar de verdeling, zou het interessant zijn om te kijken hoe de punten van elke klasse zijn gescheiden met betrekking tot elk kenmerk. Om dat te doen, kunnen we een spreidingsdiagram plotten door een combinatie van kenmerken ertussen te maken, en verschillende kleuren toekennen aan elk punt met betrekking tot zijn klasse.

Laten we beginnen met de distributie van elk kenmerk en het histogram van elke gegevenskolom plotten, behalve de class kolom. De class kolom wordt niet in aanmerking genomen door zijn positie in de reeks kolommen met bankgegevens. Alle kolommen worden geselecteerd behalve de laatste met columns[:-1]:

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

Na het uitvoeren van de bovenstaande code, kunnen we zien dat beide skewness en entropy gegevensdistributies zijn negatief scheef en curtosis positief scheef is. Alle distributies zijn symmetrisch, en variance is de enige verdeling die dicht bij normaal ligt.

We kunnen nu doorgaan naar het tweede deel, en de scatterplot van elke variabele plotten. Om dit te doen, kunnen we ook alle kolommen selecteren behalve de klasse, met columns[:-1], gebruik Seaborn's scatterplot() en twee for-lussen om de variaties in koppeling voor elk van de functies te verkrijgen. We kunnen ook de koppeling van een kenmerk met zichzelf uitsluiten door te testen of het eerste kenmerk gelijk is aan het tweede met een 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();

Merk op dat alle grafieken zowel echte als vervalste gegevenspunten hebben die niet duidelijk van elkaar gescheiden zijn, dit betekent dat er een soort superpositie van klassen is. Aangezien een SVM-model een lijn gebruikt om klassen van elkaar te scheiden, kan een van die groepen in de grafieken dan worden gescheiden met slechts รฉรฉn lijn? Het lijkt onwaarschijnlijk. Zo zien de meeste echte gegevens eruit. Het dichtst bij een scheiding komen we in de combinatie van skewness en varianceof entropy en variance percelen. Dit komt waarschijnlijk door variance gegevens met een verdelingsvorm die dichter bij normaal ligt.

Maar het kan een beetje moeilijk zijn om al die grafieken achter elkaar te bekijken. We hebben het alternatief om alle distributie- en spreidingsgrafieken samen te bekijken met behulp van Seaborn's pairplot().

Beide vorige for-lussen die we hadden gedaan, kunnen worden vervangen door alleen deze regel:

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

Kijkend naar de pairplot, lijkt het erop dat, eigenlijk, curtosis en variance zou de gemakkelijkste combinatie van functies zijn, dus de verschillende klassen kunnen worden gescheiden door een lijn, of lineair scheidbaar.

Als de meeste gegevens verre van lineair scheidbaar zijn, kunnen we proberen ze voor te verwerken door de afmetingen ervan te verkleinen, en ook de waarden ervan te normaliseren om te proberen de verdeling dichter bij een normaal te brengen.

Laten we in dit geval de gegevens gebruiken zoals ze zijn, zonder verdere voorverwerking, en later kunnen we een stap teruggaan, toevoegen aan de gegevensvoorverwerking en de resultaten vergelijken.

Advies: Bij het werken met gegevens gaat informatie meestal verloren bij het transformeren ervan, omdat we benaderingen maken in plaats van meer gegevens te verzamelen. Door eerst met de initiรซle gegevens te werken zoals ze zijn, biedt dit, indien mogelijk, een basislijn voordat u andere voorverwerkingstechnieken probeert. Wanneer u dit pad volgt, kan het eerste resultaat met onbewerkte gegevens worden vergeleken met een ander resultaat dat voorverwerkingstechnieken op de gegevens gebruikt.

Opmerking: Gewoonlijk is het in de statistiek bij het bouwen van modellen gebruikelijk om een โ€‹โ€‹procedure te volgen die afhangt van het soort gegevens (discreet, continu, categoriaal, numeriek), de distributie ervan en de aannames van het model. Terwijl er in Computer Science (CS) meer ruimte is voor vallen, opstaan โ€‹โ€‹en nieuwe iteraties. In CS is het gebruikelijk om een โ€‹โ€‹basislijn te hebben om mee te vergelijken. In Scikit-learn is er een implementatie van dummy-modellen (of dummy-schatters), sommige zijn niet beter dan het opgooien van een munt, en antwoorden gewoon ja (of 1) 50% van de tijd. Het is interessant om dummy-modellen te gebruiken als basis voor het daadwerkelijke model bij het vergelijken van resultaten. Er wordt verwacht dat de daadwerkelijke modelresultaten beter zijn dan een willekeurige gok, anders zou het gebruik van een machine learning-model niet nodig zijn.

SVM implementeren met Scikit-Learn

Voordat we meer ingaan op de theorie van hoe SVM werkt, kunnen we ons eerste basismodel bouwen met de gegevens, en Scikit-Learn's Ondersteuning van vectorclassificator or SVC klasse.

Ons model ontvangt de wavelet-coรซfficiรซnten en probeert ze te classificeren op basis van de klasse. De eerste stap in dit proces is het scheiden van de coรซfficiรซnten of functionaliteiten uit de klas of doel. Na die stap is de tweede stap het verder verdelen van de gegevens in een set die zal worden gebruikt voor het leren van het model of trein set en een andere die zal worden gebruikt voor de evaluatie van het model of testset.

Opmerking: De nomenclatuur van test en evaluatie kan een beetje verwarrend zijn, omdat u uw gegevens ook kunt splitsen tussen trein-, evaluatie- en testsets. Op deze manier zou u in plaats van twee sets een tussenset hebben om te gebruiken en te kijken of de prestaties van uw model verbeteren. Dit betekent dat het model wordt getraind met de treinset, verbeterd met de evaluatieset en een laatste metriek wordt verkregen met de testset.

Sommige mensen zeggen dat de evaluatie die tussenset is, anderen zullen zeggen dat de testset de tussenset is en dat de evaluatieset de laatste set is. Dit is een andere manier om te proberen te garanderen dat het model op geen enkele manier hetzelfde voorbeeld ziet, of op de een of andere manier data lekkage niet gebeurt, en dat er een modelgeneralisatie is door de verbetering van de laatst ingestelde statistieken. Als u die aanpak wilt volgen, kunt u de gegevens nog een keer verder splitsen zoals hierin beschreven Train_test_split() van Scikit-Learn โ€“ Trainings-, test- en validatiesets gids.

Gegevens verdelen in trein-/testsets

In de vorige sessie hebben we de gegevens begrepen en onderzocht. Nu kunnen we onze gegevens in twee arrays verdelen: een voor de vier kenmerken en een andere voor het vijfde of doelkenmerk. Omdat we de klasse willen voorspellen op basis van de wavelets-coรซfficiรซnten, is onze y zal het zijn class column en onze X zal de variance, skewness, curtosis en entropy kolommen.

Om het doelwit en de kenmerken te scheiden, kunnen we alleen de toeschrijven class kolom naar y, en laat het later uit het dataframe vallen om de resterende kolommen aan toe te schrijven X Met .drop() methode:

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

Zodra de gegevens zijn onderverdeeld in attributen en labels, kunnen we deze verder verdelen in trein- en testsets. Dit kan met de hand worden gedaan, maar de model_selection bibliotheek van Scikit-Learn bevat de train_test_split() methode waarmee we gegevens willekeurig kunnen verdelen in trein- en testsets.

Om het te gebruiken, kunnen we de bibliotheek importeren, de train_test_split() methode, doorgeven X en y gegevens, en definieer a test_size als argument doorgeven. In dit geval zullen we het definiรซren als 0.20โ€“ dit betekent dat 20% van de gegevens wordt gebruikt voor testen en de overige 80% voor training.

Deze methode neemt willekeurig monsters met inachtneming van het percentage dat we hebben gedefinieerd, maar respecteert de Xy-paren, anders zou de bemonstering de relatie volledig door elkaar halen.

Aangezien het bemonsteringsproces inherent willekeurig is, zullen we altijd verschillende resultaten hebben bij het uitvoeren van de methode. Om dezelfde resultaten of reproduceerbare resultaten te krijgen, kunnen we een constante genaamd SEED definiรซren met de waarde 42.

U kunt hiervoor het volgende script uitvoeren:

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)

Merk op dat de train_test_split() methode retourneert al de X_train, X_test, y_train, y_test sets in deze volgorde. We kunnen het aantal gescheiden monsters voor trein en test afdrukken door het eerste (0) element van het shape eigenschap geretourneerde tuple:

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

Hieruit blijkt dat er 1097 monsters zijn voor training en 275 voor testen.

Het model trainen

We hebben de data opgedeeld in trein- en testsets. Nu is het tijd om een โ€‹โ€‹SVM-model te maken en te trainen op de treingegevens. Om dat te doen, kunnen we Scikit-Learn's importeren svm bibliotheek samen met de Ondersteuning van vectorclassificator klasse, of SVC klasse.

Nadat we de klasse hebben geรฏmporteerd, kunnen we er een instantie van maken - aangezien we een eenvoudig SVM-model maken, proberen we onze gegevens lineair te scheiden, zodat we een lijn kunnen trekken om onze gegevens te verdelen - wat hetzelfde is als het gebruik van een lineaire functie - door te definiรซren kernel='linear' als argument voor de classifier:

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

Op deze manier probeert de classifier een lineaire functie te vinden die onze gegevens scheidt. Nadat we het model hebben gemaakt, gaan we het trainen, of geschikt het, met de treingegevens, in dienst van de fit() methode en het geven van de X_train Kenmerken en y_train doelstellingen als argumenten.

We kunnen de volgende code uitvoeren om het model te trainen:

svc.fit(X_train, y_train)

Zo wordt het model getraind. Tot nu toe hebben we de gegevens begrepen, verdeeld, een eenvoudig SVM-model gemaakt en het model aangepast aan de treingegevens.

De volgende stap is om te begrijpen hoe goed die fit erin slaagde onze gegevens te beschrijven. Met andere woorden, om te beantwoorden of een lineaire SVM een adequate keuze was.

Voorspellingen doen

Een manier om erachter te komen of het model erin is geslaagd de gegevens te beschrijven, is door een classificatie te berekenen en te bekijken metriek.

Aangezien het leren begeleid wordt, kunnen we er voorspellingen mee doen X_test en vergelijk die voorspellingsresultaten - die we zouden kunnen noemen y_pred โ€“ met het werkelijke y_testof grond waarheid.

Om een โ€‹โ€‹deel van de gegevens te voorspellen, gebruikt het model predict() methode kan worden toegepast. Deze methode ontvangt de testfuncties, X_test, als een argument en retourneert een voorspelling, 0 of 1, voor elk van X_test's rijen.

Na het voorspellen van de X_test gegevens worden de resultaten opgeslagen in een y_pred variabel. Dus elk van de klassen die zijn voorspeld met het eenvoudige lineaire SVM-model, bevindt zich nu in de y_pred variabel.

Dit is de voorspellingscode:

y_pred = svc.predict(X_test)

Aangezien we de voorspellingen hebben, kunnen we ze nu vergelijken met de werkelijke resultaten.

Het model evalueren

Er zijn verschillende manieren om voorspellingen te vergelijken met werkelijke resultaten, en ze meten verschillende aspecten van een classificatie. Enkele meest gebruikte classificatiestatistieken zijn:

  1. Verwarring Matrix: wanneer we moeten weten voor hoeveel monsters we goed of fout zijn elke klas. De waarden die correct en correct voorspeld waren, worden genoemd echte positieven, degenen die als positief werden voorspeld maar niet positief waren, worden genoemd valse positieven. Dezelfde nomenclatuur van echte negatieven en valse negatieven wordt gebruikt voor negatieve waarden;

  2. precisie: wanneer het ons doel is om te begrijpen welke correcte voorspellingswaarden door onze classificator als correct werden beschouwd. Precisie deelt die echte positieve waarden door de monsters die als positief werden voorspeld;

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

  1. Terugroepen: gewoonlijk berekend samen met precisie om te begrijpen hoeveel van de echte positieven werden geรฏdentificeerd door onze classificator. De terugroepactie wordt berekend door de echte positieven te delen door alles wat als positief had moeten worden voorspeld.

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

  1. F1-score: is de gebalanceerde of harmonisch gemiddelde van precisie en herinnering. De laagste waarde is 0 en de hoogste is 1. Wanneer f1-score gelijk is aan 1, betekent dit dat alle klassen correct werden voorspeld - dit is een zeer moeilijke score om te verkrijgen met echte gegevens (uitzonderingen zijn er bijna altijd).

$$
tekst{f1-score} = 2* frac{tekst{precisie} * tekst{herinnering}}{tekst{precisie} + tekst{herinnering}}
$$

We zijn al bekend met verwarringsmatrix, precisie, herinnering en F1-scoremetingen. Om ze te berekenen, kunnen we Scikit-Learn's importeren metrics bibliotheek. Deze bibliotheek bevat de classification_report en confusion_matrix methoden, retourneert de classificatierapportmethode de precisie, herinnering en f1-score. Beide classification_report en confusion_matrix kan gemakkelijk worden gebruikt om de waarden voor al die belangrijke statistieken te achterhalen.

Voor het berekenen van de statistieken importeren we de methoden, roepen ze op en geven als argumenten de voorspelde classificaties door, y_test, en de classificatielabels, of y_true.

Voor een betere visualisatie van de verwarringsmatrix kunnen we deze plotten in een Seaborn's heatmap samen met kwantiteitsaantekeningen, en voor het classificatierapport is het het beste om de uitkomst af te drukken, zodat de resultaten opgemaakt zijn. Dit is de volgende code:

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

Dit toont:

 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

Implementatie van SVM en Kernel SVM met Python's Scikit-Learn PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

In het classificatierapport weten we dat er een precisie is van 0.99, recall van 0.99 en een f1-score van 0.99 voor de vervalste bankbiljetten, of klasse 0. Die metingen werden verkregen met behulp van 148 monsters, zoals weergegeven in de ondersteuningskolom. Ondertussen, voor klasse 1, of echte noten, was het resultaat รฉรฉn eenheid lager, een precisie van 0.98, 0.98 herinnering en dezelfde f1-score. Dit keer werden 127 beeldmetingen gebruikt om die resultaten te verkrijgen.

Als we naar de verwarringsmatrix kijken, kunnen we ook zien dat van 148 monsters van klasse 0 er 146 correct werden geclassificeerd en dat er 2 fout-positieven waren, terwijl er voor 127 monsters van klasse 1 2 fout-negatieven en 125 terecht-positieven waren.

We kunnen het classificatierapport en de verwarringsmatrix lezen, maar wat betekenen ze?

Resultaten interpreteren

Laten we eens kijken naar alle statistieken gecombineerd om de betekenis te achterhalen.

Bijna alle monsters voor klasse 1 waren correct geclassificeerd, er waren 2 fouten voor ons model bij het identificeren van echte bankbiljetten. Dit is hetzelfde als 0.98 of 98% terugroepen. Iets soortgelijks kan worden gezegd van klasse 0, slechts 2 monsters werden onjuist geclassificeerd, terwijl 148 echte negatieven zijn, wat neerkomt op een nauwkeurigheid van 99%.

Afgezien van die resultaten markeren alle andere 0.99, wat bijna 1 is, een zeer hoge statistiek. Meestal, wanneer zo'n hoge statistiek voorkomt met gegevens uit het echte leven, kan dit duiden op een model dat te veel is aangepast aan de gegevens, of overfit.

Als er een overfit is, werkt het model misschien goed bij het voorspellen van de gegevens die al bekend zijn, maar verliest het de mogelijkheid om te generaliseren naar nieuwe gegevens, wat belangrijk is in scenario's uit de echte wereld.

Een snelle test om erachter te komen of er sprake is van een overfit is ook met treingegevens. Als het model de treingegevens enigszins heeft onthouden, zullen de statistieken zeer dicht bij 1 of 100% liggen. Onthoud dat de treingegevens groter zijn dan de testgegevens - probeer het daarom proportioneel te bekijken, meer steekproeven, meer kans op fouten, tenzij er sprake is van een overfit.

Om te voorspellen met treindata kunnen we herhalen wat we hebben gedaan voor testdata, maar nu met 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))

Dit levert op:

 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

Implementatie van SVM en Kernel SVM met Python's Scikit-Learn PlatoBlockchain Data Intelligence. Verticaal zoeken. Ai.

Het is gemakkelijk te zien dat er een overfit lijkt te zijn, zodra de treinstatistieken 99% zijn bij 4 keer meer gegevens. Wat kan er in dit scenario worden gedaan?

Om de overfit ongedaan te maken, kunnen we meer treinwaarnemingen toevoegen, een trainingsmethode gebruiken met verschillende delen van de dataset, zoals kruisvalidatie, en verander ook de standaardparameters die al bestaan โ€‹โ€‹voorafgaand aan de training, bij het maken van ons model, of hyperparameters. Meestal stelt Scikit-learn enkele parameters als standaard in, en dit kan geruisloos gebeuren als er niet veel tijd is besteed aan het lezen van de documentatie.

U kunt het tweede deel van deze gids raadplegen (coming soon!) om te zien hoe u kruisvalidatie implementeert en hyperparameterafstemming uitvoert.

Conclusie

In dit artikel hebben we de eenvoudige lineaire kernel SVM bestudeerd. We kregen de intuรฏtie achter het SVM-algoritme, gebruikten een echte dataset, verkenden de gegevens en zagen hoe deze gegevens samen met SVM kunnen worden gebruikt door ze te implementeren met de Scikit-Learn-bibliotheek van Python.

Om te blijven oefenen, kunt u andere gegevenssets uit de echte wereld proberen die beschikbaar zijn op plaatsen zoals Kaggle, UCI, Big Query openbare datasets, universiteiten en overheidswebsites.

Ik zou ook willen voorstellen dat u de feitelijke wiskunde achter het SVM-model onderzoekt. Hoewel je het niet per se nodig hebt om het SVM-algoritme te gebruiken, is het toch erg handig om te weten wat er achter de schermen gebeurt terwijl je algoritme beslissingsgrenzen zoekt.

Tijdstempel:

Meer van Stapelmisbruik