Spec-Zone.ru › scikit-learn

1.4. Машины опорных векторов

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

Преимущества машин опорных векторов:

  • Эффективны в пространствах высокой размерности.
  • Остаются эффективными в случаях, когда число признаков превышает число образцов.
  • В функции принятия решения используются только некоторые обучающие точки (называемые опорными векторами), поэтому такие методы также экономны по памяти.
  • Универсальность: для функции принятия решения можно указать различные ядерные функции. Доступны распространённые ядра, но также можно задать пользовательские.

К недостаткам машин опорных векторов относятся:

  • Если число признаков значительно превышает число образцов, для предотвращения переобучения крайне важно правильно выбрать ядерные функции и член регуляризации.
  • SVM напрямую не предоставляют оценки вероятностей; они вычисляются с помощью дорогостоящей пятикратной перекрёстной проверки (см. раздел Оценки и вероятности ниже).

Реализации машин опорных векторов в scikit-learn поддерживают на входе как плотные (numpy.ndarray и преобразуемые в них с помощью numpy.asarray), так и разреженные (любые scipy.sparse) векторы образцов. Однако, чтобы использовать SVM для предсказаний на разреженных данных, модель должна быть обучена на таких данных. Для оптимальной производительности используйте dtype=float64 с numpy.ndarray (плотными) или scipy.sparse.csr_matrix (разреженными) массивами.

1.4.1. Классификация

SVC, NuSVC и LinearSVC — это классы, способные выполнять бинарную и многоклассовую классификацию набора данных.

../_images/sphx_glr_plot_iris_svc_001.png

SVC и NuSVC — похожие методы, но они принимают несколько разные наборы параметров и имеют разные математические формулировки (см. раздел Математическая формулировка). С другой стороны, LinearSVC — это другая (более быстрая) реализация классификации с помощью машин опорных векторов для случая линейного ядра. В ней также отсутствуют некоторые атрибуты SVC и NuSVC, например support_. В LinearSVC используется функция потерь squared_hinge, а из-за реализации на liblinear регуляризуется также свободный член, если он учитывается. Однако этот эффект можно уменьшить, тщательно настроив параметр intercept_scaling, который позволяет применять к свободному члену режим регуляризации, отличный от режима для остальных признаков. Поэтому результаты классификации и оценка могут отличаться от результатов двух других классификаторов.

Как и другие классификаторы, SVC, NuSVC и LinearSVC принимают на вход два массива: массив X формы (n_samples, n_features), содержащий обучающие образцы, и массив y с метками классов (строками или целыми числами) формы (n_samples):

>>> from sklearn import svm
>>> X = [[0, 0], [1, 1]]
>>> y = [0, 1]
>>> clf = svm.SVC()
>>> clf.fit(X, y)
SVC()

После обучения модель можно использовать для предсказания новых значений:

>>> clf.predict([[2., 2.]])
array([1])

Функция принятия решений SVM (подробно описанная в разделе Математическая формулировка) зависит от некоторого подмножества обучающих данных, называемого опорными векторами. Некоторые свойства этих опорных векторов доступны в атрибутах support_vectors_, support_ и n_support_:

>>> # get support vectors
>>> clf.support_vectors_
array([[0., 0.],
       [1., 1.]])
>>> # get indices of support vectors
>>> clf.support_
array([0, 1]...)
>>> # get number of support vectors for each class
>>> clf.n_support_
array([1, 1]...)

Примеры

  • SVM: разделяющая гиперплоскость с максимальным отступом
  • SVM-Anova: SVM с одномерным отбором признаков
  • График вероятностей классификации

1.4.1.1. Многоклассовая классификация

SVC и NuSVC реализуют подход «один против одного» («ovo») для многоклассовой классификации: он строит n_classes * (n_classes - 1) / 2 классификаторов, каждый из которых обучается на данных двух классов. Внутри решатель всегда использует эту стратегию «ovo» для обучения моделей. Однако по умолчанию параметр decision_function_shape имеет значение "ovr" («один против всех»), чтобы обеспечить согласованный интерфейс с другими классификаторами посредством монотонного преобразования функции принятия решений «ovo» в функцию принятия решений «ovr» формы (n_samples, n_classes).

