Implementacja SVM i Kernel SVM za pomocą Scikit-Learn w Pythonie

Implementacja SVM i Kernel SVM za pomocą Scikit-Learn w Pythonie

Wprowadzenie

Ten przewodnik jest pierwszą częścią trzech przewodników dotyczących maszyn wektorów nośnych (SVM). W tej serii będziemy pracować nad przypadkiem użycia sfałszowanych banknotów, poznamy prostą SVM, następnie hiperparametry SVM i wreszcie poznamy koncepcję zwaną sztuczka z jądrem i poznaj inne typy maszyn SVM.

Jeśli chcesz przeczytać wszystkie poradniki lub sprawdzić, który z nich najbardziej Cię interesuje, poniżej znajduje się tabela tematów poruszanych w każdym poradniku:

1. Implementacja SVM i Kernel SVM za pomocą Scikit-Learn w Pythonie

  • Przypadek użycia: zapomnij o banknotach
  • Tło maszyn SVM
  • Prosty (liniowy) model SVM
    • O zbiorze danych
    • Importowanie zestawu danych
    • Eksploracja zbioru danych
  • Implementacja SVM z Scikit-Learn
    • Dzielenie danych na zestawy pociągów/testów
    • Trenowanie modelu
    • Dokonywanie prognoz
    • Ocena modelu
    • Interpretowanie wyników

2. Zrozumienie hiperparametrów SVM (wkrótce!)

  • Hiperparametr C
  • Hiperparametr Gamma

3. Implementacja innych smaków SVM za pomocą Scikit-Learn w Pythonie (wkrótce!)

  • Ogólna koncepcja maszyn SVM (podsumowanie)
  • Jądro (sztuczka) SVM
  • Implementacja SVM z nieliniowym jądrem za pomocą Scikit-Learn
  • Importowanie bibliotek
    • Importowanie zbioru danych
    • Podział danych na cechy (X) i cel (y)
    • Dzielenie danych na zestawy pociągów/testów
    • Trening algorytmu
  • Jądro wielomianowe
    • Dokonywanie prognoz
    • Ocena algorytmu
  • Jądro Gaussa
    • Przewidywanie i ocena
  • Jądro esicy
    • Przewidywanie i ocena
  • Porównanie nieliniowych wydajności jądra

Przypadek użycia: sfałszowane banknoty

Czasami ludzie znajdują sposób na fałszowanie banknotów. Jeśli jest osoba, która przegląda te notatki i weryfikuje ich ważność, może być trudno dać się nabrać na ich widok.

Ale co się dzieje, gdy nie ma osoby, która mogłaby spojrzeć na każdą notatkę? Czy istnieje sposób automatycznego rozpoznania, czy banknoty są fałszywe, czy prawdziwe?

Na te pytania można odpowiedzieć na wiele sposobów. Jedną z odpowiedzi jest sfotografowanie każdego otrzymanego banknotu, porównanie jego obrazu z wizerunkiem sfałszowanego banknotu, a następnie sklasyfikowanie go jako prawdziwego lub sfałszowanego. Gdy oczekiwanie na zatwierdzenie notatki może być żmudne lub krytyczne, interesujące byłoby również szybkie wykonanie tego porównania.

Ponieważ używane są obrazy, można je upakować, zredukować do skali szarości, a ich pomiary wyodrębnić lub skwantyzować. W ten sposób porównanie odbywałoby się między pomiarami obrazów, a nie pikselami każdego obrazu.

Jak dotąd znaleźliśmy sposób na przetwarzanie i porównywanie banknotów, ale jak zostaną one sklasyfikowane jako prawdziwe lub podrobione? Możemy użyć uczenia maszynowego, aby dokonać tej klasyfikacji. Istnieje algorytm klasyfikacji tzw Maszyna wektorów nośnych, znany głównie ze skróconej formy: SVM.

Tło maszyn SVM

SVM zostały wprowadzone początkowo w 1968 roku przez Vladmira Vapnika i Alexeya Chervonenkisa. W tamtym czasie ich algorytm ograniczał się do klasyfikacji danych, które można było oddzielić za pomocą jednej linii prostej, czyli danych, które były liniowo oddzielone. Możemy zobaczyć, jak wyglądałoby to rozdzielenie:

Implementacja SVM i Kernel SVM za pomocą Pythona Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Na powyższym obrazku mamy linię pośrodku, do której niektóre punkty znajdują się na lewo, a inne na prawo od tej linii. Zauważ, że obie grupy punktów są idealnie rozdzielone, nie ma punktów pomiędzy ani nawet blisko linii. Wydaje się, że istnieje margines między podobnymi punktami a linią, która je dzieli, margines ten nazywa się margines separacji. Funkcją marginesu separacji jest zwiększenie odstępu między podobnymi punktami a linią, która je dzieli. SVM robi to, używając niektórych punktów i oblicza swoje prostopadłe wektory, aby wesprzeć decyzję dotyczącą marginesu linii. To są wektory wsparcia które są częścią nazwy algorytmu. Dowiemy się o nich więcej później. A linia prosta, którą widzimy pośrodku, jest znajdowana metodami, które maksymalizacji tę przestrzeń między linią a punktami lub które maksymalizują margines separacji. Metody te wywodzą się z dziedziny Teoria optymalizacji.

