Spec-Zone.ru › scikit-learn

Примечание

Перейти к концу для скачивания полного примера кода. или для запуска этого примера в вашем браузере через JupyterLite или Binder

Графическое отображение границ классификации с различными ядрами SVM

Этот пример демонстрирует, как различные ядра в SVC (классификатор опорных векторов) влияют на границы классификации в бинарной двумерной задаче классификации.

SVC стремятся найти гиперплоскость, которая эффективно разделяет классы в данных обучения, максимизируя расстояние между самыми удаленными точками данных каждого класса. Это достигается путем поиска лучшего вектора весов \(w\), который определяет гиперплоскость границы принятия решений и минимизирует сумму потерь по типу «замок» для неправильно классифицированных образцов, измеряемых функцией hinge_loss. По умолчанию применяется регуляризация с параметром C=1, что допускает определенную степень терпимости к ошибочной классификации.

Если данные не являются линейно разделимыми в исходном пространстве признаков, можно установить параметр нелинейного ядра. В зависимости от ядра процесс включает добавление новых признаков или преобразование существующих признаков для обогащения и, возможно, придания смысла данным. При установке ядра, отличного от "linear", SVC применяет трюк ядра, который вычисляет сходство между парами точек данных с использованием функции ядра без явного преобразования всего набора данных. Трюк ядра превосходит необходимость иначе необходимой матричной трансформации всего набора данных, рассматривая только отношения между всеми парами точек данных. Функция ядра отображает два вектора (каждую пару наблюдений) в их сходство, используя их скалярное произведение.

Затем гиперплоскость можно рассчитать, используя функцию ядра, как если бы набор данных был представлен в пространстве большей размерности. Использование функции ядра вместо явного преобразования матрицы повышает производительность, поскольку функция ядра имеет временную сложность \(O({n}^2)\), тогда как преобразование матрицы масштабируется в зависимости от применяемого преобразования.

В этом примере мы сравниваем наиболее распространенные типы ядер машинных векторов поддержки: линейное ядро ("linear"), полиномиальное ядро ("poly"), ядро радиальной базисной функции ("rbf") и сигмоидное ядро ("sigmoid").

# Authors: The scikit-learn developers
# SPDX-License-Identifier: BSD-3-Clause

Создание набора данных

Мы создаем двумерный набор данных классификации с 16 образцами и двумя классами. Мы отображаем образцы с цветами, соответствующими их соответствующим целям.

import matplotlib.pyplot as plt
import numpy as np

X = np.array(
    [
        [0.4, -0.7],
        [-1.5, -1.0],
        [-1.4, -0.9],
        [-1.3, -1.2],
        [-1.1, -0.2],
        [-1.2, -0.4],
        [-0.5, 1.2],
        [-1.5, 2.1],
        [1.0, 1.0],
        [1.3, 0.8],
        [1.2, 0.5],
        [0.2, -2.0],
        [0.5, -2.4],
        [0.2, -2.3],
        [0.0, -2.7],
        [1.3, 2.1],
    ]
)

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

# Plotting settings
fig, ax = plt.subplots(figsize=(4, 3))
x_min, x_max, y_min, y_max = -3, 3, -3, 3
ax.set(xlim=(x_min, x_max), ylim=(y_min, y_max))

# Plot samples by color and add legend
scatter = ax.scatter(X[:, 0], X[:, 1], s=150, c=y, label=y, edgecolors="k")
ax.legend(*scatter.legend_elements(), loc="upper right", title="Classes")
ax.set_title("Samples in two-dimensional feature space")
_ = plt.show()
Samples in two-dimensional feature space

Мы видим, что образцы не являются четко разделимыми прямой линией.

Обучение модели SVC и построение границ принятия решений

Мы определяем функцию, которая подгоняет классификатор SVC, позволяя параметру kernel как вход, а затем строит границы принятия решений, полученные моделью, используя DecisionBoundaryDisplay.

Обратите внимание, что для простоты параметр C установлен на его значение по умолчанию (C=1) в этом примере, а параметр gamma установлен на gamma=2 во всех ядрах, хотя он автоматически игнорируется для линейного ядра. В реальной задаче классификации, где важна производительность, настройка параметров (например, с использованием GridSearchCV) настоятельно рекомендуется для захвата различных структур в данных.