>>> X = [[0], [1], [2], [3]]
>>> Y = [0, 1, 2, 3]
>>> clf = svm.SVC(decision_function_shape='ovo')
>>> clf.fit(X, Y)
SVC(decision_function_shape='ovo')
>>> dec = clf.decision_function([[1]])
>>> dec.shape[1] # 6 classes: 4*3/2 = 6
6
>>> clf.decision_function_shape = "ovr"
>>> dec = clf.decision_function([[1]])
>>> dec.shape[1] # 4 classes
4

С другой стороны, LinearSVC реализует многоклассовую стратегию «один против всех» («ovr»), обучая таким образом n_classes моделей.

>>> lin_clf = svm.LinearSVC()
>>> lin_clf.fit(X, Y)
LinearSVC()
>>> dec = lin_clf.decision_function([[1]])
>>> dec.shape[1]
4

Полное описание функции принятия решений см. в разделе Математическая формулировка.

Подробнее о многоклассовых стратегиях

Обратите внимание, что LinearSVC также реализует альтернативную многоклассовую стратегию — так называемую многоклассовую SVM, сформулированную Краммером и Сингером [16], с помощью параметра multi_class='crammer_singer'. На практике обычно предпочитают классификацию «один против всех»: результаты в основном схожи, но время выполнения значительно меньше.

Для стратегии «один против всех» у LinearSVC атрибуты coef_ и intercept_ имеют формы (n_classes, n_features) и (n_classes,) соответственно. Каждая строка коэффициентов соответствует одному из n_classes классификаторов «один против всех»; то же относится к свободным членам, упорядоченным по классу «один».

В случае стратегии «один против одного» у SVC и NuSVC структура атрибутов несколько сложнее. В случае линейного ядра атрибуты coef_ и intercept_ имеют формы (n_classes * (n_classes - 1) / 2, n_features) и (n_classes * (n_classes - 1) / 2) соответственно. Это похоже на описанную выше структуру для LinearSVC, но теперь каждая строка соответствует бинарному классификатору. Для классов от 0 до n порядок следующий: «0 против 1», «0 против 2», … «0 против n», «1 против 2», «1 против 3», «1 против n», . . . «n-1 против n».

Форма dual_coef_ — (n_classes-1, n_SV), а её структуру довольно сложно понять. Столбцы соответствуют опорным векторам, участвующим в любом из n_classes * (n_classes - 1) / 2 классификаторов «один против одного». У каждого опорного вектора v есть двойственный коэффициент в каждом из n_classes - 1 классификаторов, сравнивающих класс v с другим классом. Обратите внимание: некоторые, но не все, эти двойственные коэффициенты могут быть равны нулю. Записи n_classes - 1 в каждом столбце — это эти двойственные коэффициенты, упорядоченные по противопоставляемому классу.

Рассмотрим пример. Пусть задача включает три класса: у класса 0 три опорных вектора \(v^{0}_0, v^{1}_0, v^{2}_0\), а у классов 1 и 2 — по два опорных вектора \(v^{0}_1, v^{1}_1\) и \(v^{0}_2, v^{1}_2\) соответственно. Для каждого опорного вектора \(v^{j}_i\) есть два двойственных коэффициента. Обозначим коэффициент опорного вектора \(v^{j}_i\) в классификаторе между классами \(i\) и \(k\) как \(\alpha^{j}_{i,k}\). Тогда dual_coef_ выглядит следующим образом:

\(\alpha^{0}_{0,1}\)

\(\alpha^{1}_{0,1}\)

\(\alpha^{2}_{0,1}\)

\(\alpha^{0}_{1,0}\)

\(\alpha^{1}_{1,0}\)

\(\alpha^{0}_{2,0}\)

\(\alpha^{1}_{2,0}\)

\(\alpha^{0}_{0,2}\)

\(\alpha^{1}_{0,2}\)

\(\alpha^{2}_{0,2}\)

