1. Создадим и обучим линейный SVM.

import numpy as np

from sklearn.pipeline import make_pipeline

from sklearn.preprocessing import StandardScaler

from sklearn.svm import SVC

 

X = np.array([

    [1, 1],

    [2, 2],

    [3, 2],

    [6, 6],

    [7, 7],

    [8, 6]

])

 

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

Ожидаемые классы:

Для [2, 2] — 0.

Для [7, 6] — 1.

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

2. Сравним различные значения параметра 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)

 

    accuracy = accuracy_score(

        y_test,

        model.predict(X_test)

    )

 

    print("C:", c, "Точность:", round(accuracy, 3))

Меньшее значение C усиливает регуляризацию и допускает больше нарушений зазора.

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

Качество модели зависит от данных, поэтому выбор параметра должен выполняться на валидационной выборке. Тестовая выборка используется для окончательной оценки.

3. Сравним линейное и RBF-ядра.

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

)

 

settings = [

    ("linear", "scale"),

    ("rbf", 0.1),

    ("rbf", 1)

]

 

for kernel, gamma in settings:

    model = make_pipeline(

        StandardScaler(),

        SVC(

            kernel=kernel,

            C=1.0,

            gamma=gamma

        )

    )

 

    model.fit(X_train, y_train)

 

    accuracy = accuracy_score(

        y_test,

        model.predict(X_test)

    )

 

    print(

        "Ядро:", kernel,

        "gamma:", gamma,

        "Точность:", round(accuracy, 3)

    )

Линейный SVM строит линейную разделяющую границу.

RBF-ядро позволяет формировать нелинейные границы без явного построения новых координат.

Параметр gamma влияет на поведение RBF-модели, поэтому его необходимо настраивать осторожно и совместно с параметром C.