W przykładzie, który właśnie widzieliśmy, obie grupy punktów można łatwo rozdzielić, ponieważ każdy pojedynczy punkt znajduje się blisko swoich podobnych punktów, a te dwie grupy są daleko od siebie.

Ale co się stanie, jeśli nie ma sposobu na oddzielenie danych jedną linią prostą? Jeśli są niechlujne punkty nie na miejscu lub potrzebna jest krzywa?

Aby rozwiązać ten problem, SVM został później udoskonalony w latach 1990., aby móc również klasyfikować dane, które miały punkty oddalone od jego centralnej tendencji, takie jak wartości odstające lub bardziej złożone problemy, które miały więcej niż dwa wymiary i nie były liniowo separowalne .

Co ciekawe, dopiero w ostatnich latach SVM stały się powszechnie stosowane, głównie ze względu na ich zdolność do uzyskiwania czasami ponad 90% poprawnych odpowiedzi lub precyzja, na trudne problemy.

SVM są implementowane w unikalny sposób w porównaniu z innymi algorytmami uczenia maszynowego, gdy opierają się na statystycznych wyjaśnieniach tego, czym jest uczenie, lub na Statystyczna teoria uczenia się.

W tym artykule zobaczymy, czym są algorytmy maszyn wektorów nośnych, krótką teorię stojącą za maszyną wektorów nośnych oraz ich implementację w bibliotece Scikit-Learn Pythona. Następnie przejdziemy do innej koncepcji SVM, znanej jako SVM jądralub Sztuczka z jądrem, a także wdroży go z pomocą Scikit-Learn.

Prosty (liniowy) model SVM

O zbiorze danych

Postępując zgodnie z przykładem podanym we wstępie, użyjemy zestawu danych, który zawiera pomiary obrazów prawdziwych i sfałszowanych banknotów.

Patrząc na dwie notatki, nasze oczy zwykle skanują je od lewej do prawej i sprawdzają, gdzie mogą występować podobieństwa lub różnice. Szukamy czarnej kropki przed zieloną kropką lub błyszczącego znaku nad ilustracją. Oznacza to, że istnieje kolejność, w jakiej patrzymy na notatki. Gdybyśmy wiedzieli, że są zielone i czarne kropki, ale nie wiedzielibyśmy, czy zielona kropka pojawia się przed czarną, albo jeśli czerń pojawia się przed zieloną, trudniej byłoby rozróżnić nuty.

Istnieje podobna metoda do tej, którą właśnie opisaliśmy, którą można zastosować do obrazów banknotów. Ogólnie rzecz biorąc, metoda ta polega na przekształceniu pikseli obrazu na sygnał, a następnie uwzględnieniu kolejności, w jakiej każdy inny sygnał pojawia się na obrazie, przekształcając go w małe fale, lub fale. Po uzyskaniu falek istnieje sposób na poznanie kolejności, w jakiej pojawia się jeden sygnał przed innym, czyli kolejność czas, ale nie do końca jaki sygnał. Aby to wiedzieć, należy uzyskać częstotliwości obrazu. Uzyskuje się je metodą polegającą na dekompozycji każdego sygnału, tzw Metoda Fouriera.

Po uzyskaniu wymiaru czasu za pomocą falek, a wymiaru częstotliwości za pomocą metody Fouriera, dokonuje się nałożenia czasu i częstotliwości, aby zobaczyć, kiedy oba mają dopasowanie, to jest skręt analiza. Splot uzyskuje dopasowanie, które dopasowuje falki do częstotliwości obrazu i stwierdza, które częstotliwości są bardziej widoczne.

Ta metoda, która polega na znalezieniu falek, ich częstotliwości, a następnie dopasowaniu ich obu, nazywa się Transformacja falkowa. Transformata falkowa ma współczynniki i te współczynniki zostały użyte do uzyskania pomiarów, które mamy w zbiorze danych.

Importowanie zestawu danych

Zestaw danych banknotów, którego będziemy używać w tej sekcji, jest taki sam, jak ten, który został użyty w sekcji klasyfikacji programu samouczek drzewa decyzyjnego.

Uwaga: Możesz pobrać zbiór danych tutaj.

Zaimportujmy dane do pliku pandas dataframe strukturę i spójrz na jej pierwsze pięć wierszy z head() Metoda.