\(\alpha^{0}_{1,2}\)

\(\alpha^{1}_{1,2}\)

\(\alpha^{0}_{2,1}\)

\(\alpha^{1}_{2,1}\)

Коэффициенты опорных векторов класса 0

Коэффициенты опорных векторов класса 1

Коэффициенты опорных векторов класса 2

Примеры

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

1.4.1.2. Оценки и вероятности

Метод decision_function класса SVC и класса NuSVC выдаёт оценки для каждого класса каждого образца (или одну оценку для образца в бинарном случае). Если параметру конструктора probability присвоено значение True, становятся доступны оценки вероятности принадлежности к классам (с помощью методов predict_proba и predict_log_proba). В бинарном случае вероятности калибруются методом масштабирования Платта [9]: логистической регрессией оценок SVM, обучаемой с помощью дополнительной перекрёстной проверки на обучающих данных. В многоклассовом случае этот подход расширяется согласно [10].

Примечание

Та же процедура калибровки вероятностей доступна для всех оценивателей через CalibratedClassifierCV (см. раздел Калибровка вероятностей). Для SVC и NuSVC эта процедура встроена в libsvm, используемую внутри, поэтому она не опирается на CalibratedClassifierCV из scikit-learn.

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

  • «argmax» оценок может не совпадать с argmax вероятностей
  • в бинарной классификации predict может пометить образец как принадлежащий положительному классу, даже если результат predict_proba меньше 0.5; аналогично, образец может быть помечен как отрицательный, даже если результат predict_proba больше 0.5.

Известно также, что метод Платта имеет теоретические недостатки. Если необходимы оценки уверенности, но не обязательно вероятности, рекомендуется установить probability=False и использовать decision_function вместо predict_proba.

Обратите внимание: при использовании decision_function_shape='ovr' и n_classes > 2, в отличие от decision_function, метод predict по умолчанию не пытается разрешать равенства. Можно установить break_ties=True, чтобы результат predict совпадал с np.argmax(clf.decision_function(...), axis=1); в противном случае всегда будет возвращаться первый из классов с одинаковым результатом. Однако это увеличивает вычислительные затраты. Пример разрешения равенств см. в разделе Пример разрешения равенств в SVM.

1.4.1.3. Несбалансированные задачи

Если в задаче требуется придавать большее значение определённым классам или отдельным образцам, можно использовать параметры class_weight и sample_weight.

SVC (но не NuSVC) реализует параметр class_weight в методе fit. Это словарь вида {class_label : value}, где value — число с плавающей точкой > 0, задающее параметр C для класса class_label равным C * value. На рисунке ниже показана граница принятия решений для несбалансированной задачи с коррекцией весов и без неё.

../_images/sphx_glr_plot_separating_hyperplane_unbalanced_001.png

SVC, NuSVC, SVR, NuSVR, LinearSVC, LinearSVR и OneClassSVM также поддерживают веса отдельных образцов в методе fit через параметр sample_weight. Как и class_weight, этот параметр задаёт значение C для i-го примера равным C * sample_weight[i], что побуждает классификатор правильно классифицировать эти образцы. На рисунке ниже показано влияние весов образцов на границу принятия решений. Размер окружностей пропорционален весам образцов:

../_images/sphx_glr_plot_weighted_samples_001.png

Примеры

  • SVM: разделяющая гиперплоскость для несбалансированных классов
  • SVM: взвешенные образцы

1.4.2. Регрессия

Метод классификации с помощью машин опорных векторов можно расширить для решения задач регрессии. Этот метод называется регрессией с помощью машин опорных векторов.

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

Существует три реализации регрессии на основе опорных векторов: SVR, NuSVR и LinearSVR. LinearSVR работает быстрее, чем SVR, но поддерживает только линейное ядро, а NuSVR реализует несколько иную формулировку, чем SVR и LinearSVR. Из-за реализации на liblinear в LinearSVR также регуляризуется свободный член, если он учитывается. Однако этот эффект можно уменьшить, тщательно настроив параметр intercept_scaling, который позволяет применять к свободному члену режим регуляризации, отличный от режима для остальных признаков. Поэтому результаты классификации и оценка могут отличаться от результатов двух других классификаторов. Дополнительные сведения см. в разделе Особенности реализации.