Установка response_method="predict" в DecisionBoundaryDisplay окрашивает области в зависимости от их предсказанного класса. Использование response_method="decision_function" позволяет нам также отображать границу принятия решений и отступы по обе стороны от нее. Наконец, опорные векторы, используемые во время обучения (которые всегда лежат на отступах), идентифицируются с помощью атрибута support_vectors_ обученных SVC и также выводятся на график.

from sklearn import svm
from sklearn.inspection import DecisionBoundaryDisplay


def plot_training_data_with_decision_boundary(
    kernel, ax=None, long_title=True, support_vectors=True
):
    # Train the SVC
    clf = svm.SVC(kernel=kernel, gamma=2).fit(X, y)

    # Settings for plotting
    if ax is None:
        _, ax = plt.subplots(figsize=(4, 3))
    x_min, x_max, y_min, y_max = -3, 3, -3, 3
    ax.set(xlim=(x_min, x_max), ylim=(y_min, y_max))

    # Plot decision boundary and margins
    common_params = {"estimator": clf, "X": X, "ax": ax}
    DecisionBoundaryDisplay.from_estimator(
        **common_params,
        response_method="predict",
        plot_method="pcolormesh",
        alpha=0.3,
    )
    DecisionBoundaryDisplay.from_estimator(
        **common_params,
        response_method="decision_function",
        plot_method="contour",
        levels=[-1, 0, 1],
        colors=["k", "k", "k"],
        linestyles=["--", "-", "--"],
    )

    if support_vectors:
        # Plot bigger circles around samples that serve as support vectors
        ax.scatter(
            clf.support_vectors_[:, 0],
            clf.support_vectors_[:, 1],
            s=150,
            facecolors="none",
            edgecolors="k",
        )

    # Plot samples by color and add legend
    ax.scatter(X[:, 0], X[:, 1], c=y, s=30, edgecolors="k")
    ax.legend(*scatter.legend_elements(), loc="upper right", title="Classes")
    if long_title:
        ax.set_title(f" Decision boundaries of {kernel} kernel in SVC")
    else:
        ax.set_title(kernel)

    if ax is None:
        plt.show()

Линейное ядро

Линейное ядро — это скалярное произведение входных образцов:

\[K(\mathbf{x}_1, \mathbf{x}_2) = \mathbf{x}_1^\top \mathbf{x}_2\]

Затем он применяется к любой комбинации двух точек данных (образцов) в наборе данных. Скалярное произведение двух точек определяет cosine_similarity между обеими точками. Чем выше значение, тем больше сходство точек.

plot_training_data_with_decision_boundary("linear")
Decision boundaries of linear kernel in SVC

Обучение SVC на линейном ядре приводит к не преобразованному пространству признаков, где гиперплоскость и отступы являются прямыми линиями. Из-за отсутствия выразительности линейного ядра обученные классы не идеально отражают данные обучения.

Полиномиальное ядро

Полиномиальное ядро изменяет понятие сходства. Функция ядра определяется как:

\[K(\mathbf{x}_1, \mathbf{x}_2) = (\gamma \cdot \ \mathbf{x}_1^\top\mathbf{x}_2 + r)^d\]

где \({d}\) — степень (degree) полинома, \({\gamma}\) (gamma) контролирует влияние каждого отдельного образца обучения на границу принятия решений, а \({r}\) — член смещения (coef0) , который смещает данные вверх или вниз. Здесь мы используем значение по умолчанию для степени полинома в функции ядра (degree=3). Когда coef0=0 (по умолчанию), данные преобразуются, но не добавляется дополнительная размерность. Использование полиномиального ядра эквивалентно созданию PolynomialFeatures и последующему подгонке SVC с линейным ядром на преобразованных данных, хотя этот альтернативный подход был бы вычислительно дорогостоящим для большинства наборов данных.

plot_training_data_with_decision_boundary("poly")
Decision boundaries of poly kernel in SVC