Zauważ, że dane są zapisywane w formacie txt (tekstowy), oddzielony przecinkami i bez nagłówka. Możemy zrekonstruować go jako tabelę, czytając jako a csv, określając separator jako przecinek i dodając nazwy kolumn z names argumenty.

Wykonajmy od razu te trzy kroki, a następnie przyjrzyjmy się pierwszym pięciu wierszom danych:

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

To skutkuje:

	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

Uwaga: Możesz także zapisać dane lokalnie i zastąpić je data_link dla data_pathi podaj ścieżkę do pliku lokalnego.

Widzimy, że w naszym zbiorze danych jest pięć kolumn, a mianowicie: variance, skewness, curtosis, entropy, class. W pięciu rzędach pierwsze cztery kolumny są wypełnione liczbami takimi jak 3.62160, 8.6661, -2.8073 lub ciągły wartości i ostatnie class kolumna ma pierwsze pięć wierszy wypełnionych zerami lub a odrębny wartość.

Ponieważ naszym celem jest przewidzenie, czy banknot bankowy jest autentyczny, czy nie, możemy to zrobić na podstawie czterech atrybutów banknotu:

  • variance obrazu przekształconego falkowo. Ogólnie rzecz biorąc, wariancja jest wartością ciągłą, która mierzy, jak bardzo punkty danych są blisko lub daleko od średniej wartości danych. Jeśli punkty są bliższe średniej wartości danych, rozkład jest bliższy rozkładowi normalnemu, co zwykle oznacza, że ​​jego wartości są lepiej rozłożone i nieco łatwiejsze do przewidzenia. W obecnym kontekście obrazu jest to wariancja współczynników wynikających z transformacji falkowej. Im mniejsza wariancja, tym współczynniki były bliższe translacji rzeczywistego obrazu.

  • skewness obrazu przekształconego falkowo. Skośność jest wartością ciągłą, która wskazuje na asymetrię rozkładu. Jeśli po lewej stronie średniej znajduje się więcej wartości, rozkład jest taki ujemnie skośny, jeśli jest więcej wartości na prawo od średniej, rozkład jest taki pozytywnie przekrzywiony, a jeśli średnia, tryb i mediana są takie same, rozkład jest taki sam symetryczny. Im bardziej symetryczny jest rozkład, tym bliższy jest rozkładowi normalnemu, a jego wartości są również lepiej rozłożone. W obecnym kontekście jest to skośność współczynników wynikających z transformacji falkowej. Im bardziej symetrycznie, tym bliższe nam współczynnikivariance, skewness, curtosis, entropyponownie do tłumaczenia rzeczywistego obrazu.

Implementacja SVM i Kernel SVM za pomocą Pythona Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

  • curtosis (lub kurtoza) obrazu poddanego transformacji falkowej. Kurtoza jest wartością ciągłą, która podobnie jak skośność opisuje również kształt rozkładu. W zależności od współczynnika kurtozy (k) rozkład – w porównaniu z rozkładem normalnym może być mniej lub bardziej płaski – lub mieć mniej lub więcej danych w swoich krańcach lub ogonach. Kiedy dystrybucja jest bardziej rozłożona i bardziej płaska, nazywa się to platykurtyka; gdy jest mniej rozłożony i bardziej skoncentrowany w środku, mezokurtyczny; a kiedy dystrybucja jest prawie całkowicie skoncentrowana w środku, nazywa się to leptokurtyka. Jest to ten sam przypadek, co poprzednie przypadki wariancji i skośności, im bardziej mezokurtyczny jest rozkład, tym współczynniki były bliższe translacji rzeczywistego obrazu.

Implementacja SVM i Kernel SVM za pomocą Pythona Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

  • entropy obrazu. Entropia jest również wartością ciągłą, zwykle mierzy losowość lub nieuporządkowanie w systemie. W kontekście obrazu entropia mierzy różnicę między pikselem a sąsiednimi pikselami. W naszym kontekście im większa entropia współczynników, tym większa strata podczas przekształcania obrazu – a im mniejsza entropia, tym mniejsza utrata informacji.

Implementacja SVM i Kernel SVM za pomocą Pythona Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Piątą zmienną była tzw class zmienna, która prawdopodobnie ma wartości 0 i 1, które mówią, czy banknot był prawdziwy, czy sfałszowany.

Możemy sprawdzić, czy piąta kolumna zawiera zera i jedynki z Pandami unique() metoda:

bankdata['class'].unique()

Powyższa metoda zwraca:

array([0, 1]) 

Powyższa metoda zwraca tablicę z wartościami 0 i 1. Oznacza to, że jedynymi wartościami zawartymi w wierszach naszej klasy są zera i jedynki. Jest gotowy do użycia jako cel w naszym nauczaniu nadzorowanym.

  • class obrazu. Jest to wartość całkowita, wynosi 0, gdy obraz jest sfałszowany, i 1, gdy obraz jest prawdziwy.

