Maszyna wektorów nośnych lub SVM to jeden z najpopularniejszych algorytmów uczenia się nadzorowanego, używany do rozwiązywania problemów związanych z klasyfikacją i regresją. Jednak przede wszystkim służy do rozwiązywania problemów klasyfikacyjnych w uczeniu maszynowym.
Celem algorytmu SVM jest utworzenie najlepszej linii lub granicy decyzyjnej, która może podzielić przestrzeń n-wymiarową na klasy, abyśmy mogli w przyszłości łatwo umieścić nowy punkt danych we właściwej kategorii. Ta granica najlepszej decyzji nazywana jest hiperpłaszczyzną.
SVM wybiera skrajne punkty/wektory, które pomagają w utworzeniu hiperpłaszczyzny. Te skrajne przypadki nazywane są wektorami nośnymi, a zatem algorytm jest określany jako maszyna wektorów nośnych. Rozważ poniższy diagram, na którym istnieją dwie różne kategorie sklasyfikowane przy użyciu granicy decyzyjnej lub hiperpłaszczyzny:
Przykład: SVM można zrozumieć na przykładzie, który wykorzystaliśmy w klasyfikatorze KNN. Załóżmy, że widzimy dziwnego kota, który ma również pewne cechy psa, więc jeśli chcemy modelu, który będzie w stanie dokładnie zidentyfikować, czy jest to kot czy pies, to taki model można stworzyć za pomocą algorytmu SVM. Najpierw wytrenujemy nasz model za pomocą wielu zdjęć kotów i psów, aby mógł poznać różne cechy kotów i psów, a następnie przetestujemy go z tym dziwnym stworzeniem. Tak więc, gdy wektor wsparcia tworzy granicę decyzyjną pomiędzy tymi dwoma danymi (kot i pies) i wybiera ekstremalne przypadki (wektory wsparcia), zobaczy ekstremalny przypadek kota i psa. Na podstawie wektorów nośnych zaklasyfikuje go jako kota. Rozważ poniższy diagram:
Można zastosować algorytm SVM Detekcja twarzy, klasyfikacja obrazu, kategoryzacja tekstu, itp.
regexp_like w mysql
Rodzaje SVM
SVM może być dwojakiego rodzaju:
Hiperpłaszczyzna i wektory podporowe w algorytmie SVM:
Hiperpłaszczyzna: Może istnieć wiele linii/granic decyzyjnych segregujących klasy w przestrzeni n-wymiarowej, ale musimy znaleźć najlepszą granicę decyzyjną, która pomoże sklasyfikować punkty danych. Ta najlepsza granica znana jest jako hiperpłaszczyzna SVM.
Wymiary hiperpłaszczyzny zależą od cech występujących w zbiorze danych, co oznacza, że jeśli istnieją 2 cechy (jak pokazano na rysunku), to hiperpłaszczyzna będzie linią prostą. A jeśli są 3 cechy, to hiperpłaszczyzna będzie płaszczyzną 2-wymiarową.
Zawsze tworzymy hiperpłaszczyznę, która ma maksymalny margines, co oznacza maksymalną odległość między punktami danych.
Wektory wsparcia:
Punkty danych lub wektory znajdujące się najbliżej hiperpłaszczyzny i wpływające na położenie hiperpłaszczyzny nazywane są wektorami nośnymi. Ponieważ wektory te wspierają hiperpłaszczyznę, stąd nazywane są wektorami wsparcia.
Jak działa SVM?
Liniowy SVM:
Działanie algorytmu SVM można zrozumieć na przykładzie. Załóżmy, że mamy zbiór danych zawierający dwa znaczniki (zielony i niebieski), a zbiór danych ma dwie cechy x1 i x2. Potrzebujemy klasyfikatora, który może sklasyfikować parę (x1, x2) współrzędnych w kolorze zielonym lub niebieskim. Rozważ poniższy obraz:
Ponieważ jest to przestrzeń dwuwymiarowa, więc używając linii prostej, możemy łatwo oddzielić te dwie klasy. Ale może istnieć wiele linii oddzielających te klasy. Rozważ poniższy obraz:
Dlatego algorytm SVM pomaga znaleźć najlepszą linię lub granicę decyzyjną; ta najlepsza granica lub region nazywa się a hiperpłaszczyzna . Algorytm SVM znajduje najbliższy punkt linii obu klas. Punkty te nazywane są wektorami nośnymi. Odległość między wektorami a hiperpłaszczyzną nazywa się jako margines . Celem SVM jest maksymalizacja tej marży. The hiperpłaszczyzna z maksymalną marżą nazywa się optymalna hiperpłaszczyzna .
Nieliniowy SVM:
Jeśli dane są ułożone liniowo, to możemy je rozdzielić linią prostą, natomiast w przypadku danych nieliniowych nie możemy narysować ani jednej linii prostej. Rozważ poniższy obraz:
Aby oddzielić te punkty danych, musimy dodać jeszcze jeden wymiar. W przypadku danych liniowych użyliśmy dwóch wymiarów x i y, więc w przypadku danych nieliniowych dodamy trzeci wymiar z. Można to obliczyć jako:
z=x<sup>2</sup> +y<sup>2</sup>
Po dodaniu trzeciego wymiaru przestrzeń próbna będzie wyglądać jak na obrazku poniżej:
Zatem teraz SVM podzieli zbiory danych na klasy w następujący sposób. Rozważ poniższy obraz:
Ponieważ jesteśmy w przestrzeni 3-d, wygląda to jak płaszczyzna równoległa do osi x. Jeśli przekształcimy to w przestrzeń 2d z z=1, wówczas będzie to wyglądało następująco:
pytania do rozmowy kwalifikacyjnej w języku Java
Stąd otrzymujemy obwód o promieniu 1 w przypadku danych nieliniowych.
Implementacja maszyny wektorów nośnych w języku Python
Teraz zaimplementujemy algorytm SVM przy użyciu języka Python. Tutaj użyjemy tego samego zestawu danych dane użytkownika , które wykorzystaliśmy w regresji logistycznej i klasyfikacji KNN.
Do etapu wstępnego przetwarzania danych kod pozostanie taki sam. Poniżej znajduje się kod:
#Data Pre-processing Step # importing libraries import numpy as nm import matplotlib.pyplot as mtp import pandas as pd #importing datasets data_set= pd.read_csv('user_data.csv') #Extracting Independent and dependent Variable x= data_set.iloc[:, [2,3]].values y= data_set.iloc[:, 4].values # Splitting the dataset into training and test set. from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test= train_test_split(x, y, test_size= 0.25, random_state=0) #feature Scaling from sklearn.preprocessing import StandardScaler st_x= StandardScaler() x_train= st_x.fit_transform(x_train) x_test= st_x.transform(x_test)
Po wykonaniu powyższego kodu dokonamy wstępnego przetworzenia danych. Kod poda zestaw danych jako:
Skalowany wynik dla zestawu testowego będzie następujący:
Dopasowanie klasyfikatora SVM do zbioru uczącego:
Teraz zbiór uczący zostanie dopasowany do klasyfikatora SVM. Aby utworzyć klasyfikator SVM, zaimportujemy SVC klasa od Sklearn.svm biblioteka. Poniżej znajduje się jego kod:
from sklearn.svm import SVC # 'Support vector classifier' classifier = SVC(kernel='linear', random_state=0) classifier.fit(x_train, y_train)
W powyższym kodzie użyliśmy jądro='liniowe' , ponieważ tutaj tworzymy SVM dla danych separowanych liniowo. Możemy to jednak zmienić dla danych nieliniowych. Następnie dopasowaliśmy klasyfikator do zbioru danych uczących (x_train, y_train)
Wyjście:
Out[8]: SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0, decision_function_shape='ovr', degree=3, gamma='auto_deprecated', kernel='linear', max_iter=-1, probability=False, random_state=0, shrinking=True, tol=0.001, verbose=False)
Wydajność modelu można zmienić, zmieniając wartość C (współczynnik regularyzacji), gamma i jądro .
Teraz przewidzimy wynik dla zestawu testowego. W tym celu utworzymy nowy wektor y_pred. Poniżej znajduje się jego kod:
#Predicting the test set result y_pred= classifier.predict(x_test)
Po otrzymaniu wektora y_pred możemy porównać wynik y_pred I y_test aby sprawdzić różnicę pomiędzy wartością rzeczywistą a wartością przewidywaną.
Wyjście: Poniżej znajduje się wynik przewidywania zbioru testowego:
alternatywa dla xamppa
Teraz zobaczymy, jak klasyfikator SVM radzi sobie z liczbą błędnych przewidywań w porównaniu z klasyfikatorem regresji logistycznej. Aby utworzyć macierz zamieszania, musimy zaimportować plik zamieszanie_matrix funkcja biblioteki sklear. Po zaimportowaniu funkcji wywołamy ją przy użyciu nowej zmiennej cm . Funkcja przyjmuje głównie dwa parametry y_prawda (wartości rzeczywiste) i y_pred (wartość docelowa zwrócona przez klasyfikator). Poniżej znajduje się jego kod:
#Creating the Confusion matrix from sklearn.metrics import confusion_matrix cm= confusion_matrix(y_test, y_pred)
Wyjście:
Jak widać na powyższym obrazie wyjściowym, jest 66+24= 90 poprawnych przewidywań i 8+2= 10 poprawnych przewidywań. Można zatem powiedzieć, że nasz model SVM poprawił się w porównaniu z modelem regresji logistycznej.
Teraz zwizualizujemy wynik zestawu treningowego, poniżej znajduje się jego kod:
from matplotlib.colors import ListedColormap x_set, y_set = x_train, y_train x1, x2 = nm.meshgrid(nm.arange(start = x_set[:, 0].min() - 1, stop = x_set[:, 0].max() + 1, step =0.01), nm.arange(start = x_set[:, 1].min() - 1, stop = x_set[:, 1].max() + 1, step = 0.01)) mtp.contourf(x1, x2, classifier.predict(nm.array([x1.ravel(), x2.ravel()]).T).reshape(x1.shape), alpha = 0.75, cmap = ListedColormap(('red', 'green'))) mtp.xlim(x1.min(), x1.max()) mtp.ylim(x2.min(), x2.max()) for i, j in enumerate(nm.unique(y_set)): mtp.scatter(x_set[y_set == j, 0], x_set[y_set == j, 1], c = ListedColormap(('red', 'green'))(i), label = j) mtp.title('SVM classifier (Training set)') mtp.xlabel('Age') mtp.ylabel('Estimated Salary') mtp.legend() mtp.show()
Wyjście:
Wykonując powyższy kod, otrzymamy wynik jako:
Jak widzimy, powyższy wynik wygląda podobnie do wyniku regresji logistycznej. Na wyjściu otrzymaliśmy linię prostą jako hiperpłaszczyznę, ponieważ tak mamy użył jądra liniowego w klasyfikatorze . Omówiliśmy także powyżej, że dla przestrzeni 2d hiperpłaszczyzna w SVM jest linią prostą.
#Visulaizing the test set result from matplotlib.colors import ListedColormap x_set, y_set = x_test, y_test x1, x2 = nm.meshgrid(nm.arange(start = x_set[:, 0].min() - 1, stop = x_set[:, 0].max() + 1, step =0.01), nm.arange(start = x_set[:, 1].min() - 1, stop = x_set[:, 1].max() + 1, step = 0.01)) mtp.contourf(x1, x2, classifier.predict(nm.array([x1.ravel(), x2.ravel()]).T).reshape(x1.shape), alpha = 0.75, cmap = ListedColormap(('red','green' ))) mtp.xlim(x1.min(), x1.max()) mtp.ylim(x2.min(), x2.max()) for i, j in enumerate(nm.unique(y_set)): mtp.scatter(x_set[y_set == j, 0], x_set[y_set == j, 1], c = ListedColormap(('red', 'green'))(i), label = j) mtp.title('SVM classifier (Test set)') mtp.xlabel('Age') mtp.ylabel('Estimated Salary') mtp.legend() mtp.show()
Wyjście:
Wykonując powyższy kod, otrzymamy wynik jako:
Jak widać na powyższym obrazie wyjściowym, klasyfikator SVM podzielił użytkowników na dwa regiony (Kupieni i Niekupieni). Użytkownicy, którzy kupili SUV-a, znajdują się w czerwonym obszarze z czerwonymi punktami rozproszenia. Użytkownicy, którzy nie kupili SUV-a, znajdują się w zielonym obszarze z zielonymi punktami rozproszonymi. Hiperpłaszczyzna podzieliła obie klasy na zmienną Zakupioną i NieKupioną.