Zrozumienie hiperparametrów SVM

Zrozumienie hiperparametrów SVM

Wprowadzenie

Ten przewodnik jest drugą częścią trzech przewodników dotyczących maszyn wektorów nośnych (SVM). W tym przewodniku będziemy dalej pracować nad przypadkiem użycia sfałszowanych banknotów, zrozumiemy, jakie parametry SVM są już ustawiane przez Scikit-learn, czym są hiperparametry C i Gamma oraz jak je dostroić za pomocą walidacji krzyżowej i wyszukiwania siatki.

W pełnej serii poradników SVM, oprócz hiperparametrów SVM, poznasz również prostą SVM, koncepcję zwaną sztuczka z jądremi poznaj inne typy maszyn SVM.

Jeśli chcesz przeczytać wszystkie poradniki, zajrzeć do pierwszego poradnika 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

  • 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

Nauczmy się, jak zaimplementować walidację krzyżową i przeprowadzić strojenie hiperparametrów.

Hiperparametry SVM

Aby zobaczyć wszystkie parametry modelu, które zostały już ustawione przez Scikit-learn i jego wartości domyślne, możemy użyć get_params() metoda:

svc.get_params()

Ta metoda wyświetla:

{'C': 1.0, 'break_ties': False, 'cache_size': 200, 'class_weight': None, 'coef0': 0.0, 'decision_function_shape': 'ovr', 'degree': 3, 'gamma': 'scale', 'kernel': 'linear', 'max_iter': -1, 'probability': False, 'random_state': None, 'shrinking': True, 'tol': 0.001, 'verbose': False}

Zauważ, że jest już ustawionych łącznie 15 hiperparametrów, dzieje się tak, ponieważ algorytm SVM ma wiele odmian. Użyliśmy jądra liniowego, aby otrzymać funkcję liniową, ale są też jądra, które opisują inne rodzaje funkcji i te jądra są sparametryzowane na różne sposoby.

Te odmiany sprawiają, że model jest bardziej elastyczny i odpowiedni do znajdowania separacji między różnymi kształtami danych. Jeśli możemy narysować linię oddzielającą nasze klasy, to a jądro liniowe będzie dobrym rozwiązaniem, jeśli potrzebujemy krzywej, to a wielomian kernel może być najlepszym wyborem, jeśli nasze dane mają okrągłe kształty, to a Radialna funkcja bazowa or RBF jądro będzie lepiej pasować do danych, jeśli istnieją wartości powyżej i poniżej progu, a esicy kernel może lepiej rozdzielać klasy. Z tego, co zbadaliśmy w naszych danych, wydaje się, że jądro RBF lub wielomianowe byłoby bardziej odpowiednie niż jądro liniowe.

Teraz, gdy wiemy, że istnieją 4 rodzaje różnych funkcji jądra, możemy wrócić do parametrów. Kiedy algorytm SVM próbuje znaleźć separację między klasami, zrozumieliśmy już, że rysuje klasyfikację margines między wektorami nośnymi a linią separacji (lub krzywą).

Margines ten jest w pewnym sensie buforem między linią separacji a punktami. Rozmiar marginesu może się różnić, gdy margines jest mniejszy, jest mniej miejsca na punkty, które wykraczają poza margines, dzięki czemu separacja między klasami jest wyraźniejsza, dlatego pobieranych jest więcej próbek poprawnie sklasyfikowany, odwrotnie, gdy margines jest większe, separacja między klasami jest mniej wyraźna i może być więcej próbek błędnie sklasyfikowany. Innymi słowy, mniejszy margines oznacza lepiej sklasyfikowane próbki, a także więcej sztywny klasyfikator, podczas gdy większy margines oznacza więcej błędnie sklasyfikowanych próbek, ale więcej elastyczne klasyfikator.

Po wybraniu tych marginesów parametrem, który je określa, jest C parametr.

Hiperparametr C

Połączenia C parametr jest odwrotnie proporcjonalny do rozmiaru marginesu, oznacza to, że większe wartość CThe mniejszy margines i odwrotnie mniejszy wartość CThe większe Margines. The C parametr może być używany wraz z dowolnym jądrem, mówi algorytmowi, jak bardzo uniknąć błędnej klasyfikacji każdej próbki treningowej, z tego powodu jest również znany jako regularyzacja. Nasz SVM z liniowym jądrem wykorzystał plik C 1.0, czyli a duży wartość i daje a mniejszy margines.

Zrozumienie hiperparametrów SVM PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Możemy poeksperymentować z mniejszy wartość „C” i zrozumieć w praktyce, co dzieje się z a większy margines. W tym celu utworzymy nowy klasyfikator, svc_ci zmienić tylko wartość C do 0.0001. Powtórzmy też fit i predict kroki:

svc_c = SVC(kernel='linear', C=0.0001)
svc_c.fit(X_train, y_train)
y_pred_c = svc_c.predict(X_test)

Teraz możemy spojrzeć na wyniki dla danych testowych:

print(classification_report(y_test, y_pred_c)) cm_c = confusion_matrix(y_test, y_pred_c)
sns.heatmap(cm_c, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with C=0.0001')

To daje:

 precision recall f1-score support 0 0.82 0.96 0.88 148 1 0.94 0.76 0.84 127 accuracy 0.87 275 macro avg 0.88 0.86 0.86 275
weighted avg 0.88 0.87 0.86 275

Zrozumienie hiperparametrów SVM PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Używając mniejszego C i uzyskując większy margines, klasyfikator stał się bardziej elastyczny i popełnia więcej błędów klasyfikacyjnych. W raporcie klasyfikacyjnym widzimy, że f1-score, poprzednio 0.99 dla obu klas, spadło do 0.88 dla klasy 0 i do 0.84 dla klasy 1. W macierzy zamieszania model przeszedł od 2 do 6 wyników fałszywie dodatnich i od 2 do 31 wyników fałszywie ujemnych.

Możemy też powtórzyć predict krok i spójrz na wyniki, aby sprawdzić, czy nadal występuje przetrenowanie podczas korzystania z danych pociągu:

y_pred_ct = svc_c.predict(X_train) cm_ct = confusion_matrix(y_train, y_pred_ct)
sns.heatmap(cm_ct, annot=True, fmt='d').set_title('Confusion matrix of linear SVM with C=0.0001 and train data') print(classification_report(y_train, y_pred_ct))

To skutkuje:

 precision recall f1-score support 0 0.88 0.96 0.92 614 1 0.94 0.84 0.88 483 accuracy 0.90 1097 macro avg 0.91 0.90 0.90 1097
weighted avg 0.91 0.90 0.90 1097

Zrozumienie hiperparametrów SVM PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Patrząc na wyniki z mniejszym C i dane pociągu, widzimy poprawę w przeuczeniu, ale gdy większość metryk jest nadal wyższa dla danych pociągu, wydaje się, że przeuczenie nie zostało rozwiązane. Więc wystarczy zmienić C parametr nie wystarczył, aby uelastycznić model i poprawić jego uogólnienie.

Note: Próba znalezienia równowagi między funkcją, która jest zbyt daleko od danych, jest zbyt stała lub ma wysokie nastawienie lub odwrotnie, funkcja pasuje do bliskości danych, jest zbyt elastyczna lub ma duża wariancja jest zwykle określany jako wymiana odchyleń wariancji. Znalezienie tej równowagi nie jest trywialne, ale kiedy już zostanie osiągnięte, nie dochodzi do niedopasowania lub nadmiernego dopasowania modelu do danych. Aby zmniejszyć wariancję i zapobiec nadmiernemu dopasowaniu, dane można równomiernie zmniejszyć, aby były bardziej regularne i uproszczone podczas uzyskiwania opisującej je funkcji. O to chodzi w parametrze C robi, gdy jest używany w SVM, z tego powodu jest również nazywany Regularyzacja L2 or Regresja Ridge.

Do tego momentu rozumieliśmy marginesy w SVM i ich wpływ na ogólny wynik algorytmu, ale co z linią (lub krzywą) oddzielającą klasy? Ta linia jest granica decyzji. Skoro więc wiemy już, że marginesy mają wpływ na elastyczność granicy decyzyjnej wobec błędów, możemy teraz przyjrzeć się kolejnemu parametrowi, który również wpływa na granicę decyzyjną.

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!

Note: Granicę decyzyjną można również nazwać a hiperpłaszczyzna. Hiperpłaszczyzna jest pojęciem geometrycznym odnoszącym się do liczby wymiarów przestrzeni minus jeden (dims-1). Jeśli przestrzeń jest dwuwymiarowa, na przykład płaszczyzna o współrzędnych x i y, jednowymiarowe linie (lub krzywe) są hiperpłaszczyznami. W kontekście uczenia maszynowego, ponieważ liczba kolumn używanych w modelu to jego wymiary płaszczyzny, kiedy pracujemy z 2 kolumnami i klasyfikatorem SVM, znajdujemy trójwymiarową hiperpłaszczyznę, która rozdziela klasy.

Hiperparametr Gamma

Można wybrać nieskończone granice decyzyjne, niektóre z tych granic rozdzielą klasy, a inne nie. Czy przy wyborze efektywnej granicy decyzyjnej należy wziąć pod uwagę pierwszych 10 najbliższych punktów każdej klasy? A może należy wziąć pod uwagę więcej punktów, w tym punkty, które są daleko? W SVM ten wybór zakresu jest zdefiniowany przez inny hiperparametr, gamma.

Jak C, gamma jest nieco odwrotnie proporcjonalna do jego odległości. The wyższy jego wartość, tj najbliższy to punkty, które są brane pod uwagę jako granica decyzyjna, a najniższy dotychczasowy gammaThe dalej punkty są również brane pod uwagę przy wyborze granicy decyzyjnej.

Zrozumienie hiperparametrów SVM PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

Innym wpływem gammy jest to, że im wyższa jej wartość, tym bardziej zakres granicy decyzyjnej zbliża się do otaczających ją punktów, czyniąc ją bardziej postrzępioną i podatną na nadmierne dopasowanie – a im niższa jej wartość, tym gładsza i regularniejsza granica decyzyjna powierzchnia staje się również mniej podatna na nadmierne dopasowanie. Dotyczy to każdej hiperpłaszczyzny, ale można to łatwiej zaobserwować, rozdzielając dane w wyższych wymiarach. W niektórych dokumentach gamma może być również określany jako sigma.

Zrozumienie hiperparametrów SVM PlatoBlockchain Data Intelligence. Wyszukiwanie pionowe. AI.

W przypadku naszego modelu domyślna wartość gamma była scale. Jak widać w Scikit-learn dokumentacja SVC, to znaczy, że jego wartość wynosi:

$$
gamma = (1/ tekst{n_cech} * X.var())
$$

or

$$
gamma = (1/ tekst{liczba_cech} * tekst{wariant_cech})
$$

W naszym przypadku musimy obliczyć wariancję X_train, pomnóż przez 4 i podziel wynik przez 1. Możemy to zrobić za pomocą następującego kodu:

number_of_features = X_train.shape[1] features_variance = X_train.values.var()
gamma = 1/(number_of_features * features_variance)
print('gamma:', gamma)

To daje:

gamma: 0.013924748072859962

Istnieje również inny sposób spojrzenia na wartość gamma, uzyskując dostęp do obiektu klasyfikatora gamma parametr z ._gamma:

svc._gamma 

Widzimy, że gamma użyty w naszym klasyfikatorze był niski, więc uwzględniał również bardziej oddalone punkty.

Note: Jak widzieliśmy, C i gamma są ważne dla niektórych definicji modelu. Kolejny hiperparametr, random_state, jest często używany w Scikit Learn, aby zagwarantować tasowanie danych lub losowe źródło dla modeli, więc zawsze mamy te same wyniki, ale jest to trochę inne w przypadku SVM. W szczególności random_state ma implikacje tylko wtedy, gdy inny hiperparametr, probability, jest ustawione na true. Dzieje się tak, ponieważ tasuje dane w celu uzyskania szacunków prawdopodobieństwa. Jeśli nie chcemy oszacowań prawdopodobieństwa dla naszych klas, a prawdopodobieństwo jest ustawione na fałsz, SVM's random_state parametr nie ma wpływu na wyniki modelu.

Nie ma reguły, jak dobierać wartości dla hiperparametrów, takich jak C i gamma – będzie to zależeć od tego, jak długo i jakie zasoby są dostępne do eksperymentowania z różnymi wartościami hiperparametrów, jakie transformacje można wykonać w danych i jakich wyników się oczekuje . Zwykłym sposobem wyszukiwania wartości hiperparametrów jest połączenie każdej z proponowanych wartości przez a wyszukiwanie w sieci wraz z procedurą, która stosuje te wartości hiperparametrów i uzyskuje metryki dla różnych części wywoływanych danych walidacja krzyżowa. W Scikit-learn jest to już zaimplementowane jako GridSearchCV (CV z walidacji krzyżowej).

Aby uruchomić wyszukiwanie w siatce z weryfikacją krzyżową, musimy zaimportować plik GridSearchCV, zdefiniuj słownik z wartościami hiperparametrów, z którymi będziemy eksperymentować, takimi jak typ kernel, zakres dla C, A na gamma, utwórz instancję pliku SVC, zdefiniuj score lub metryka zostanie użyta do oceny (tutaj wybierzemy optymalizację zarówno pod kątem precyzji, jak i zapamiętania, więc użyjemy f1-score), liczba podziałów, które zostaną wykonane w danych do uruchomienia wyszukiwania cv – domyślnie jest to 5, ale dobrą praktyką jest użycie co najmniej 10 – tutaj użyjemy 5 fałd danych, aby było to bardziej przejrzyste podczas porównywania wyników.

Połączenia GridSearchCV ma fit metoda, która odbiera nasze dane o pociągu i dalej dzieli je na pociągi i zestawy testowe w celu walidacji krzyżowej. Możemy ustawić return_train_score na true, aby porównać wyniki i zagwarantować, że nie ma nadmiernego dopasowania.

To jest kod wyszukiwania siatki z weryfikacją krzyżową:

from sklearn.model_selection import GridSearchCV parameters_dictionary = {'kernel':['linear', 'rbf'], 'C':[0.0001, 1, 10], 'gamma':[1, 10, 100]}
svc = SVC() grid_search = GridSearchCV(svc, parameters_dictionary, scoring = 'f1', return_train_score=True, cv = 5, verbose = 1) grid_search.fit(X_train, y_train)

Ten kod wyświetla:

Fitting 5 folds for each of 18 candidates, totalling 90 fits
# and a clickable GridSeachCV object schema

Po przeprowadzeniu wyszukiwania hiperparametrów możemy użyć metody best_estimator_, best_params_ i best_score_ właściwości w celu uzyskania najlepszego modelu, wartości parametrów i najwyższego wyniku f1:

best_model = grid_search.best_estimator_
best_parameters = grid_search.best_params_
best_f1 = grid_search.best_score_ print('The best model was:', best_model)
print('The best parameter values were:', best_parameters)
print('The best f1-score was:', best_f1)

To skutkuje:

The best model was: SVC(C=1, gamma=1)
The best parameter values were: {'C': 1, 'gamma': 1, 'kernel': 'rbf'}
The best f1-score was: 0.9979166666666666

Potwierdzając nasze wstępne przypuszczenia na podstawie danych, najlepszy model nie ma liniowego jądra, ale nieliniowe, RBF.

Rada: podczas dalszych badań interesujące jest uwzględnienie większej liczby nieliniowych jąder w wyszukiwaniu siatki.

Obie C i gamma mają wartość 1, a f1-score jest bardzo wysoki, 0.99. Ponieważ wartość jest wysoka, sprawdźmy, czy wystąpiło nadmierne dopasowanie, zerkając na średnie wyniki testu i pociągu, które zwróciliśmy, wewnątrz cv_results_ obiekt:

gs_mean_test_scores = grid_search.cv_results_['mean_test_score']
gs_mean_train_scores = grid_search.cv_results_['mean_train_score'] print("The mean test f1-scores were:", gs_mean_test_scores)
print("The mean train f1-scores were:", gs_mean_train_scores)

Średnie wyniki były następujące:

The mean test f1-scores were: [0.78017291 0. 0.78017291 0. 0.78017291 0. 0.98865407 0.99791667 0.98865407 0.76553515 0.98865407 0.040291 0.98656 0.99791667 0.98656 0.79182565 0.98656 0.09443985] The mean train f1-scores were: [0.78443424 0. 0.78443424 0. 0.78443424 0. 0.98762683 1. 0.98762683 1. 0.98762683 1. 0.98942923 1. 0.98942923 1. 0.98942923 1. ]

Patrząc na średnie wyniki, możemy zobaczyć, że najwyższy z nich, 0.99791667, pojawia się dwukrotnie iw obu przypadkach wynik w danych pociągu wynosił 1. Oznacza to, że nadmierne dopasowanie się utrzymuje. Odtąd warto byłoby wrócić do przygotowania danych i zrozumieć, czy normalizacja danych, dokonanie innego rodzaju transformacji danych, a także tworzenie nowych funkcji za pomocą inżynierii funkcji ma sens.

Właśnie widzieliśmy technikę znajdowania hiperparametrów modelu i wspomnieliśmy już coś o liniowej separowalności, wektorach nośnych, granicy decyzyjnej, maksymalizacji marginesów i sztuczce jądra. SVM jest złożonym algorytmem, zwykle obejmującym wiele koncepcji matematycznych i małych części, które można modyfikować, które należy dostosować, aby tworzyły całość.

Połączmy to, co widzieliśmy do tej pory, podsumujmy, jak działają wszystkie części SVM, a następnie przyjrzyjmy się niektórym innym implementacjom jądra wraz z ich wynikami.

Wnioski

W tym artykule poznaliśmy domyślne parametry implementacji SVM w Scikit-Learn. Zrozumieliśmy, czym są parametry C i Gamma oraz jak zmiana każdego z nich może wpłynąć na model SVM.

Nauczyliśmy się również wyszukiwania siatki w celu znalezienia najlepszych wartości C i Gamma oraz stosowania walidacji krzyżowej w celu lepszego uogólnienia naszych wyników i zagwarantowania, że ​​nie ma żadnej formy wycieku danych.

Wykonywanie strojenia hiperparametrów za pomocą wyszukiwania siatki i walidacji krzyżowej jest powszechną praktyką w data science, dlatego zdecydowanie sugeruję wdrożenie technik, uruchomienie kodu i zobaczenie powiązań między wartościami hiperparametrów a zmianami w przewidywaniach SVM.

Znak czasu:

Więcej z Nadużycie stosu