Ponieważ mamy kolumnę z adnotacjami prawdziwych i zapomnianych obrazów, oznacza to, że nasz rodzaj uczenia się jest nadzorowany.

Rada: aby dowiedzieć się więcej o przyczynach transformacji falkowej na obrazach banknotów i wykorzystaniu SVM, przeczytaj opublikowany artykuł autorów.

Możemy również zobaczyć, ile mamy rekordów lub obrazów, patrząc na liczbę wierszy w danych za pomocą shape własność:

bankdata.shape

To daje:

(1372, 5)

Powyższa linia oznacza, że ​​mamy 1,372 rzędy przekształconych obrazów banknotów i 5 kolumn. To są dane, które będziemy analizować.

Zaimportowaliśmy nasz zbiór danych i przeprowadziliśmy kilka kontroli. Teraz możemy eksplorować nasze dane, aby lepiej je zrozumieć.

Eksploracja zbioru danych

Właśnie widzieliśmy, że w kolumnie klasy są tylko zera i jedynki, ale możemy też wiedzieć, w jakiej proporcji są one – innymi słowy – czy jest więcej zer niż jedynek, więcej jedynek niż zer, czy też liczby zer jest taka sama jak liczba jedynek, co oznacza, że ​​są zrównoważony.

Aby poznać proporcję, za pomocą której możemy policzyć każdą zerową i jedynkową wartość w danych value_counts() metoda:

bankdata['class'].value_counts()

To daje:

0 762
1 610
Name: class, dtype: int64

W powyższym wyniku widzimy, że jest 762 zer i 610 jedynek, czyli o 152 zer więcej niż jedynek. Oznacza to, że mamy trochę więcej sfałszowanych obrazów niż rzeczywistych i gdyby ta rozbieżność była większa, np. 5500 zer i 610 jedynek, mogłoby to negatywnie wpłynąć na nasze wyniki. Kiedy już spróbujemy wykorzystać te przykłady w naszym modelu – im więcej przykładów, tym więcej informacji będzie miał model, aby zdecydować między fałszywymi a prawdziwymi banknotami – jeśli przykładów prawdziwych banknotów jest niewiele, model jest podatny na myli się, próbując je rozpoznać.

Wiemy już, że sfałszowanych notatek jest jeszcze 152, ale czy możemy być pewni, że to wystarczająca liczba przykładów, aby model mógł się ich nauczyć? Wiedza o tym, ile przykładów jest potrzebnych do nauki, jest bardzo trudnym pytaniem, na które można odpowiedzieć, zamiast tego możemy spróbować zrozumieć, w ujęciu procentowym, jaka jest różnica między klasami.

Pierwszym krokiem jest użycie pand value_counts() metodę ponownie, ale teraz zobaczmy procent, uwzględniając argument normalize=True:

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

Połączenia normalize=True oblicza procent danych dla każdej klasy. Jak dotąd odsetek danych sfałszowanych (0) i prawdziwych (1) wynosi:

0 0.555394
1 0.444606
Name: class, dtype: float64

Oznacza to, że około (~) 56% naszego zbioru danych jest sfałszowanych, a 44% jest prawdziwych. Daje nam to stosunek 56%-44%, czyli tyle samo, co 12% różnicy. Statystycznie uważa się to za niewielką różnicę, ponieważ wynosi niewiele ponad 10%, więc dane są uważane za zrównoważone. Gdyby zamiast proporcji 56:44 była proporcja 80:20 lub 70:30, to nasze dane zostałyby uznane za niezrównoważone i musielibyśmy zrobić jakieś leczenie nierównowagi, ale na szczęście tak nie jest.

Możemy również zobaczyć tę różnicę wizualnie, patrząc na dystrybucję klasy lub celu za pomocą nasyconego histogramu Pandy, używając:

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

Spowoduje to wykreślenie histogramu bezpośrednio przy użyciu struktury ramki danych w połączeniu z matplotlib biblioteka, która jest za kulisami.

Implementacja SVM i Kernel SVM za pomocą Pythona Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Patrząc na histogram, możemy być pewni, że nasze wartości docelowe wynoszą 0 lub 1 i że dane są zrównoważone.

To była analiza kolumny, którą próbowaliśmy przewidzieć, ale co z analizą innych kolumn naszych danych?

Możemy przyjrzeć się pomiarom statystycznym z describe() metoda ramki danych. Możemy również skorzystać .T transpozycji — odwraca kolumny i wiersze, co ułatwia bezpośrednie porównywanie wartości:

Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!

bankdata.describe().T

To skutkuje:

 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

Zauważ, że kolumny skośności i krzywizny mają wartości średnie, które są dalekie od wartości odchylenia standardowego, co wskazuje, że są to wartości, które są dalej od centralnej tendencji danych lub mają większą zmienność.

