Forstå SVM-hyperparametre

Forstå SVM-hyperparametre

Introduksjon

Denne veiledningen er den andre delen av tre guider om Support Vector Machines (SVM). I denne veiledningen vil vi fortsette å jobbe med brukssaken for forfalskede sedler, forstå hvilke SVM-parametere som allerede settes av Scikit-learn, hva er C- og Gamma-hyperparametere, og hvordan du kan justere dem ved å bruke kryssvalidering og rutenettsøk.

I den komplette serien med SVM-guider, i tillegg til SVM-hyperparametre, vil du også lære om enkel SVM, et konsept kalt kjernetriks, og utforske andre typer SVM-er.

Hvis du ønsker å lese alle veiledningene, ta en titt på den første veiledningen, eller se hvilke som interesserer deg mest, nedenfor er tabellen over emner som dekkes i hver veiledning:

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

2. Forstå SVM-hyperparametere

  • C-hyperparameteren
  • Gamma-hyperparameteren

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

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

La oss lære hvordan du implementerer kryssvalidering og utfører en hyperparameterinnstilling.

SVM Hyperparametere

For å se alle modellparametere som allerede er satt av Scikit-learn og standardverdiene, kan vi bruke get_params() metode:

svc.get_params()

Denne metoden viser:

{'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}

Legg merke til at det er totalt 15 hyperparametre som allerede er satt, dette skjer fordi SVM-algoritmen har mange variasjoner. Vi har brukt den lineære kjernen for å få en lineær funksjon, men det finnes også kjerner som beskriver andre typer funksjoner og disse kjernene er parametrisert på forskjellige måter.

Disse variasjonene gjør modellen mer fleksibel og egnet for å finne et skille mellom ulike former for data. Hvis vi kan trekke en linje for å skille klassene våre, så a lineær kjerne vil være et godt alternativ, hvis vi trenger en kurve, så en polynom kjerne kan være det beste valget, hvis dataene våre har sirkulære former, så en Radial basisfunksjon or RBF kjernen vil passe dataene bedre, hvis det er verdier over og under en terskel, en sigmoid kjernen kan skille klassene bedre. Ut fra det vi har utforsket i våre data, ser det ut til at enten en RBF eller en polynom kjerne ville være mer egnet enn en lineær kjerne.

Nå som vi har en ide om at det er 4 typer forskjellige kjernefunksjoner, kan vi gå tilbake til parameterne. Når SVM-algoritmen prøver å finne et skille mellom klasser, har vi allerede forstått at den tegner en klassifisering margin mellom støttevektorene og separasjonslinjen (eller kurven).

Denne marginen er på en måte som en buffer mellom skillelinjen og punktene. Marginstørrelsen kan variere når margen er mindre, er det mindre plass til punkter som faller utenfor margen, noe som gjør skillet mellom klasser klarere, så flere prøver blir riktig klassifisert, omvendt, når marginen er større, skillet mellom klasser er mindre tydelig, og flere prøver kan være feilklassifisert. Med andre ord, en mindre margin betyr mer korrekt klassifiserte prøver, og også en mer rigid klassifiserer, mens en større margin, angir flere feilklassifiserte prøver, men en mer fleksibel klassifiserer.

Når disse margene er valgt, er parameteren som bestemmer dem C parameter.

C-hyperparameteren

De C parameteren er omvendt proporsjonal med marginstørrelsen, dette betyr at større verdien av Cden mindre marginen, og omvendt mindre verdien av Cden større marginen. De C parameter kan brukes sammen med hvilken som helst kjerne, den forteller algoritmen hvor mye den skal unngå feilklassifisering av hver treningsprøve, på grunn av det er den også kjent som regularisering. Vår lineære kjerne SVM har brukt en C på 1.0, som er en stor verdi og gir en mindre margin.

Forstå SVM Hyperparameters PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Vi kan eksperimentere med en mindre verdien av 'C' og forstå i praksis hva som skjer med en større margin. For å gjøre det, vil vi lage en ny klassifisering, svc_c, og endre bare verdien av C til 0.0001. La oss også gjenta fit og predict trinn:

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

Nå kan vi se på resultatene for testdataene:

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

Dette gir utganger:

 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

Forstå SVM Hyperparameters PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Ved å bruke en mindre C og oppnår en større margin, har klassifikatoren blitt mer fleksibel og med flere klassifiseringsfeil. I klassifiseringsrapporten kan vi se at f1-score, tidligere 0.99 for begge klasser, har senket til 0.88 for klasse 0, og til 0.84 for klasse 1. I forvirringsmatrisen gikk modellen fra 2 til 6 falske positive, og fra 2 til 31 falske negative.

Vi kan også gjenta predict trinn og se på resultatene for å sjekke om det fortsatt er overfit når du bruker togdata:

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

Dette resulterer i:

 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

Forstå SVM Hyperparameters PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

Ved å se på resultatene med en mindre C og togdata, kan vi se at det var en forbedring i overfittet, men når de fleste beregningene fortsatt er høyere for togdata, ser det ut til at overfittet ikke er løst. Så det er bare å endre C parameteren var ikke nok til å gjøre modellen mer fleksibel og forbedre generaliseringen.

Merknader: Prøver å finne balanse mellom at en funksjon kommer for langt fra dataene, er for fast eller har høy skjevhet eller det er motsatt, en funksjon som passer til å nærme dataene, er for fleksibel eller har høy varians blir vanligvis referert til som bias varians trade-off. Å finne den balansen er ikke trivielt, men når den er oppnådd, er det ingen undertilpasning eller overtilpasning av modellen til dataene. Som en måte å redusere variansen på og forhindre overtilpasning, kan dataene krympes jevnt for å bli mer regelmessige og forenklet når man får en funksjon som beskriver det. Det er det som er parameteren C gjør når det brukes i SVM, av den grunn kalles det også L2 regulering or Ridge Regresjon.

Frem til dette punktet har vi forstått om marginene i SVM og hvordan de påvirker det samlede resultatet av algoritmen, men hva med linjen (eller kurven) som skiller klassene? Denne linjen er beslutningsgrense. Så vi vet allerede at marginene har en innvirkning på beslutningsgrensens fleksibilitet mot feil, vi kan nå ta en titt på en annen parameter som også påvirker beslutningsgrensen.

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

Merknader: Vedtaksgrensen kan også kalles en hyper. Et hyperplan er et geometrisk konsept for å referere til antall dimensjoner av et rom minus én (dims-1). Hvis rommet er 2-dimensjonalt, for eksempel et plan med x- og y-koordinater, er de 1-dimensjonale linjene (eller kurvene) hyperplanene. I maskinlæringssammenheng, siden antall kolonner som brukes i modellen er dens plandimensjoner, finner vi et 4-dimensjonalt hyperplan som skiller mellom klasser når vi arbeider med 3 kolonner og en SVM-klassifisering.

Gamma-hyperparameteren

Uendelige beslutningsgrenser kan velges, noen av disse grensene vil skille klassene og andre ikke. Når man velger en effektiv beslutningsgrense, bør de første 10 nærmeste punktene i hver klasse vurderes? Eller bør flere punkter vurderes, inkludert punktene som er langt unna? I SVM er dette valget av område definert av en annen hyperparameter, gamma.

I likhet med C, gamma er noe omvendt proporsjonal med avstanden. De høyere dens verdi, den nærmeste er punktene som vurderes for vedtaksgrensen, og de lavest de gammaden lenger poeng vurderes også for valg av vedtaksgrense.

Forstå SVM Hyperparameters PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

En annen effekt av gamma er at jo høyere verdien den har, desto mer kommer omfanget av beslutningsgrensen nærmere punktene rundt den, noe som gjør den mer taggete og utsatt for overfitting – og jo lavest verdien er, jo jevnere og jevnere er beslutningsgrensen. overflaten blir også mindre utsatt for overfitting. Dette er sant for ethvert hyperplan, men kan lettere observeres når du skiller data i høyere dimensjoner. I noen dokumentasjoner, gamma kan også refereres til som sigma.

Forstå SVM Hyperparameters PlatoBlockchain Data Intelligence. Vertikalt søk. Ai.

For vår modell er standardverdien på gamma var scale. Som det kan sees i Scikit-learn SVC-dokumentasjon, betyr det at verdien er:

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

or

$$
gamma = (1/ tekst{number_of_features} * tekst{features_variance})
$$

I vårt tilfelle må vi beregne variansen av X_train, gang det med 4 og del resultatet på 1. Vi kan gjøre dette med følgende kode:

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

Dette gir utganger:

gamma: 0.013924748072859962

Det er også en annen måte å se på verdien av gamma, ved å få tilgang til klassifisererens objekt gamma parameter med ._gamma:

svc._gamma 

Vi kan se at gamma brukt i klassifiseringen vår var lav, så den vurderte også poeng lenger unna.

Merknader: Som vi har sett, C og gamma er viktige for noen definisjoner av modellen. En annen hyperparameter, random_state, brukes ofte i Scikit Learn for å garantere data shuffling eller et tilfeldig frø for modeller, så vi har alltid de samme resultatene, men dette er litt annerledes for SVM-er. Spesielt random_state har bare implikasjoner hvis en annen hyperparameter, probability, er satt til sann. Dette er fordi det vil blande dataene for å oppnå sannsynlighetsestimater. Hvis vi ikke vil ha sannsynlighetsestimater for klassene våre og sannsynligheten er satt til usann, vil SVMs random_state parameter har ingen implikasjoner på modellresultatene.

Det er ingen regel for hvordan man velger verdier for hyperparametere, som C og gamma – det vil avhenge av hvor lenge og hvilke ressurser som er tilgjengelige for å eksperimentere med ulike hyperparameterverdier, hvilke transformasjoner som kan gjøres til dataene, og hvilke resultater som forventes. . Den vanlige måten å søke etter hyperparameterverdiene på er ved å kombinere hver av de foreslåtte verdiene gjennom en rutenettsøk sammen med en prosedyre som bruker disse hyperparameterverdiene og henter beregninger for forskjellige deler av dataene som kalles kryssvalidering. I Scikit-learn er dette allerede implementert som GridSearchCV (CV fra kryssvalidering) metode.

For å kjøre et rutenettsøk med kryssvalidering, må vi importere GridSearchCV, definer en ordbok med verdiene til hyperparametere som skal eksperimenteres med, for eksempel typen kernel, rekkevidden for C, Og for gamma, opprette en forekomst av SVC, definer score eller metrikk vil bli brukt for å evaluere (her vil vi velge å optimalisere for både presisjon og tilbakekalling, så vi bruker f1-score), antall inndelinger som vil bli gjort i dataene for å kjøre søket i cv – standarden er 5, men det er en god praksis å bruke minst 10 – her vil vi bruke 5 datafoldinger for å gjøre det klarere når vi sammenligner resultater.

De GridSearchCV har en fit metode som mottar togdataene våre og deler dem videre i tog- og testsett for kryssvalideringen. Vi kan sette return_train_score til sant for å sammenligne resultatene og garantere at det ikke er overfit.

Dette er koden for rutenettsøket med kryssvalidering:

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)

