Пример 1. Линейный SVM и опорные векторы

Метод опорных векторов (SVM) ищет разделяющую гиперплоскость с большим геометрическим зазором между классами.

На положение разделяющей границы существенно влияют опорные векторы — наблюдения, расположенные на границе зазора или нарушающие его.

Рассмотрим простую задачу бинарной классификации.

import numpy as np

from sklearn.svm import SVC

from sklearn.pipeline import make_pipeline

from sklearn.preprocessing import StandardScaler

 

X = np.array([

    [1, 2],

    [2, 1],

    [2, 3],

    [6, 6],

    [7, 5],

    [7, 7]

])

 

y = np.array([0, 0, 0, 1, 1, 1])

 

model = make_pipeline(

    StandardScaler(),

    SVC(kernel="linear", C=1.0)

)

 

model.fit(X, y)

 

predictions = model.predict([

    [2, 2],

    [7, 6]

])

 

svm = model.named_steps["svc"]

 

print("Прогнозы:", predictions)

print("Количество опорных векторов:", svm.n_support_)

print("Индексы опорных векторов:", svm.support_)

Модель формирует линейную границу между двумя классами.

Опорные векторы определяют положение этой границы. Именно поэтому их анализ помогает понять механизм работы SVM.

Пример 2. Влияние параметра C

В soft-margin SVM параметр C управляет балансом между шириной зазора и штрафом за нарушения.

Сравним несколько значений параметра C.

from sklearn.datasets import make_classification

from sklearn.model_selection import train_test_split

from sklearn.pipeline import make_pipeline

from sklearn.preprocessing import StandardScaler

from sklearn.svm import SVC

from sklearn.metrics import accuracy_score

 

X, y = make_classification(

    n_samples=200,

    n_features=5,

    n_informative=3,

    n_redundant=0,

    flip_y=0.1,

    random_state=42

)

 

X_train, X_test, y_train, y_test = train_test_split(

    X, y,

    test_size=0.2,

    stratify=y,

    random_state=42

)

 

for c in [0.1, 1, 10]:

    model = make_pipeline(

        StandardScaler(),

        SVC(kernel="linear", C=c)

    )

 

    model.fit(X_train, y_train)

 

    predictions = model.predict(X_test)

 

    print("C =", c)

    print(

        "Точность:",

        round(accuracy_score(y_test, predictions), 3)

    )

Меньшее значение C допускает больший штрафуемый объём нарушений зазора ради более сильной регуляризации.

Большее значение C усиливает штраф за нарушения.

Оптимальное значение параметра следует выбирать по результатам валидации.

Пример 3. Использование RBF-ядра

Ядерные функции позволяют SVM строить нелинейные разделяющие границы без явного построения новых координат.

Одним из используемых ядер является RBF. Его поведение зависит от параметра gamma.

from sklearn.datasets import make_circles

from sklearn.model_selection import train_test_split

from sklearn.pipeline import make_pipeline

from sklearn.preprocessing import StandardScaler

from sklearn.svm import SVC

from sklearn.metrics import accuracy_score

 

X, y = make_circles(

    n_samples=300,

    factor=0.4,

    noise=0.1,

    random_state=42

)

 

X_train, X_test, y_train, y_test = train_test_split(

    X, y,

    test_size=0.2,

    stratify=y,

    random_state=42

)

 

for gamma in [0.01, 0.1, 1, 10]:

    model = make_pipeline(

        StandardScaler(),

        SVC(

            kernel="rbf",

            C=1.0,

            gamma=gamma

        )

    )

 

    model.fit(X_train, y_train)

 

    predictions = model.predict(X_test)

 

    print(

        "gamma =", gamma,

        "Точность =",

        round(accuracy_score(y_test, predictions), 3)

    )

Эксперимент демонстрирует, что качество модели с RBF-ядром зависит от значения gamma.

При использовании RBF важно выполнять масштабирование признаков и осторожно настраивать гиперпараметры.