Możemy również rzucić okiem na rozkład każdej cechy wizualnie, wykreślając histogram każdej cechy w pętli for. Oprócz przyjrzenia się rozkładowi, interesujące byłoby przyjrzenie się, w jaki sposób punkty każdej klasy są rozdzielone w odniesieniu do każdej cechy. Aby to zrobić, możemy wykreślić wykres punktowy, tworząc kombinację cech między nimi i przypisać każdemu punktowi różne kolory w odniesieniu do jego klasy.

Zacznijmy od rozkładu każdej cechy i wykreśl histogram każdej kolumny danych z wyjątkiem kolumny class kolumna. The class kolumna nie będzie brana pod uwagę przez jej pozycję w tablicy kolumn danych bankowych. Zostaną wybrane wszystkie kolumny z wyjątkiem ostatniej z columns[:-1]:

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

Po uruchomieniu powyższego kodu widzimy, że oba skewness i entropy rozkłady danych są skośne ujemnie i curtosis jest dodatnio skośny. Wszystkie rozkłady są symetryczne i variance jest jedynym rozkładem zbliżonym do normalnego.

Możemy teraz przejść do drugiej części i wykreślić wykres rozrzutu każdej zmiennej. Aby to zrobić, możemy również zaznaczyć wszystkie kolumny oprócz klasy, za pomocą columns[:-1], użyj Seaborn's scatterplot() i dwie pętle for, aby uzyskać różnice w parowaniu dla każdej z cech. Możemy również wykluczyć parowanie cechy ze sobą, sprawdzając, czy pierwsza cecha jest równa drugiej z an 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();

Zauważ, że wszystkie wykresy mają zarówno rzeczywiste, jak i sfałszowane punkty danych, które nie są wyraźnie oddzielone od siebie, co oznacza, że ​​istnieje pewnego rodzaju superpozycja klas. Ponieważ model SVM używa linii do oddzielania klas, czy którąkolwiek z tych grup na wykresach można rozdzielić za pomocą tylko jednej linii? Wydaje się to mało prawdopodobne. Tak wygląda większość prawdziwych danych. Najbliżej separacji, jaką możemy osiągnąć, jest połączenie skewness i variancelub entropy i variance działki. Wynika to prawdopodobnie z variance dane o kształcie rozkładu bliższym normalnemu.

Ale patrzenie na wszystkie te wykresy po kolei może być trochę trudne. Mamy alternatywę, aby spojrzeć razem na wszystkie wykresy rozkładu i wykresów punktowych, korzystając z wykresów Seaborna pairplot().

Obie poprzednie pętle for, które wykonaliśmy, można zastąpić tylko tą linią:

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

Patrząc na wykres par, wydaje się, że tak naprawdę curtosis i variance byłaby najłatwiejszą kombinacją cech, więc różne klasy mogłyby być oddzielone linią, lub liniowo oddzielone.

Jeśli większość danych nie jest liniowo separowalna, możemy spróbować je wstępnie przetworzyć, zmniejszając ich wymiary, a także znormalizować ich wartości, aby spróbować zbliżyć rozkład do normalnego.

W tym przypadku użyjmy danych w takiej postaci, w jakiej są, bez dalszego wstępnego przetwarzania, a później możemy cofnąć się o jeden krok, dodać do wstępnego przetwarzania danych i porównać wyniki.

Rada: Podczas pracy z danymi informacje są zwykle tracone podczas ich przekształcania, ponieważ zamiast zbierać więcej danych, dokonujemy przybliżeń. Jeśli jest to możliwe, praca z danymi początkowymi w takiej postaci, w jakiej są dostępne, stanowi punkt odniesienia przed wypróbowaniem innych technik przetwarzania wstępnego. Podążając tą ścieżką, początkowy wynik wykorzystujący surowe dane można porównać z innym wynikiem, który wykorzystuje techniki wstępnego przetwarzania danych.

Uwaga: Zwykle w statystyce przy budowaniu modeli często stosuje się procedurę w zależności od rodzaju danych (dyskretne, ciągłe, kategorialne, numeryczne), ich rozkładu i założeń modelu. W informatyce (CS) jest więcej miejsca na próby, błędy i nowe iteracje. W CS często istnieje linia bazowa do porównania. W Scikit-learn istnieje implementacja modeli fikcyjnych (lub estymatorów fikcyjnych), niektóre nie są lepsze niż rzut monetą i po prostu odpowiedz tak (lub 1) 50% czasu. Interesujące jest użycie modeli fikcyjnych jako punktu odniesienia dla rzeczywistego modelu podczas porównywania wyników. Oczekuje się, że rzeczywiste wyniki modelu są lepsze niż losowe zgadywanie, w przeciwnym razie użycie modelu uczenia maszynowego nie byłoby konieczne.

Implementacja SVM z Scikit-Learn