Denne koden gir ut:

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

Etter å ha gjort hyperparametersøket, kan vi bruke best_estimator_, best_params_ og best_score_ egenskaper for å oppnå den beste modellen, parameterverdier og høyeste f1-score:

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)

Dette resulterer i:

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

For å bekrefte vår første gjetning fra å se på dataene, har den beste modellen ikke en lineær kjerne, men en ikke-lineær, RBF.

Råd: Når du undersøker videre, er det interessant at du inkluderer flere ikke-lineære kjerner i rutenettsøket.

Begge C og gamma har verdien av 1, og f1-score er veldig høy, 0.99. Siden verdien er høy, la oss se om det var overfit ved å se på gjennomsnittstesten og togresultatene vi har returnert, inne i cv_results_ gjenstand:

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)

Gjennomsnittlig poengsum var:

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. ]

Ved å se på gjennomsnittsskårene kan vi se at den høyeste, 0.99791667 vises to ganger, og i begge tilfeller var skåren i togdata 1. Dette indikerer at overfitten vedvarer. Herfra ville det vært interessant å gå tilbake til dataforberedelsen og forstå om det er fornuftig å normalisere dataene, foreta en annen type datatransformasjon og også lage nye funksjoner med funksjonsteknikk.

Vi har nettopp sett en teknikk for å finne modellhyperparametrene, og vi har allerede nevnt noe om lineær separerbarhet, støttevektorer, beslutningsgrense, maksimering av marginer og kjernetriks. SVM er en kompleks algoritme, vanligvis med mange matematiske konsepter involvert og små tweakable deler som må justeres for å komme sammen som en helhet.

La oss kombinere det vi har sett så langt, lage en oppsummering av hvordan alle delene av SVM fungerer, og så ta en titt på noen av de andre kjerneimplementeringene sammen med resultatene deres.

konklusjonen

I denne artikkelen forsto vi om standardparametrene bak Scikit-Learns SVM-implementering. Vi forsto hva C- og Gamma-parametere er, og hvordan endring av hver enkelt av dem kan påvirke SVM-modellen.

Vi lærte også om nettsøk for å se etter de beste C- og Gamma-verdiene, og for å bruke kryssvalidering for å generalisere resultatene våre bedre og garantere at det ikke er noen form for datalekkasje.

Å utføre en hyperparameterjustering med rutenettsøk og kryssvalidering er en vanlig praksis innen datavitenskap, så jeg anbefaler på det sterkeste at du implementerer teknikkene, kjører koden og ser koblingene mellom hyperparameterverdiene og endringene i SVM-prediksjoner.

Tidstempel:

Mer fra Stackabuse