Как и в случае классов классификации, метод fit принимает в качестве аргументов векторы X и y, но в данном случае ожидается, что y содержит значения с плавающей точкой, а не целые числа:

>>> from sklearn import svm
>>> X = [[0, 0], [2, 2]]
>>> y = [0.5, 2.5]
>>> regr = svm.SVR()
>>> regr.fit(X, y)
SVR()
>>> regr.predict([[1, 1]])
array([1.5])

Примеры

  • Регрессия с помощью машин опорных векторов (SVR) с линейными и нелинейными ядрами

1.4.3. Оценка плотности, обнаружение новых объектов

Класс OneClassSVM реализует одноклассовую SVM, используемую для обнаружения выбросов.

Описание и сведения об использовании OneClassSVM см. в разделе Обнаружение новых объектов и выбросов.

1.4.4. Сложность

Машины опорных векторов — мощные инструменты, однако требования к вычислительным ресурсам и памяти быстро возрастают с увеличением числа обучающих векторов. В основе SVM лежит задача квадратичного программирования (QP), отделяющая опорные векторы от остальных обучающих данных. Решатель QP, используемый в реализации на основе libsvm, имеет сложность от \(O(n_{features} \times n_{samples}^2)\) до \(O(n_{features} \times n_{samples}^3)\) в зависимости от того, насколько эффективно на практике используется кэш libsvm (зависит от набора данных). Для очень разреженных данных вместо \(n_{features}\) следует использовать среднее число ненулевых признаков в векторе образца.

Для линейного случая алгоритм, используемый в LinearSVC при реализации на основе liblinear, значительно эффективнее аналога SVC на основе libsvm и масштабируется почти линейно до миллионов образцов и/или признаков.