Zanim zagłębimy się bardziej w teorię działania SVM, możemy zbudować nasz pierwszy model bazowy z danymi i Scikit-Learn Wsparcie klasyfikatora wektorów or SVC class.

Nasz model otrzyma współczynniki falkowe i spróbuje je sklasyfikować na podstawie klasy. Pierwszym krokiem w tym procesie jest oddzielenie współczynników lub cechy z klasy lub cel. Po tym kroku drugim krokiem jest dalsze podzielenie danych na zbiór, który posłuży do uczenia modelu lub zestaw pociągowy oraz inny, który posłuży do oceny modelu lub zestaw testowy.

Uwaga: Nomenklatura testu i oceny może być nieco myląca, ponieważ można również podzielić dane między zestawy pociągów, oceny i testów. W ten sposób, zamiast dwóch zestawów, miałbyś zestaw pośredni do użycia i sprawdzenia, czy wydajność twojego modelu się poprawia. Oznacza to, że model zostałby wytrenowany z zestawem pociągów, wzmocniony zbiorem ewaluacyjnym i uzyskałby ostateczną metrykę ze zbiorem testowym.

Niektórzy powiedzą, że zestawem pośrednim jest zestaw ewaluacyjny, inni powiedzą, że zestaw testowy jest zbiorem pośrednim, a zestaw ewaluacyjny jest zbiorem ostatecznym. Jest to kolejny sposób, aby spróbować zagwarantować, że model w żaden sposób nie widzi tego samego przykładu lub że w jakiś sposób wyciek danych tak się nie dzieje, i że istnieje uogólnienie modelu poprzez poprawę ostatniego zestawu metryk. Jeśli chcesz zastosować to podejście, możesz jeszcze raz podzielić dane, jak opisano w this Scikit-Learn's train_test_split() — Zestawy treningowe, testowe i walidacyjne przewodnik.

Dzielenie danych na zestawy pociągów/testów

W poprzedniej sesji zrozumieliśmy i zbadaliśmy dane. Teraz możemy podzielić nasze dane na dwie tablice – jedną dla czterech cech, a drugą dla piątej, czyli docelowej cechy. Ponieważ chcemy przewidzieć klasę w zależności od współczynników falkowych, nasz y będzie class kolumna i nasza X będzie variance, skewness, curtosis, entropy kolumny.

Aby oddzielić cel i funkcje, możemy przypisać tylko class kolumna do y, później upuszczając go z ramki danych, aby przypisać pozostałe kolumny X w .drop() metoda:

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

Po podzieleniu danych na atrybuty i etykiety możemy dalej podzielić je na zbiory pociągów i testów. Można to zrobić ręcznie, ale np model_selection biblioteka Scikit-Learn zawiera train_test_split() metoda pozwalająca na losowy podział danych na zbiory pociągów i testy.

Aby z niego skorzystać, możemy zaimportować bibliotekę, wywołać train_test_split() sposób, podaj X i y dane i zdefiniuj a test_size uchodzić za argument. W tym przypadku zdefiniujemy to jako 0.20– oznacza to, że 20% danych zostanie wykorzystanych do testowania, a pozostałe 80% do treningu.

Ta metoda losowo pobiera próbki zgodnie z określonym przez nas procentem, ale szanuje pary Xy, aby próbkowanie całkowicie nie pomieszało relacji.

Ponieważ proces próbkowania jest z natury losowy, zawsze będziemy mieć różne wyniki podczas uruchamiania metody. Aby móc uzyskać takie same wyniki lub powtarzalne wyniki, możemy zdefiniować stałą o nazwie SEED o wartości 42.

W tym celu możesz wykonać następujący skrypt:

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)

Zauważ, że train_test_split() metoda już zwraca X_train, X_test, y_train, y_test zestawy w tej kolejności. Możemy wydrukować liczbę próbek rozdzielonych do pociągu i testu, pobierając pierwszy (0) element shape krotka zwrócona przez właściwość:

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

To pokazuje, że istnieje 1097 próbek do uczenia i 275 do testowania.

Trenowanie modelu

Dane podzieliliśmy na zestawy pociągów i zestawy testowe. Teraz nadszedł czas, aby utworzyć i wytrenować model SVM na danych pociągu. Aby to zrobić, możemy zaimportować Scikit-Learn svm biblioteka wraz z Wsparcie klasyfikatora wektorów klasa, lub SVC class.

Po zaimportowaniu klasy możemy utworzyć jej instancję – ponieważ tworzymy prosty model SVM, staramy się rozdzielić nasze dane liniowo, aby można było narysować linię dzielącą nasze dane – co jest równoważne użyciu funkcja liniowa – definiując kernel='linear' jako argument klasyfikatora:

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

W ten sposób klasyfikator spróbuje znaleźć funkcję liniową rozdzielającą nasze dane. Po utworzeniu modelu wytrenujmy go lub dopasować to, z danymi pociągu, wykorzystując fit() metoda i podanie X_train cechy i funkcje y_train cele jako argumenty.