Полиномиальное ядро с gamma=2` хорошо адаптируется к данным обучения, заставляя отступы по обе стороны от гиперплоскости соответственно изгибаться.

Ядро RBF

Ядро радиальной базисной функции (RBF), также известное как гауссовское ядро, является ядром по умолчанию для машин опорных векторов в scikit-learn. Оно измеряет сходство между двумя точками данных в бесконечномерном пространстве, а затем приближается к классификации большинством голосов. Функция ядра определяется как:

\[K(\mathbf{x}_1, \mathbf{x}_2) = \exp\left(-\gamma \cdot {\|\mathbf{x}_1 - \mathbf{x}_2\|^2}\right)\]

где \({\gamma}\) (gamma) контролирует влияние каждого отдельного образца обучения на границу принятия решений.

Чем больше евклидово расстояние между двумя точками \(\|\mathbf{x}_1 - \mathbf{x}_2\|^2\), тем ближе функция ядра к нулю. Это означает, что две удаленные точки с большей вероятностью будут несходными.

plot_training_data_with_decision_boundary("rbf")
Decision boundaries of rbf kernel in SVC

На графике можно увидеть, как границы принятия решений стремятся сжаться вокруг точек данных, которые находятся близко друг к другу.

Ядро сигмоиды

Функция ядра сигмоиды определяется как:

\[K(\mathbf{x}_1, \mathbf{x}_2) = \tanh(\gamma \cdot \mathbf{x}_1^\top\mathbf{x}_2 + r)\]

где коэффициент ядра \({\gamma}\) (gamma) контролирует влияние каждого отдельного образца обучения на границу принятия решений, а \({r}\) — член смещения (coef0) , который смещает данные вверх или вниз.

В сигмоидном ядре сходство между двумя точками данных вычисляется с помощью гиперболической функции тангенса (\(\tanh\)). Функция ядра масштабирует и, возможно, смещает скалярное произведение двух точек (\(\mathbf{x}_1\) и \(\mathbf{x}_2\)).

plot_training_data_with_decision_boundary("sigmoid")
Decision boundaries of sigmoid kernel in SVC

Мы видим, что границы принятия решений, полученные с помощью сигмоидного ядра, выглядят изогнутыми и нерегулярными. Граница принятия решений пытается разделить классы, подгоняя кривую в форме сигмоиды, что приводит к сложной границе, которая может не обобщаться хорошо на незасмотренные данные. Из этого примера становится очевидным, что сигмоидное ядро имеет очень специфические области применения при работе с данными, которые демонстрируют сигмоидальную форму. В этом примере тщательная настройка может найти более обобщаемые границы принятия решений. Из-за своей специфичности сигмоидное ядро используется реже на практике по сравнению с другими ядрами.

Заключение

В этом примере мы визуализировали разделяющие границы, обученные на предоставленном наборе данных. Диаграммы служат наглядной демонстрацией того, как различные ядра используют данные обучения для определения границ классификации.

Гиперплоскости и маржины, хотя и вычисляются косвенно, можно представить как плоскости в преобразованном пространстве признаков. Однако на диаграммах они представлены относительно исходного пространства признаков, что приводит к криволинейным разделяющим границам для полиномиальных, RBF и сигмоидных ядер.

Обратите внимание, что диаграммы не оценивают точность или качество отдельных ядер. Они предназначены для визуального понимания того, как различные ядра используют данные обучения.

Для всесторонней оценки рекомендуется тонкая настройка параметров SVC с использованием таких методов, как GridSearchCV, чтобы уловить лежащие в основе структуры данных.

Набор данных XOR

Классическим примером набора данных, который не является линейно разделимым, является XOR-паттерн. Здесь мы демонстрируем, как различные ядра работают с таким набором данных.

xx, yy = np.meshgrid(np.linspace(-3, 3, 500), np.linspace(-3, 3, 500))
np.random.seed(0)
X = np.random.randn(300, 2)
y = np.logical_xor(X[:, 0] > 0, X[:, 1] > 0)

_, ax = plt.subplots(2, 2, figsize=(8, 8))
args = dict(long_title=False, support_vectors=False)
plot_training_data_with_decision_boundary("linear", ax[0, 0], **args)
plot_training_data_with_decision_boundary("poly", ax[0, 1], **args)
plot_training_data_with_decision_boundary("rbf", ax[1, 0], **args)
plot_training_data_with_decision_boundary("sigmoid", ax[1, 1], **args)
plt.show()
linear, poly, rbf, sigmoid

Как видно из диаграмм выше, только ядро rbf может найти разумную разделяющую границу для вышеуказанного набора данных.

Общее время выполнения скрипта: (0 минут 1.364 секунды)

Launch binder
Launch JupyterLite

Download Jupyter notebook: plot_svm_kernels.ipynb

Download Python source code: plot_svm_kernels.py

Download zipped: plot_svm_kernels.zip

Связанные примеры

Параметры RBF SVM

Графическое представление различных классификаторов SVM в наборе данных iris

Разделяющие границы полуконтролируемых классификаторов по сравнению с SVM в наборе данных Iris

SVM: Максимальная маржа разделяющей гиперплоскости

© 2007–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/svm/plot_svm_kernels.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API