1.4.5. Советы по практическому использованию

  • Избегайте копирования данных: для SVC, SVR, NuSVC и NuSVR, если данные, переданные некоторым методам, не являются непрерывными массивами в порядке C и не используют двойную точность, перед вызовом базовой реализации на C они будут скопированы. Проверить, является ли заданный массив numpy непрерывным в порядке C, можно, изучив его атрибут flags.

    Для LinearSVC (и LogisticRegression) любой входной массив numpy будет скопирован и преобразован во внутреннее разреженное представление данных liblinear (числа с плавающей точкой двойной точности и индексы ненулевых компонент типа int32). Если вы хотите обучить линейный классификатор для больших наборов данных, не копируя в качестве входных данных плотный непрерывный в порядке C массив numpy двойной точности, рекомендуем вместо этого использовать класс SGDClassifier. Целевую функцию можно настроить так, чтобы она была почти такой же, как у модели LinearSVC.

  • Размер кэша ядра: для SVC, SVR, NuSVC и NuSVR размер кэша ядра существенно влияет на время выполнения при решении задач большого размера. Если у вас достаточно оперативной памяти, рекомендуется установить для cache_size значение выше заданного по умолчанию (200 МБ), например 500 МБ или 1000 МБ.
  • Настройка C: по умолчанию C равно 1, и это разумный выбор по умолчанию. Если у вас много зашумлённых наблюдений, следует уменьшить это значение: уменьшение C соответствует усилению регуляризации.

    LinearSVC и LinearSVR менее чувствительны к C при больших значениях, и после достижения определённого порога качество предсказаний перестаёт улучшаться. При этом для обучения с большими значениями C требуется больше времени — иногда до 10 раз больше, как показано в [11].

  • Алгоритмы машин опорных векторов не инвариантны к масштабу, поэтому настоятельно рекомендуется масштабировать данные. Например, масштабируйте каждый признак входного вектора X до диапазона [0,1] или [-1,+1] либо стандартизируйте его так, чтобы среднее значение было равно 0, а дисперсия — 1. Обратите внимание, что для получения значимых результатов к тестовому вектору необходимо применить то же масштабирование. Это можно легко сделать с помощью Pipeline:

    >>> from sklearn.pipeline import make_pipeline
    >>> from sklearn.preprocessing import StandardScaler
    >>> from sklearn.svm import SVC
    
    >>> clf = make_pipeline(StandardScaler(), SVC())
    

    Дополнительные сведения о масштабировании и нормализации см. в разделе Предварительная обработка данных.

  • О параметре shrinking, цитата из [12]: Мы обнаружили, что при большом числе итераций сокращение может уменьшить время обучения. Однако если решить задачу оптимизации с невысокой точностью (например, задав большой порог остановки), версия кода без сокращения может работать значительно быстрее
  • Параметр nu в NuSVC/OneClassSVM/NuSVR приближённо задаёт долю ошибок на обучающей выборке и опорных векторов.
  • В SVC, если данные несбалансированы (например, положительных объектов много, а отрицательных мало), задайте class_weight='balanced' и/или попробуйте разные значения параметра штрафа C.
  • Случайность базовых реализаций: базовые реализации SVC и NuSVC используют генератор случайных чисел только для перемешивания данных при оценке вероятностей (когда probability установлено в True). Эту случайность можно контролировать с помощью параметра random_state. Если probability установлено в False, эти оцениватели не используют случайность, и random_state не влияет на результаты. Базовая реализация OneClassSVM похожа на реализации SVC и NuSVC. Поскольку для OneClassSVM оценка вероятностей не предоставляется, он не использует случайность.

    Базовая реализация LinearSVC использует генератор случайных чисел для выбора признаков при обучении модели методом двойственного координатного спуска (то есть когда dual установлено в True). Поэтому для одних и тех же входных данных результаты могут немного различаться. Если это происходит, попробуйте уменьшить значение параметра tol. Эту случайность также можно контролировать с помощью параметра random_state. Если dual установлено в False, базовая реализация LinearSVC не использует случайность, и random_state не влияет на результаты.

  • Использование L1-штрафа, обеспечиваемого LinearSVC(penalty='l1', dual=False), даёт разреженное решение: ненулевыми и влияющими на функцию принятия решения оказываются веса лишь для части признаков. Увеличение C приводит к усложнению модели (выбирается больше признаков). Значение C, при котором получается «нулевая» модель (все веса равны нулю), можно вычислить с помощью l1_min_c.

1.4.6. Функции ядра