Możemy wykonać następujący kod w celu nauczenia modelu:

svc.fit(X_train, y_train)

Tak po prostu model jest szkolony. Do tej pory zrozumieliśmy dane, podzieliliśmy je, stworzyliśmy prosty model SVM i dopasowaliśmy model do danych pociągu.

Następnym krokiem jest zrozumienie, jak dobrze to dopasowanie udało się opisać nasze dane. Innymi słowy, aby odpowiedzieć, czy liniowa SVM była odpowiednim wyborem.

Dokonywanie prognoz

Sposobem na odpowiedź, czy modelowi udało się opisać dane, jest obliczenie i przyjrzenie się pewnej klasyfikacji metryka.

Biorąc pod uwagę, że nauka jest nadzorowana, możemy przewidywać X_test i porównaj te wyniki przewidywań – które możemy nazwać y_pred – z faktycznym y_testlub podstawowa prawda.

Aby przewidzieć niektóre dane, model predict() metoda może być zastosowana. Ta metoda otrzymuje cechy testowe, X_test, jako argument i zwraca prognozę 0 lub 1 dla każdego z nich X_testrzędy.

Po przewidzeniu X_test danych, wyniki są przechowywane w y_pred zmienny. Tak więc każda z klas przewidywanych za pomocą prostego liniowego modelu SVM jest teraz w y_pred zmienna.

To jest kod przewidywania:

y_pred = svc.predict(X_test)

Biorąc pod uwagę, że mamy prognozy, możemy teraz porównać je z rzeczywistymi wynikami.

Ocena modelu

Istnieje kilka sposobów porównywania przewidywań z rzeczywistymi wynikami, które mierzą różne aspekty klasyfikacji. Niektóre najczęściej używane metryki klasyfikacji to:

  1. Macierz zamieszania: kiedy musimy wiedzieć, ile próbek otrzymaliśmy dobrze lub źle kazda klasa. Wartości, które były poprawne i poprawnie przewidziane, nazywane są prawdziwe pozytywy, nazywane są te, które były przewidywane jako dodatnie, ale nie były dodatnie fałszywe alarmy. Ta sama nomenklatura prawdziwe negatywy i fałszywe negatywy służy do wartości ujemnych;

  2. Detaliczność: gdy naszym celem jest zrozumienie, jakie prawidłowe wartości predykcji zostały uznane przez nasz klasyfikator za prawidłowe. Precyzja podzieli te prawdziwie dodatnie wartości przez próbki, które przewidywano jako dodatnie;

$$
precyzja = frac{tekst{prawdziwe trafienia}}{tekst{prawdziwe trafienia} + tekst{fałszywe trafienia}}
$$

  1. Odwołanie: często obliczane wraz z precyzją, aby zrozumieć, ile prawdziwych pozytywów zostało zidentyfikowanych przez nasz klasyfikator. Wycofanie jest obliczane poprzez podzielenie prawdziwych pozytywów przez wszystko, co powinno być przewidywane jako pozytywne.

$$
przywołaj = frac{tekst{prawdziwe pozytywy}}{tekst{prawdziwie pozytywy} + tekst{fałszywie pozytywy}}
$$

  1. Wynik F1: czy zrównoważony lub Średnia harmoniczna precyzji i przypomnienia. Najniższa wartość to 0, a najwyższa to 1. Kiedy f1-score jest równy 1, oznacza to, że wszystkie klasy zostały poprawnie przewidziane – jest to bardzo trudny wynik do uzyskania na rzeczywistych danych (wyjątki prawie zawsze istnieją).

$$
tekst{f1-score} = 2* frac{tekst{precyzja} * tekst{przypomnij}}{tekst{precyzja} + tekst{przypomnij}}
$$

Zapoznaliśmy się już z miarami matrycy dezorientacji, precyzji, pamięci i wyniku F1. Aby je obliczyć, możemy zaimportować Scikit-Learn metrics biblioteka. Ta biblioteka zawiera tzw classification_report i confusion_matrix metod, metoda raportu klasyfikacji zwraca precyzję, powtarzalność i wynik f1. Obydwa classification_report i confusion_matrix można łatwo wykorzystać do znalezienia wartości dla wszystkich tych ważnych metryk.

Do obliczenia metryk importujemy metody, wywołujemy je i przekazujemy jako argumenty przewidywane klasyfikacje, y_testoraz etykiety klasyfikacyjne lub y_true.

Aby lepiej zobrazować macierz zamieszania, możemy wykreślić ją w Seaborn's heatmap wraz z adnotacjami ilościowymi, a dla raportu klasyfikacyjnego najlepiej wydrukować jego wynik, aby jego wyniki były sformatowane. To jest następujący kod:

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

Wyświetla:

 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