Функция ядра может быть одной из следующих:

  • линейное: \(\langle x, x'\rangle\).
  • полиномиальное: \((\gamma \langle x, x'\rangle + r)^d\), где \(d\) задаётся параметром degree, а \(r\) — параметром coef0.
  • rbf: \(\exp(-\gamma \|x-x'\|^2)\), где \(\gamma\) задаётся параметром gamma и должен быть больше 0.
  • сигмоидальное \(\tanh(\gamma \langle x,x'\rangle + r)\), где \(r\) задаётся параметром coef0.

Различные ядра задаются параметром kernel:

>>> linear_svc = svm.SVC(kernel='linear')
>>> linear_svc.kernel
'linear'
>>> rbf_svc = svm.SVC(kernel='rbf')
>>> rbf_svc.kernel
'rbf'

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

1.4.6.1. Параметры ядра RBF

При обучении SVM с ядром радиальных базисных функций (RBF) необходимо учитывать два параметра: C и gamma. Параметр C, общий для всех ядер SVM, задаёт компромисс между ошибочной классификацией обучающих примеров и простотой поверхности принятия решения. Низкое значение C делает поверхность принятия решения гладкой, тогда как высокое значение C нацелено на правильную классификацию всех обучающих примеров. gamma определяет, насколько сильно влияет отдельный обучающий пример. Чем больше gamma, тем ближе должны быть другие примеры, чтобы испытать это влияние.

Правильный выбор C и gamma критически важен для эффективности SVM. Рекомендуется использовать GridSearchCV, задав C и gamma значения, экспоненциально удалённые друг от друга, чтобы подобрать подходящие параметры.

Примеры

  • Параметры SVM с ядром RBF
  • Масштабирование параметра регуляризации для SVC

1.4.6.2. Пользовательские ядра

Вы можете определить собственные ядра, передав функцию Python в качестве ядра или предварительно вычислив матрицу Грама.

Классификаторы с пользовательскими ядрами работают так же, как и любые другие классификаторы, за исключением следующего:

  • Поле support_vectors_ теперь пусто, в support_ сохраняются только индексы опорных векторов
  • Для дальнейшего использования сохраняется ссылка (а не копия) на первый аргумент метода fit(). Если этот массив изменится между вызовами fit() и predict(), вы получите неожиданные результаты.
Использование функций Python в качестве ядер

Вы можете использовать собственные определённые ядра, передав функцию в параметр kernel.

Ваша функция ядра должна принимать в качестве аргументов две матрицы формы (n_samples_1, n_features), (n_samples_2, n_features) и возвращать матрицу ядра формы (n_samples_1, n_samples_2).

Следующий код определяет линейное ядро и создаёт экземпляр классификатора, который будет его использовать:

>>> import numpy as np
>>> from sklearn import svm
>>> def my_kernel(X, Y):
...     return np.dot(X, Y.T)
...
>>> clf = svm.SVC(kernel=my_kernel)
Использование матрицы Грама

Вы можете передать предварительно вычисленные ядра, используя параметр kernel='precomputed'. В этом случае вместо X следует передать матрицу Грама в методы fit и predict. Необходимо предоставить значения ядра между всеми обучающими векторами и тестовыми векторами:

>>> import numpy as np
>>> from sklearn.datasets import make_classification
>>> from sklearn.model_selection import train_test_split
>>> from sklearn import svm
>>> X, y = make_classification(n_samples=10, random_state=0)
>>> X_train , X_test , y_train, y_test = train_test_split(X, y, random_state=0)
>>> clf = svm.SVC(kernel='precomputed')
>>> # linear kernel computation
>>> gram_train = np.dot(X_train, X_train.T)
>>> clf.fit(gram_train, y_train)
SVC(kernel='precomputed')
>>> # predict on training examples
>>> gram_test = np.dot(X_test, X_train.T)
>>> clf.predict(gram_test)
array([0, 1, 0])

Примеры

  • SVM с пользовательским ядром

1.4.7. Математическая формулировка

Машина опорных векторов строит гиперплоскость или набор гиперплоскостей в пространстве высокой или бесконечной размерности, которые можно использовать для классификации, регрессии и других задач. Интуитивно хорошее разделение достигается гиперплоскостью, расположенной на максимальном расстоянии от ближайших обучающих точек любого класса (так называемый функциональный зазор), поскольку, как правило, чем больше зазор, тем ниже ошибка обобщения классификатора. На рисунке ниже показана функция принятия решения для линейно разделимой задачи; три образца находятся на границах зазора и называются «опорными векторами»:

../_images/sphx_glr_plot_separating_hyperplane_001.png

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

В качестве полезных источников по теории и практическому применению SVM рекомендуем [13] и [14].

1.4.7.1. SVC

Для обучающих векторов \(x_i \in \mathbb{R}^p\), i=1,…, n, принадлежащих двум классам, и вектора \(y \in \{1, -1\}^n\) наша цель — найти \(w \in \mathbb{R}^p\) и \(b \in \mathbb{R}\) так, чтобы предсказание, задаваемое выражением \(\text{sign} (w^T\phi(x) + b)\), было правильным для большинства образцов.

SVC решает следующую прямую задачу:

\[ \begin{align}\begin{aligned}\min_ {w, b, \zeta} \frac{1}{2} w^T w + C \sum_{i=1}^{n} \zeta_i\\\begin{split}\textrm {subject to } & y_i (w^T \phi (x_i) + b) \geq 1 - \zeta_i,\\ & \zeta_i \geq 0, i=1, ..., n\end{split}\end{aligned}\end{align} \]

Интуитивно мы стремимся максимизировать зазор (минимизируя \(||w||^2 = w^Tw\)) и одновременно штрафуем за ошибочную классификацию образца или его попадание внутрь границы зазора. В идеале значение \(y_i (w^T \phi (x_i) + b)\) должно быть \(\geq 1\) для всех образцов, что соответствует идеальному предсказанию. Однако обычно гиперплоскость не позволяет идеально разделить все задачи, поэтому мы допускаем, что некоторые образцы могут отстоять на расстояние \(\zeta_i\) от соответствующей им границы зазора. Член штрафа C определяет силу этого штрафа и, как следствие, действует как параметр, обратный параметру регуляризации (см. примечание ниже).

Двойственная к прямой задача имеет вид

\[ \begin{align}\begin{aligned}\min_{\alpha} \frac{1}{2} \alpha^T Q \alpha - e^T \alpha\\\begin{split} \textrm {subject to } & y^T \alpha = 0\\ & 0 \leq \alpha_i \leq C, i=1, ..., n\end{split}\end{aligned}\end{align} \]

где \(e\) — вектор, состоящий из единиц, а \(Q\) — положительно полуопределённая матрица размера \(n\) на \(n\), \(Q_{ij} \equiv y_i y_j K(x_i, x_j)\), где \(K(x_i, x_j) = \phi (x_i)^T \phi (x_j)\) — ядро. Величины \(\alpha_i\) называются двойственными коэффициентами и ограничены сверху значением \(C\). Это двойственное представление показывает, что функция \(\phi\) неявно отображает обучающие векторы в пространство более высокой (возможно, бесконечной) размерности: см. ядерный трюк.

После решения задачи оптимизации результат работы decision_function для заданного образца \(x\) имеет вид:

\[\sum_{i\in SV} y_i \alpha_i K(x_i, x) + b,\]

а предсказанный класс соответствует знаку этого выражения. Суммировать нужно только по опорным векторам (то есть образцам, расположенным внутри зазора), поскольку для остальных образцов двойственные коэффициенты \(\alpha_i\) равны нулю.

К этим параметрам можно обратиться через атрибуты dual_coef_, содержащий произведение \(y_i \alpha_i\), support_vectors_, содержащий опорные векторы, и intercept_, содержащий свободный член \(b\).

Примечание

В моделях SVM на основе libsvm и liblinear в качестве параметра регуляризации используется C, тогда как в большинстве других оценивателей используется alpha. Точная зависимость между степенью регуляризации двух моделей определяется конкретной целевой функцией, которую оптимизирует модель. Например, если используется оцениватель регрессии Ridge, связь между ними задаётся выражением \(C = \frac{1}{\alpha}\).

LinearSVC

Прямую задачу можно эквивалентным образом записать как

\[\min_ {w, b} \frac{1}{2} w^T w + C \sum_{i=1}^{n}\max(0, 1 - y_i (w^T \phi(x_i) + b)),\]

используя шарнирную функцию потерь. Именно эту форму напрямую оптимизирует LinearSVC. Однако, в отличие от двойственной формы, она не включает скалярные произведения между образцами, поэтому применить знаменитый ядерный трюк нельзя. Именно поэтому LinearSVC поддерживает только линейное ядро (\(\phi\) — тождественная функция).

NuSVC

Формулировка \(\nu\)-SVC [15] представляет собой перепараметризацию \(C\)-SVC и поэтому математически эквивалентна ей.

Мы вводим новый параметр \(\nu\) (вместо \(C\)), который определяет количество опорных векторов и ошибок зазора: \(\nu \in (0, 1]\) является верхней границей доли ошибок зазора и нижней границей доли опорных векторов. Ошибка зазора соответствует образцу, лежащему по неправильную сторону границы зазора: он либо классифицирован ошибочно, либо классифицирован правильно, но находится внутри зазора.

1.4.7.2. SVR

Для обучающих векторов \(x_i \in \mathbb{R}^p\), i=1,…, n, и вектора \(y \in \mathbb{R}^n\) метод \(\varepsilon\)-SVR решает следующую прямую задачу:

\[ \begin{align}\begin{aligned}\min_ {w, b, \zeta, \zeta^*} \frac{1}{2} w^T w + C \sum_{i=1}^{n} (\zeta_i + \zeta_i^*)\\\begin{split}\textrm {subject to } & y_i - w^T \phi (x_i) - b \leq \varepsilon + \zeta_i,\\ & w^T \phi (x_i) + b - y_i \leq \varepsilon + \zeta_i^*,\\ & \zeta_i, \zeta_i^* \geq 0, i=1, ..., n\end{split}\end{aligned}\end{align} \]

Здесь штраф применяется к образцам, для которых расстояние между предсказанием и истинным целевым значением составляет не менее \(\varepsilon\). Эти образцы увеличивают значение целевой функции на \(\zeta_i\) или \(\zeta_i^*\) в зависимости от того, находится ли их предсказание выше или ниже трубки \(\varepsilon\).

Двойственная задача имеет вид

\[ \begin{align}\begin{aligned}\min_{\alpha, \alpha^*} \frac{1}{2} (\alpha - \alpha^*)^T Q (\alpha - \alpha^*) + \varepsilon e^T (\alpha + \alpha^*) - y^T (\alpha - \alpha^*)\\\begin{split} \textrm {subject to } & e^T (\alpha - \alpha^*) = 0\\ & 0 \leq \alpha_i, \alpha_i^* \leq C, i=1, ..., n\end{split}\end{aligned}\end{align} \]

где \(e\) — вектор, состоящий из единиц, \(Q\) — положительно полуопределённая матрица размера \(n\) на \(n\), а \(Q_{ij} \equiv K(x_i, x_j) = \phi (x_i)^T \phi (x_j)\) — ядро. Здесь функция \(\phi\) неявно отображает обучающие векторы в пространство более высокой (возможно, бесконечной) размерности.

Предсказание вычисляется по формуле:

\[\sum_{i \in SV}(\alpha_i - \alpha_i^*) K(x_i, x) + b\]

К этим параметрам можно обратиться через атрибуты dual_coef_, содержащий разность \(\alpha_i - \alpha_i^*\), support_vectors_, содержащий опорные векторы, и intercept_, содержащий свободный член \(b\)

LinearSVR

Прямую задачу можно эквивалентным образом записать как

\[\min_ {w, b} \frac{1}{2} w^T w + C \sum_{i=1}^{n}\max(0, |y_i - (w^T \phi(x_i) + b)| - \varepsilon),\]

используя функцию потерь, нечувствительную к ошибкам меньше эпсилон: ошибки величиной менее \(\varepsilon\) игнорируются. Именно эту форму напрямую оптимизирует LinearSVR.

1.4.8. Подробности реализации

Внутри мы используем libsvm [12] и liblinear [11] для выполнения всех вычислений. Эти библиотеки имеют оболочки на C и Cython. Описание реализации и подробности используемых алгоритмов приведены в соответствующих научных статьях.

Литература

[9]

Platt «Вероятностные выходы для SVM и сравнение с методами регуляризованного правдоподобия».

[10]

Wu, Lin и Weng, «Оценки вероятностей для многоклассовой классификации методом попарного сопряжения», JMLR 5:975-1005, 2004.

[11] (1,2)

Fan, Rong-En и др., «LIBLINEAR: библиотека для крупномасштабной линейной классификации», Journal of machine learning research 9.Aug (2008): 1871-1874.

[12] (1,2)

Chang и Lin, LIBSVM: библиотека для машин опорных векторов.

[13]

Bishop, Распознавание образов и машинное обучение, глава 7 «Разреженные машины с ядром».

[14]

«Введение в регрессию на основе опорных векторов» Alex J. Smola, Bernhard Schölkopf — архив журнала Statistics and Computing, том 14, выпуск 3, август 2004, с. 199–222.

[15]

Schölkopf и др. Новые алгоритмы для машин опорных векторов, Neural Computation 12, 1207-1245 (2000).

[16]

Crammer и Singer Об алгоритмической реализации многоклассовых машин на основе ядер и векторов, JMLR 2001.

© 2007–2026 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.9/modules/svm.html

Spec-Zone.ru

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