Implementacja SVM i Kernel SVM za pomocą Pythona Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

W raporcie klasyfikacyjnym wiemy, że dokładność 0.99, zapamiętanie 0.99 i wynik f1 0.99 dla sfałszowanych banknotów, czyli klasa 0. Pomiary te uzyskano przy użyciu 148 próbek, jak pokazano w kolumnie pomocniczej. Tymczasem dla klasy 1, czyli prawdziwych notatek, wynik był o jedną jednostkę niższy, 0.98 precyzji, 0.98 przypomnienia i ten sam wynik f1. Tym razem do uzyskania tych wyników wykorzystano 127 pomiarów obrazu.

Jeśli spojrzymy na macierz zamieszania, możemy również zobaczyć, że ze 148 próbek klasy 0 146 zostało poprawnie sklasyfikowanych i były 2 wyniki fałszywie pozytywne, podczas gdy dla 127 próbek klasy 1 były 2 wyniki fałszywie negatywne i 125 prawdziwie dodatnie.

Możemy przeczytać raport klasyfikacyjny i macierz zamieszania, ale co one oznaczają?

Interpretowanie wyników

Aby poznać znaczenie, spójrzmy na wszystkie dane razem wzięte.

Prawie wszystkie próbki do klasy 1 zostały poprawnie sklasyfikowane, w naszym modelu wystąpiły 2 błędy podczas identyfikacji rzeczywistych banknotów. To tyle samo, co 0.98 lub 98% przypomnienia. Coś podobnego można powiedzieć o klasie 0, tylko 2 próbki zostały sklasyfikowane nieprawidłowo, podczas gdy 148 to prawdziwie negatywy, co daje w sumie 99% precyzję.

Oprócz tych wyników, wszystkie inne oznaczają 0.99, czyli prawie 1, bardzo wysoki wskaźnik. W większości przypadków, gdy tak wysoka metryka ma miejsce w przypadku rzeczywistych danych, może to oznaczać, że model jest nadmiernie dostosowany do danych lub przesadnie dopasowany.

W przypadku nadmiernego dopasowania model może dobrze działać podczas przewidywania danych, które są już znane, ale traci możliwość uogólniania na nowe dane, co jest ważne w rzeczywistych scenariuszach.

Szybki test, aby dowiedzieć się, czy występuje przeuczenie, jest również z danymi pociągu. Jeśli model w pewnym stopniu zapamiętał dane pociągu, metryki będą bardzo bliskie 1 lub 100%. Pamiętaj, że dane pociągu są większe niż dane testowe – z tego powodu – spróbuj spojrzeć na to proporcjonalnie, więcej próbek, większe prawdopodobieństwo popełnienia błędów, chyba że doszło do przeuczenia.

Aby przewidzieć z danymi pociągu, możemy powtórzyć to, co zrobiliśmy dla danych testowych, ale teraz z 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))

To daje:

 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

Implementacja SVM i Kernel SVM za pomocą Pythona Scikit-Learn PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Łatwo zauważyć, że występuje nadmierne dopasowanie, gdy metryki pociągu wynoszą 99%, gdy ma się 4 razy więcej danych. Co można zrobić w tym scenariuszu?

Aby odwrócić nadmierne dopasowanie, możemy dodać więcej obserwacji pociągów, zastosować metodę uczenia z różnymi częściami zbioru danych, takimi jak walidacja krzyżowa, a także zmienić domyślne parametry, które już istnieją przed treningiem, podczas tworzenia naszego modelu lub hiperparametry. W większości przypadków Scikit-learn ustawia niektóre parametry jako domyślne i może to nastąpić po cichu, jeśli nie ma zbyt wiele czasu na czytanie dokumentacji.

Możesz sprawdzić drugą część tego przewodnika (wkrótce!), aby zobaczyć, jak zaimplementować walidację krzyżową i przeprowadzić dostrajanie hiperparametrów.

Wnioski

W tym artykule zbadaliśmy prostą SVM z liniowym jądrem. Poznaliśmy intuicję stojącą za algorytmem SVM, wykorzystaliśmy prawdziwy zbiór danych, zbadaliśmy dane i zobaczyliśmy, jak te dane można wykorzystać wraz z SVM, implementując je w bibliotece Scikit-Learn Pythona.

Aby ćwiczyć, możesz wypróbować inne rzeczywiste zestawy danych dostępne w miejscach takich jak Kaggle, UCI, Publiczne zbiory danych Big Query, uniwersytety i strony rządowe.

Sugerowałbym również zbadanie rzeczywistej matematyki stojącej za modelem SVM. Chociaż niekoniecznie będziesz go potrzebować, aby korzystać z algorytmu SVM, nadal bardzo przydatna jest wiedza o tym, co faktycznie dzieje się za kulisami, gdy algorytm znajduje granice decyzyjne.

Znak czasu:

Więcej z Nadużycie stosu