Классификаторы SVC основаны на одной из наиболее популярных методологий обучения по прецедентам, которая была предложена в 70-е годы прошлого века сотрудниками Института проблем управления АН СССР В. Н. Вапником и А. Я. Червоненкисом. Данный подход называется в настоящее время "Машина опорных векторов" (SVM -Support Vector Machine).
SVM — набор схожих алгоритмов обучения с учителем, использующихся для задач классификации и регрессионного анализа. Принадлежит семейству линейных классификаторов с адаптацией для нелинейных классификаторов и может также рассматриваться как частный случай регуляризации по Тихонову. Особым свойством метода опорных векторов является непрерывное уменьшение эмпирической ошибки классификации и увеличение зазора, поэтому метод также известен как метод классификатора с максимальным зазором.
Основная идея метода — перевод исходных векторов в пространство более высокой размерности и поиск разделяющей гиперплоскости с наибольшим зазором в этом пространстве. Две параллельных гиперплоскости строятся по обеим сторонам гиперплоскости, разделяющей классы. Разделяющей гиперплоскостью будет гиперплоскость, создающая наибольшее расстояние до двух параллельных гиперплоскостей. Алгоритм основан на допущении, что чем больше разница или расстояние между этими параллельными гиперплоскостями, тем меньше будет средняя ошибка классификатора.
Рассматривается задача обучения по прецедентам $(X, Y, y∗,X^l)$, где $X$ - пространство объектов, $Y$ - множество ответов, $y∗ : X → Y$ - целевая зависимость,значения которой известны только на объектах обучающей выборки $X^l = \left( {x_i ,y_i } \right)_{i = 1}^l ,y_i = y^* \left( {x_i } \right)$. Требуется построить алгоритм $a: X → Y$ , аппроксимирующий целевую зависимость на всём пространстве $X$.
Метод опорных векторов в задачах бинарной классификации
Рассмотрим задачу классификации на два непересекающихся класса, в которой объекты описываются $n$-мерными вещественными векторами: $X = R^n ,Y = \left\{ { - 1, + 1} \right\}$
Будем строить линейный пороговый классификатор:
$$a\left( x \right) = sign\left( {\sum\limits_{j = 1}^n {w_j x^j - w_0 } } \right) = sign\left( {\left\langle {w,x} \right\rangle - w_0 } \right),\;\;\;(1)$$где $x = (x^1, . . . , x^n)$ - признаковое описание объекта $x$; вектор $w = \left( {w_1 ,....,w_n } \right) \in R^n$ и скалярный порог $w_0 \in R$ являются параметрами алгоритма.
Уравнение $\left\langle {w,x} \right\rangle = w_0$ описывает гиперплоскость, разделяющую классы в пространстве $R^n$.
Хотя правило классификации в точности совпадает с моделью нейрона по МакКаллоку-Питтсу, критерий и методы настройки параметров в $SVM$ радикально отличаются от персептронных (градиентных) методов обучения.
Понятие оптимальной разделяющей гиперплоскости
Предположим, что выборка линейно разделима, то есть существуют такие значения параметров $w, w_0$, при которых функционал числа ошибок:
$$Q\left( {w,w_0 } \right) = \sum\limits_{i = 1}^l {\left[ {y_i \left( {\left\langle {w,x_i } \right\rangle - w_0 } \right) < 0} \right]}$$принимает нулевое значение. Но тогда разделяющая гиперплоскость не единственна, поскольку существуют и другие положения разделяющей гиперплоскости, реализующие то же самое разбиение выборки. Идея метода заключается в том, чтобы разумным образом распорядиться этой свободой выбора. Потребуем, чтобы разделяющая гиперплоскость максимально далеко отстояла от ближайших к ней точек обоих классов. Первоначально данный принцип классификации возник из эвристических соображений: вполне естественно полагать, что максимизация зазора (margin) между классами должна способствовать более уверенной классификации. В дальнейшем этот принцип получил мощное теоретическое обоснование.
Нормировка. Заметим, что параметры линейного порогового классификатора определены с точностью до нормировки: алгоритм a(x) не изменится, если $w$ и $w_0$ одновременно умножить на одну и ту же положительную константу. Удобно выбрать эту константу таким образом, чтобы для всех пограничных (т. е. ближайших к разделяющей гиперплоскости) объектов $x_i$ из $X^l$ выполнялись условия: $\left\langle {w,x_i } \right\rangle - w_0 = y_i$
Сделать это возможно, поскольку при оптимальном положении разделяющей гиперплоскости все пограничные объекты находятся от неё на одинаковом расстоянии. Остальные объекты находятся дальше. Таким образом, для всех
$$\left\langle {w,x_i } \right\rangle - w_0 = \left\{ {\begin{array}{*{20}c} { \le - 1,{\rm if }y_i = - 1} \\ { \ge 1,{\rm if }y_i = + 1} \\ \end{array}} \right.\;\;\;(2)$$$$ - 1 < \left\langle {w,x} \right\rangle - w_0 < 1$$задаёт полосу, разделяющую классы. Ни одна из точек обучающей выборки не может лежать внутри этой полосы. Границами полосы служат две параллельные гиперплоскости с направляющим вектором w. Точки, ближайшие к разделяющей гиперплоскости, лежат в точности на границах полосы. При этом сама разделяющая гиперплоскость проходит ровно по середине полосы.
Ширина разделяющей полосы. Чтобы разделяющая гиперплоскость как можно дальше отстояла от точек выборки, ширина полосы должна быть максимальной. Пусть $x_-$ и $x_+$ - две произвольные точки классов −1 и +1 соответственно, лежащие на границе полосы. Тогда ширина полосы есть:
$$\left\langle {\left( {x_ + - x_ - } \right),\frac{w}{{\left\| w \right\|}}} \right\rangle = \frac{{\left\langle {w,x_ + } \right\rangle - \left\langle {w,x_ - } \right\rangle }}{{\left\| w \right\|}} = \frac{{\left( {w_0 + 1} \right) - \left( {w_0 - 1} \right)}}{{\left\| w \right\|}} = \frac{2}{{\left\| w \right\|}}$$Ширина полосы максимальна, когда норма вектора w минимальна. Итак, в случае, когда выборка линейно разделима, достаточно простые геометрические соображения приводят к следующей задаче: требуется найти такие значения параметров $w$ и $w_0$, при которых норма вектора $w$ минимальна при условии (2). Это задача квадратичного программирования. Она будет подробно рас- смотрена ниже . Затем будет сделано обобщение на тот случай, когда линейной разделимости нет
Линейно разделимая выборка.
Построение оптимальной разделяющей гиперплоскости сводится к минимизации квадратичной формы при l ограничениях-неравенствах вида (2) относительно $n + 1$ переменных $w, w_0$:
$$\left\{ {\begin{array}{*{20}c} {\left\langle {w,w } \right\rangle \to \min } \\ {y_i \left( {\left\langle {w,x_i } \right\rangle - w_0 } \right) \ge 1,i = 1,....,l} \\ \end{array}} \right.\;\;\;(3)$$По теореме Куна-Таккера эта задача эквивалентна двойственной задаче поиска седловой точки функции Лагранжа
$$\left\{ {\begin{array}{*{20}c} {\Lambda \left( {w,w_0 ;\lambda } \right) = \frac{1}{2}\left\langle {w,w } \right\rangle - \sum\limits_{i = 1}^l {\lambda _i \left( {y_i \left( {\left\langle {w,x{}_i} \right\rangle - w_0 } \right) - 1} \right) \to \min _{w,w_0 } \max _\lambda } } \\ {\lambda _i \ge 0,{\rm }i = 1,...............,l{\rm }} \\ {\lambda _i = 0,{\rm } \vee {\rm }\left\langle {w,x_i } \right\rangle - w_0 = y_i ,{\rm }i = 1,.....................,l;{\rm }} \\ \end{array}} \right.$$где $\lambda = \left( {\lambda _1 ,.......,\lambda _l } \right)$ - вектор двойственных переменных. Последнее из трёх условий называется условием дополняющей нежёсткости. Необходимым условием седловой точки является равенство нулю производных Лагранжиана. Отсюда немедленно вытекают два полезных соотношения
$$\frac{{\partial \Lambda }}{{\partial w}} = w - \sum\limits_{i = 1}^l {\lambda _i y_i x_i } = 0 \Rightarrow w = \sum\limits_{i = 1}^l {\lambda _i y_i x_i }\;\;\;(4)$$$$\frac{{\partial \Lambda }}{{\partial w_0 }} = - \sum\limits_{i = 1}^l {\lambda _i y_i } = 0 \Rightarrow \sum\limits_{i = 1}^l {\lambda _i y_i } = 0\;\;\;(5)$$Из (4) следует, что искомый вектор весов $w$ является линейной комбинацией векторов обучающей выборки, причём только тех, для которых $\lambda _i \ne 0$. Согласно условию дополняющей нежёсткости на этих векторах $x_i$ ограничения-неравенства обращаются в равенства: $\left\langle {w,x{}_i} \right\rangle - w_0 = y_i$,следовательно, эти векторы находятся на границе разделяющей полосы. Все остальные векторы отстоят дальше от границы,для них $\lambda_i = 0$, и они не участвуют в сумме (4). Алгоритм (1) не изменился бы,если бы этих векторов вообще не было в обучающей выборке.
Опр.1. Если $\lambda _i > 0$ и $\left\langle {w,x{}_i} \right\rangle - w_0 = y_i$ , то объект обучающей выборки $x_i$ называется опорным вектором (support vector). Подставляя (4) и (5) обратно в Лагранжиан, получим эквивалентную задачу квадратичного программирования, содержащую только двойственные переменные
$$\left\{ {\begin{array}{*{20}c} { - \Lambda \left( \lambda \right) = - \sum\limits_{i = 1}^l {\lambda _i + \frac{1}{2}\sum\limits_{i = 1}^l {\sum\limits_{j = 1}^l {\lambda _i \lambda _j y_i y_j \left( {\left\langle {x_i ,x_j } \right\rangle } \right) \to \mathop {\min }\limits_\lambda } } } } \\ {\lambda _i \ge 0,{\rm }i = 1,............,l;{\rm }} \\ {\sum\limits_{i = 1}^l {\lambda _i y_i = 0} } \\ \end{array}} \right.\;\;\;(6)$$Здесь минимизируется квадратичный функционал, имеющий неотрицательно определённую квадратичную форму, следовательно, выпуклый. Область, определяемая ограничениями неравенствами и одним равенством, также выпуклая. Следовательно, данная задача имеет единственное решение. Допустим, мы решили эту задачу. Тогда вектор $w$ вычисляется по формуле (4). Для определения порога $w_0$ достаточно взять произвольный опорный вектор $x_i$ и выразить $w_0$ из равенства $w_0 = \left\langle {w,x_i } \right\rangle - y_i$ . На практике для повышения численной устойчивости рекомендуется брать в качестве w0 среднее по всем опорным векторам, а ещё лучше медиану:
$$w_0 = med\left\{ {\left\langle {w,x_i } \right\rangle - y_i :\lambda _i > 0,i = 1,....,l} \right\}\;\;\;(7)$$$$a\left( x \right) = sign\left( {\sum\limits_{i = 1}^l {\lambda _i y_i \left\langle {x_i ,x} \right\rangle - w_0 } } \right)\;\;\;(8)$$Обратим внимание, что реально суммирование идёт не по всей выборке, а только по опорным векторам, для которых $\lambda _i \ne 0$. Именно это свойство разреженности (sparsity) отличает SVM от других линейных разделителей - дискриминанта Фише ра, логистической регрессии и однослойного персептрона.
Резюмируя, отметим, что пока остаются открытыми два вопроса: как быть, если классы линейно не разделимы, и как решить двойственную задачу (6)? Начнём с первого вопроса. Ниже рассматривается обобщение двойственной задачи на случай отсутствия линейной разделимости. После этого будет рассмотрен переход от скалярных произведений к произвольным ядрам - так называемый 'kernel trick', позволяющий строить нелинейные разделители.
Линейно неразделимая выборка.
Чтобы обобщить SVM на случай линейной неразделимости, позволим алгоритму допускать ошибки на обучающих объектах, но при этом постараемся, чтобы ошибок было поменьше. Введём набор дополнительных переменных $\xi _i \ge 0$, характеризующих величину ошибки на объектах $x_i, i = 1, . . . , l$. Возьмём за отправную точку задачу (3); смягчим в ней ограничения-неравенства, и одновременно введём в минимизируемый функционал штраф за суммарную ошибку:
$$\left\{ {\begin{array}{*{20}c} {\frac{1}{2}\left\langle {w,w} \right\rangle + C\sum\limits_{i = 1}^l {\xi _i \to \mathop {\min ;}\limits_{w,w_0 ,\xi } } } \\ {y_i \left( {\left\langle {w,x_i } \right\rangle - w_0 } \right) \ge 1 - \xi _i ,{\rm }i = 1,....,l;} \\ {\xi _i \ge 0,{\rm }i = 1,........,l.} \\ \end{array}} \right.\;\;\;\;(9)$$К этой же оптимизационной задаче приводит ещё одна цепочка рассуждений.Вспомним, что в случае $Y = {−1,+1}$ отступом (margin) объекта $x_i$ от границы классов называется величина
$$m_i = y_i \left( {\left\langle {w,x_i } \right\rangle - w_0 } \right)$$Алгоритм допускает ошибку на объекте $x_i$ тогда и только тогда, когда отступ $m_i$ отрицателен. Если $m_i ∈ (−1,+1)$, то объект $x_i$ попадает внутрь разделяющей полосы. Если $m_i > 1$, то объект $x_i$ классифицируется правильно, и находится на некотором удалении от разделяющей полосы. Запишем функционал числа ошибок алгоритма a на выборке $X^l$ в терминах отступов:
$$Q\left( {a,X^l } \right) = \sum\limits_{i = 1}^l {\left[ {m_i < 0} \right]}$$Заменим в этом функционале пороговую функцию потерь кусочно-линейной верхней оценкой: $\left[ {m_i < 0} \right] \le \left( {1 - m_i } \right)_ +$ .Смысл этой замены в том, чтобы сделать функцию потерь чувствительной к величине ошибки и заодно ввести штраф за приближение объекта к границе классов.Кроме того, добавим к функционалу $Q$ штрафное слагаемое $\tau \left\| w \right\|^2$. В соответствии с принципом регуляризации некорректно поставленных задач по А. Н. Тихонову такая добавка означает, что среди всех векторов $w$, минимизирующих функци онал $Q$, наиболее предпочтительны векторы с минимальной нормой. Регуляризация часто применяется для настройки линейных моделей классификации и регрессии. При наличии шумовых и/или зависимых признаков она повышает устойчивость алгоритма по отношению к составу выборки и его обобщающую способность.
С учётом обеих модификаций функционал качества принимает вид:
$$Q\left( {a,X^l } \right) = \sum\limits_{i = 1}^l {\left( {1 - m_i } \right)_ + + } \tau \left\| w \right\|^2 \to \mathop {\min }\limits_{w,w_0 }\;\;\;(10)$$Нетрудно показать, что задача минимизации данного функционала эквивалентна оптимизационной задаче с ограничениями (9), если взять параметр регуляризации $\tau = \frac{1}{{2C}}$ . Таким образом, принцип оптимальной разделяющей гиперплоскости (или максимизации ширины разделяющей полосы) совпадает с принципом регуляризации по Тихонову. Положительная константа $C$ (или $τ$ ) является управляющим параметром метода и позволяет находить компромисс между максимизацией разделяющей полосы и минимизацией суммарной ошибки.
Вернёмся к задаче (9) и запишем её функцию Лагранжа:
$$\Lambda \left( {w,w_0 ,\xi ;\lambda ,\eta } \right) = \frac{1}{2}\left\langle {w,w} \right\rangle - \sum\limits_{i = 1}^l {\lambda _i } \left( {y_i \left( {\left\langle {w,x_i } \right\rangle - w_0 } \right) - 1} \right) - \sum\limits_{i = 1}^l {\xi _i \left( {\lambda _i + \eta _i - C} \right)}$$где $\eta = \left( {\eta {}_1,.....,\eta _l } \right)$ - вектор переменных, двойственных к переменным $\xi = \left( {\xi _1 ,.....,\xi _l } \right)$. Как и в прошлый раз, условия Куна-Таккера сводят задачу к поиску седловой точки функции Лагранжа:
$$\left\{ {\begin{array}{*{20}c} {\Lambda \left( {w,w_0 ,\xi ;\lambda ,\eta } \right) \to \min _{w,w_0 ,\xi } \max _{\lambda ,\eta } } \\ \begin{array}{l} \xi _i \ge 0,{\rm }\lambda _i \ge 0,{\rm }\eta _i \ge {\rm 0}{\rm , }i = 1,....,l{\rm } \\ \lambda _i = 0,{\rm } \vee {\rm }y_i \left( {\left\langle {w,x_i } \right\rangle - w_0 } \right) = 1 - \xi _i ,{\rm }i = 1,....,l \\ \eta _i = 0{\rm } \vee {\rm }\xi _i {\rm = 0}{\rm , }i = 1,....,l \\ \end{array} \\ \end{array}} \right.$$В последних двух строках записаны условия дополняющей нежёсткости. Необходимым условием седловой точки является равенство нулю производных Лагранжиана. Отсюда получаются три полезных соотношения:
$$\frac{{\partial \Lambda }}{{\partial w}} = w - \sum\limits_{i = 1}^l {\lambda _i } y_i x_i = 0{\rm } \Rightarrow {\rm }w = \sum\limits_{i = 1}^l {\lambda _i } y_i x_i\;\;\;(11)$$$$\frac{{\partial \Lambda }}{{\partial w_0 }} = - \sum\limits_{i = 1}^l {\lambda _i } y_i = 0{\rm } \Rightarrow {\rm }\sum\limits_{i = 1}^l {\lambda _i } y_i = 0\;\;\;(12)$$$$\frac{{\partial \Lambda }}{{\partial \xi _i }} = - \lambda _i - \eta _i + C = 0{\rm } \Rightarrow {\rm }\lambda _i + \eta _i = C,{\rm }i = 1,....,l\;\;\;(13)$$Первые два соотношения в точности такие же, как и в линейно разделимом случае. Из третьего соотношения и неравенства $η_i > 0$ следует ограничение $\lambda _i \le C$. Отсюда, и из условий дополняющей нежёсткости вытекает, что возможны только три допустимых сочетания значений переменных $ξ_i, λ_i, η_i$ и отступов $m_i$.
Соответственно, все объекты $x_i, i = 1, . . . , l$ делятся на следующие три типа:
Объект $x_i$ классифицируется правильно и находится далеко от разделяющей полосы. Такие объекты будем называть периферийными.
Объект $x_i$ классифицируется правильно и лежит в точности на границе разде- ляющей полосы. Такие объекты, как и раньше, будем называть опорными.
Объект $x_i$ либо лежит внутри разделяющей полосы, но классифицируется пра вильно ($0 < ξ_i < 1, 0 < m_i < 1$), либо попадает на границу классов ($ξ_i = 1, m_i = 0$), либо вообще относится к чужому классу ($ξ_i > 1, m_i < 0$). Во всех этих случаях объект $x_i$ будем называть нарушителем
В силу соотношения (13) в Лагранжиане обнуляются все члены, содержащие переменные $ξ_i$ и $η_i$, и он принимает тот же вид, что и в случае линейной разделимости. Параметры разделяющей поверхности $w$ и $w_0$, согласно формулам (11) и (12), также выражаются только через двойственные переменные $λ_i$. Таким образом, задача снова сводится к квадратичному программированию относительно двойственных переменных $λ_i$. Единственное отличие от линейно разделимого случая состоит в появлении ограничения сверху $\lambda _i \le C$:
$$\left\{ {\begin{array}{*{20}c} { - \Lambda \left( \lambda \right) = - \sum\limits_{i = 1}^l {\lambda _i + \frac{1}{2}\sum\limits_{i = 1}^l {\sum\limits_{j = 1}^l {\lambda _i \lambda _j y_i y_j \left\langle {x_i ,x_j } \right\rangle \to \mathop {\min }\limits_\lambda } } } } \\ {0 \le \lambda _i \le C,{\rm }i = 1,....,l} \\ {\sum\limits_{i = 1}^l {\lambda _i y{}_i = 0{\rm }} } \\ \end{array}} \right.\;\;\;(14)$$На практике для построения SVM решают именно эту задачу, а не (6), так как гарантировать линейную разделимость выборки в общем случае не представляется возможным. Этот вариант алгоритма называют SVM с мягким зазором (soft-margin SVM), тогда как в линейно разделимом случае говорят об SVM с жёстким зазором (hard-margin SVM).
Для алгоритма классификации сохраняется формула (8), с той лишь разницей, что теперь ненулевыми $λ_i$ обладают не только опорные объекты, но и объекты-нарушители. В определённом смысле это недостаток SVM, поскольку нарушителями часто оказываются шумовые выбросы, и построенное на них решающее правило,по сути дела, опирается на шум.
Константу $C$ обычно выбирают по критерию скользящего контроля. Это трудоёмкий способ, так как задачу приходится решать заново при каждом значении $C$.
Если есть основания полагать, что выборка почти линейно разделима, и лишь объекты-выбросы классифицируются неверно, то можно применить фильтрацию выбросов. Сначала задача решается при некотором $C$, и из выборки удаляется небольшая доля объектов, имеющих наибольшую величину ошибки $ξ_i$. После этого задача решается заново по усечённой выборке. Возможно, придётся проделать несколько таких итераций, пока оставшиеся объекты не окажутся линейно разделимыми.
Ядра и спрямляющие пространства.
Существует ещё один подход к решению проблемы линейной неразделимости. Это переход от исходного пространства признаковых описаний объектов $X$ к новому пространству $H$ с помощью некоторого преобразования $\varphi: X → H$. Если пространство $H$ имеет достаточно высокую размерность, то можно надеяться, что в нём выборка окажется линейно разделимой (легко показать, что если выборка $X^l$ не противоречива, то всегда найдётся пространство размерности не более $l$, в котором она будет линейно разделима). Пространство $H$ называют спрямляющим. Если предположить, что признаковыми описаниями объектов являются векторы $\varphi(x_i)$, а не векторы $x_i$, то построение SVM проводится точно так же, как и ранее.Единственное отличие состоит в том, что скалярное произведение $\left\langle {x,x'} \right\rangle$ в пространстве $X$ всюду заменяется скалярным произведением $\left\langle {\varphi (x),\varphi (x')} \right\rangle$ в пространстве $H$. Отсюда вытекает естественное требование: пространство $H$ должно быть наделено скалярным произведением, в частности, подойдёт любое евклидово, а в общем случае и гильбертово, пространство.
Опр.2. Функция $K: X × X → R$ называется ядром (kernel function), если она представима в виде $K\left( {x,x'} \right) = \left\langle {\varphi (x),\varphi (x')} \right\rangle$ при некотором отображении $\varphi: X → H$, где $H$ - пространство со скалярным произведением.
Постановка задачи (14), и сам алгоритм классификации (8) зависят только от скалярных произведений объектов, но не от самих признаковых описаний. Это означает, что скалярное произведение $\left\langle {x,x'} \right\rangle$ можно формально заменить ядром $K(x, x′)$. Поскольку ядро в общем случае нелинейно, такая замена приводит к существенному расширению множества реализуемых алгоритмов $a: X → Y$.
Более того, можно вообще не строить спрямляющее пространство $H$ в явном виде, и вместо подбора отображения $\varphi$ заниматься непосредственно подбором ядра.Можно пойти ещё дальше, и вовсе отказаться от признаковых описаний объек- тов. Во многих практических задачах объекты изначально задаются информацией об их попарном взаимоотношении, например, отношении сходства. Если эта информация допускает представление в виде двуместной функции $K(x, x′)$, удовлетворяю- щей аксиомам скалярного произведения, то задача может решаться методом SVM. Для такого подхода был придуман термин беспризнаковое распознавание (featureless recognition), хотя многие давно известные метрические алгоритмы клас- сификации (kNN, RBF и др.) также не требуют задания признаковых описаний.
Любая ли функция двух аргументов $K(x, x′)$ может исполнять роль ядра? Следующая теорема даёт исчерпывающий ответ на этот вопрос и показывает, что класс допустимых ядер достаточно широк
Теорема 1 (Мерсер, 1909). Функция $K(x, x′)$ является ядром тогда и только тогда, когда она симметрична, $K(x, x′) = K(x′, x)$, и неотрицательно определена: $\int\limits_X {\int\limits_X {K\left( {x,x'} \right)} } g\left( x \right)g\left( {x'} \right)dxdx' \ge 0$ для любой функции $g:X \to R$
Существует эквивалентное определение неотрицательной определённости.
Опр.3. Функция $K(x, x′)$ неотрицательно определена, если для любой конечной выборки $X^p = (x_1, . . . , x_p)$ из $X$ матрица $K = \left\| {K\left( {x_i ,x_j } \right)} \right\|$ размера $p × p$ неотрицательно определена: $z^T Kz \ge 0$ для любого $z ∈ R^p$.
Проверка неотрицательной определённости функции в практических ситуациях может оказаться делом нетривиальным. Часто ограничиваются перебором конечного числа функций, про которые известно, что они являются ядрами. Среди них выбирается лучшая, как правило, по критерию скользящего контроля. Очевидно, что это не оптимальное решение. На сегодняшний день проблема выбора ядра, оптимального для данной конкретной задачи, остаётся открытой.
Следующие правила порождения позволяют строить ядра в практических задачах:
Существует несколько 'стандартных' ядер, которые при ближайшем рассмотрении приводят к известным алгоритмам: полиномиальным разделяющим поверхностям, двухслойным нейронным сетям, потенциальным функциям (RBF-сетям), и другим.
Наиболее распространённые ядра:
линейное: $k(x,x')=\left\langle {x,x'} \right\rangle$
полиномиальное: $k\left( {x,x'} \right) = \left( {\gamma \left\langle {x,x'} \right\rangle + r} \right)^d$
радиальная базисная функция: $k\left( {x,x'} \right) = \exp \left( { - \gamma \left\| {x - x'} \right\|^2 } \right),\gamma > 0$
радиальная базисная функция Гаусса: $k\left( {x,x'} \right) = \exp \left( { - \frac{{\left\| {x - x'} \right\|^2 }}{{2\sigma ^2 }}} \right)$
сигмовидная : $k\left( {x,x'} \right) = \tanh \left( {\gamma \left\langle {x,x'} \right\rangle + r} \right)$, для почти всех $\gamma >0$ и $r<0$
Ядра претендуют на роль универсального языка для описания широкого класса алгоритмов обучения по прецедентам. Наблю- дается парадоксальная ситуация. С одной стороны, ядра одно из самых красивых и плодотворных изобретений в машинном обучении. С другой стороны, до сих пор не найдено эффективного общего подхода к их подбору в конкретных задачах.
Преимущества SVM перед методом стохастического градиента.
Вместо многоэкстремальной задачи решается задача квадратичного программирования, имеющая единственное решение. Методы оптимизации в этом случае существенно более эффективны.
Автоматически определяется число нейронов скрытого слоя. Оно равно числу опорных векторов.
Принцип оптимальной разделяющей гиперплоскости приводит к максимизации ширины разделяющей полосы между классами, следовательно, к более уверенной классификации. Градиентные нейросетевые методы выбирают положение разделяющей гиперплоскости произвольным образом, 'как придётся
Недостатки SVM.
Метод опорных векторов неустойчив по отношению к шуму в исходных данных. Если обучающая выборка содержат шумовые выбросы, они будут существенным образом учтены при построении разделяющей гиперплоскости. Этого недостатка лишён метод релевантных векторов (relevance vector machine, RVM).
До сих пор не разработаны общие методы построения спрямляющих пространств или ядер, наиболее подходящих для конкретной задачи. Построение адекватного ядра является искусством и, как правило, опирается на априорные знания о предметной области. На практике 'вполне разумные' функции $K(x, x′)$, выведенные из содержательных соображений, далеко не всегда оказываются положительно определёнными.
В общем случае, когда линейная разделимость не гарантируется, приходится подбирать управляющий параметр алгоритма $C$.
Алгоритм настройки SVM.
Двойственная задача (14) является задачей квадратичного программирования. Общие методы решения таких задач известны, но довольно трудоёмки, как в смысле реализации, так и по времени выполнения. Поэтому для обучения SVM применяются алгоритмы, учитывающие специфические особенности SVM. Специфика заключается в том, что число опорных векторов $h$, как правило, невелико, $h ≪ l$,и эти векторы находятся поблизости от границы классов. Именно эти особенности и позволяют ускорить поиск опорных объектов. Специализированные алгоритмы настройки SVM успешно справляются с выборками из десятков тысяч объектов. Здесь мы рассмотрим не самый известный, но также довольно эффективный алгоритм - последовательный метод активных ограничений (incremental active set method, INCAS).
Перепишем двойственную задачу (14) в матричных обозначениях. Введём матрицу $Q = \left( {y{}_iy_j K\left( {x_i ,x_j } \right)} \right)_{i = 1,l}^{j = 1,l}$ размера $l × l$ и три вектор-столбца длины $l$: вектор ответов $y = \left( {y_i } \right)_{i = 1,l}$ , вектор двойственных переменных $\lambda = \left( {\lambda _i } \right)_{i = 1,l}$ и вектор единиц $e = \left( 1 \right)_{i = 1,l}$ . Тогда задачу (1.14) можно переписать в виде:
$$\left\{ {\begin{array}{*{20}c} {\frac{1}{2}\lambda ^T Q\lambda - e^T \lambda \to \mathop {\min }\limits_\lambda } \\ {y^T \lambda = 0} \\ {0 \le \lambda \le C_e } \\ \end{array}} \right.\;\;\;(15)$$Допустим, что решение $λ$ ещё не известно, но зато известно разбиение множества объектов на три непересекающихся подмножества $\left\{ {1,....,l} \right\} = I_O \cup I_C \cup I_S$:
$I_O = \left\{ {i:\lambda {}_i = 0} \right\}$ -периферийные объекты, $m_i > 1$;
$I_S = \left\{ {i:0 < \lambda {}_i < C} \right\}$ -опорные объекты, $m_i = 1$;
$I_C = \left\{ {i:\lambda {}_i = C} \right\}$ -объекты-нарушители, $m_i < 1$;
где $m_i = y_i \left( {\left\langle {w,x_i } \right\rangle - w_0 } \right)$ отступ объекта $x_i$ от границы классов.
Ограничения-неравенства $0 \le \lambda _i \le C$ становятся активными, то есть обращаются в равенства, на периферийных объектах ($i \in I_O ,\lambda _i = 0$) и объектах - нарушителях ($i \in I_C ,\lambda _i = C$). Соответствующие значения $λ_i$ можно подставить обратно в (15) и получить оптимизационную задачу, зависящую только от части переменных $\lambda _i ,i \in I_S$. Чтобы выписать эту задачу в матричном виде, введём трёхблочные обозначения для матрицы $Q$ и векторов $y, e, λ$:
$$Q = \left( {\begin{array}{*{20}c} {Q_{SS} } & {Q_{SO} } & {Q_{SC} } \\ {Q_{OS} } & {Q_{OO} } & {Q_{OC} } \\ {Q_{CS} } & {Q_{CO} } & {Q_{CC} } \\ \end{array}} \right); y = \left( {\begin{array}{*{20}c} {y_S } \\ {y_O } \\ {y_C } \\ \end{array}} \right);e = \left( {\begin{array}{*{20}c} {e_S } \\ {e_O } \\ {e_C } \\ \end{array}} \right);\lambda = \left( {\begin{array}{*{20}c} {\lambda _S } \\ {\lambda _O } \\ {\lambda _C } \\ \end{array}} \right)$$В этих обозначениях задача (15) принимает вид:
$$\left\{ {\begin{array}{*{20}c} {\frac{1}{2}\lambda _S^T Q_{SS} \lambda _S + Ce_C^T Q_{CS} - e_S^T \lambda _S \to \mathop {\min }\limits_{\lambda _S } } \\ {y_S^T \lambda _S + Ce_C^T y_C = 0} \\ \end{array}} \right.\;\;\;(16)$$Если не обращать внимания на ограничения-неравенства, то это задача минимизации квадратичного функционала от $h = |I_S|$ переменных с одним линейным ограничением типа равенства. Она легко решается стандартными методами линейной алгебры и сводится, фактически, к обращению симметричной положительно определённой матрицы $Q_{SS}$ размера $h × h$.
Решение этой задачи даёт весь вектор $\lambda$, что позволяет вычислить параметры алгоритма $w$ и $w_0$ по формулам (4) и (7). Теперь можно классифицировать объекты выборки $x_i$, вычислить отступы $m_i$, и проверить, правильно ли множество объектов было разбито на подмножества $I_O ∪ I_C ∪ I_S$. Если условия Куна-Таккера не нарушатся ни на одном объекте, значит, решение задачи (15) найдено. Если же обнаружится хотя бы одно противоречие, то соответствующий объект должен быть переведён из одного подмножества в другое.
Всего возможны четыре типа противоречий:
После каждой модификации множеств $I_O, I_C, I_S$ задача (16) решается заново. Итерационный процесс перевода объектов из одного множества в другое продолжается до тех пор, пока все объекты не будут удовлетворять условиям Куна-Таккера. Описанный процесс является частным случаем метода активных ограничений (active sets method), который применяется для решения произвольных задач математического программирования с ограничениями-неравенствами. В линейном программировании он эквивалентен симплекс-методу. Сходимость данного метода в общем случае не гарантируется, однако в задачах настройки SVM зацикливания случаются крайне редко и легко предотвращаются с помощью нескольких удачных эвристик.Неплохая эвристика заключается в том, чтобы на каждом шаге выбирать объект $i$, для которого условие Куна-Таккера нарушается сильнее всего. Это способствует увеличению скорости сходимости.
Количество итераций существенно зависит от того, насколько удачным окажется начальное приближение. На практике применяются различные приёмы, чтобы сразу поточнее 'угадать' множество опорных векторов $I_S$.
Приём 1. Выбирается произвольная точка выборки, и находится ближайшая к ней точка другого класса. Для неё, в свою очередь, находится ближайшая точка в первом классе, и т. д. Этот итерационный процесс, как правило, сходится очень быстро к некоторой паре пограничных точек. В Алгоритме 1 эта пара принимается за начальное приближение $I_S$, но можно и продолжить процесс, построив несколько или даже все такие пары.
Приём 2. Строится несколько достаточно грубых линейных классификаторов.Для этого можно использовать однослойные персептроны, проводя небольшое число итераций методом стохастического градиента. Затем для каждой линейной разделя- ющей поверхности находится несколько ближайших к ней точек.
Алгоритм 1. Обучение SVM: последовательный метод активных ограничений
Вход:
$X^l$ - обучающая выборка;
$C$ - параметр двойственной задачи;
Выход:
параметры линейного классификатора $w, w_0$;
$I_S =$ две ближайшие точки из разных классов; $I_O =$ все остальные точки; $I_C = \emptyset$;
2: повторять
3: повторять
4: решение оптимизационной задачи относительно $λ_S$:
$$\left\{ {\begin{array}{*{20}c} {\frac{1}{2}\lambda _S^T Q_{SS} \lambda _S + Ce_C^T Q_{CS} - e_S^T \lambda _S \to \mathop {\min }\limits_{\lambda _S } } \\ {y_S^T \lambda _S + Ce_C^T y_C = 0} \\ \end{array}} \right.$$
5: если $|I_S| > 2$ и $∃i: i ∈ I_S$ и $\lambda _i \le 0$ то перевести $i$ в $I_O$;
6: если $|I_S| > 2$ и $∃i: i ∈ I_S$ и $\lambda _i \ge C$ то перевести $i$ в $I_C$;
7: пока существует $i ∈ I_S$, который необходимо перевести в $I_O$ или в $I_C$;
8: вычислить параметры алгоритма $w$ и $w_0$ по формулам (4) и (7);
9: вычислить отступы $m_i$, $i ∈ I_0 ∪ I_C$;
10: если $∃i: i ∈ I_O$ и $m_i \le 1$ то перевести $i$ в $I_S$;
11: если $∃i: i ∈ I_C$ и $m_i \ge 1$ то перевести $i$ в $I_S$;
12: пока существует $i ∈ I_O ∪ I_C$, который необходимо перевести в $I_S$;
Высокая эффективность Алгоритма 1 вытекает из двух фактов. Во-первых, оптимизационная задача, решаемая на шаге 4, зависит только от матриц $Q_{SS}$ и $Q_{CS}$. Значит, вычислять скалярные произведения $K(x, x′)$ приходится только для пар объектов типа 'опорный–опорный' и 'опорный–нарушитель'.Во-вторых, множество $I_S$ на каждом шаге изменяется только на один элемент.Это позволяет выполнять пересчёт обратной матрицы $Q_{SS}^{ - 1}$ за $O(h^2)$ операций, тогда как обычное обращение потребовало бы $O(h^3)$ операций.
Преимущества метода INCAS.
Метод позволяет решать задачи, в которых нет линейной разделимости, в том числе задачи с шумовыми выбросами.
Метод особенно эффективен, когда число опорных векторов $h = |I_S|$ невелико.
Метод хорошо приспособлен для решения таких задач, в которых обучающие объекты поступают по одному в режиме реального времени. Добавление нового объекта реализуется практически так же, как перевод объекта из одного подмножества в другое, и требует порядка $O(h^2)$ операций
Недостатки метода INCAS.
Мультиклассовые методы опорных векторов
В своем исходном виде SVM не поддерживает многоклассовую классификацию. Для этого дополнительно разработано несколько мультиклассовых методов SVM:
OvR «один против остальных»
OvO «один против одного»
DAGSVM ( Directed Acyclic Graph SVM) "SVM с поддержкой направленного ациклического графа"
Метод Крамера и Зингера
Метод OvR.
Самой ранней реализацией многоклассовой классификации SVM, вероятно, является метод «один против всех». Он строит k моделей SVM, где k — количество классов.M-тый SVM обучается на всех примерах с положительными метками m-го класса и на всех остальных примерах с отрицательными метками. Таким образом, учитывая $l$ данных обучения $(x_1, y_1),...., (x_l, y_l)$ где $x_i \in R^n$ ,$i = 1,....,l$ и $y_i \in \left\{ {1,....,k} \right\}$ $x_i$ относится к m-му классу, m-й SVM решает следующую задачу:
$$\left\{ {\begin{array}{*{20}c} {\frac{1}{2}\left( {w^m } \right)^T w^m + C\sum\limits_{i = 1}^l {\xi _i^m {\rm } \to {\rm }\mathop {\min }\limits_{w^m ,b^m ,\xi ^m } } } \\ \begin{array}{l} \left( {w^m } \right)^T \phi \left( {x_i } \right) + b^m \ge 1 - \xi _i^m ,{\rm }if{\rm }y_i = m \\ \left( {w^m } \right)^T \phi \left( {x_i } \right) + b^m \le - 1 + \xi _i^m ,{\rm }if{\rm }y_i \ne m \\ \xi _i^m \ge 0,{\rm }i = 1,....,l \\ \end{array} \\ \end{array}} \right.\;\;\;(1)$$где обучающие данные $x_i$ отображаются в пространство более высокой размерности с помощью функции $\phi$, а $C$ — штрафной параметр.
Минимизация ${\frac{1}{2}\left( {w^m } \right)^T w^m }$ означает, что мы хотим максимизировать $2/\left\| {w^m } \right\|$, разницу между двумя группами данных. Когда данные не являются линейно разделимыми, существует штрафной член $C\sum\limits_{i = 1}^l {\xi _i^m {\rm }}$ ,который может уменьшить количество ошибок обучения. Основная концепция SVM стоит состоит в поиске баланса между членом регуляризации ${\frac{1}{2}\left( {w^m } \right)^T w^m }$ и ошибками обучения.
После решения (1) имеется k решающих функций:
$$\begin{array}{*{20}c} {\left( {w^1 } \right)^T \phi \left( x \right) + b^1 } \\ {...} \\ {\left( {w^k } \right)^T \phi \left( x \right) + b^k } \\ \end{array}$$Мы говорим, что $x$ находится в классе, который имеет наибольшее значение решающей функции:
$$class{\rm }\;\;of\;\;{\rm }x \equiv \mathop {\arg \max }\limits_{m = 1,....,k} \left( {\left( {w^k } \right)^T \phi \left( x \right) + b^k } \right),\;\;\;(2)$$Практически мы решаем двойственную задачу (1), в которой количество переменных совпадает с количеством данных в (1). Таким образом, решены задачи квадратичного программирования с k l-переменными.
Метод OvO.
Другой важный метод называется методом «один против одного». Этот метод создает $k(k- 1)/2$ классификаторов, каждый из которых обучается на данных из двух классов. Для обучающих данных $i$-го и $j$-го классов мы решаем следующую задачу бинарной классификации:
$$\left\{ {\begin{array}{*{20}c} {\frac{1}{2}\left( {w^{ij} } \right)^T w^{ij} + C\sum\limits_i {\xi _t^{ij} \to \mathop {\min }\limits_{w^{ij} ,b^{ij} ,\xi ^{ij} } } } \\ \begin{array}{l} \left( {w^{ij} } \right)^T \phi \left( {x_t } \right) + b^{ij} \ge 1 - \xi ^{ij} {\rm , }if{\rm }y_t = i \\ \left( {w^{ij} } \right)^T \phi \left( {x_t } \right) + b^{ij} \le - 1 + \xi ^{ij} {\rm , }if{\rm }y_t = j \\ \xi ^{ij} \ge 0 \\ \end{array} \\ \end{array}} \right.\;\;\;(3)$$Существуют разные методы проведения будущего тестирования после того, как построены все классификаторы $k(k-1)/2$. Можно использовать следующую стратегию голосования.Если $sign\left( {\left( {w^{ij} } \right)^T \phi \left( x \right) + b^{ij} } \right)$ говорит, что x принадлежит i-му классу, то добавляется голос за i-й класс. В противном случае j-ое увеличивается на единицу. Затем мы прогнозируем, что x принадлежит к классу с наибольшим количеством голосов. Подход к голосованию, описанный выше также называется стратегией «Максимум побед». В случае, если два класса имеют одинаковые голоса, хотя это может быть не очень хорошей стратегией, теперь мы просто выбираем тот, у которого меньший индекс.
Практически мы решаем двойственное уравнение (3), в котором количество переменных совпадает с количеством данных в двух классах. Следовательно, если в среднем каждый класс имеет $l/k$ точек данных, нам нужно решить $k(k-1)/2$ задач квадратичного программирования, где каждая из них имеет около $2l/k$ переменных.
Метод DAGSVM
Третий алгоритм, обсуждаемый здесь, — это машины опорных векторов направленных ациклических графов (DAGSVM). Фаза его обучения такая же, как и у метода «один против одного», путем решения $k(k-1)/2$ двоичных SVM. Однако на этапе тестирования он использует корневой бинарно-направленный ациклический граф, который имеет $k(k-1)/2$ внутренних узла и $k$ листьев. Каждый узел представляет собой двоичную SVM $i$-го и $j$-го классов. Учитывая тест выборка x, начиная с корневого узла, оценивает функцию двоичного решения. Затем он перемещается влево или вправо в зависимости от выходного значения. Следовательно, мы проходим определенный путь, прежде чем достичь листового узла, который указывает предсказанный класс.
Преимущество использования DAG заключается в том, что можно провести некоторый анализ обобщений. Аналогичных теоретических результатов для методов «один против всех» и «один против одного» пока нет. Кроме того, время его тестирования меньше, чем у метода «один против одного».
Метод Крамера и Зингера.
Краммер и Сингер предложили подход к решению многоклассовых задач путем решения одной задачи оптимизации.По сути решается следующая основная задача:
$$\left\{ {\begin{array}{*{20}c} {\mathop {\min }\limits_{w_m ,\xi _i } \frac{1}{2}\sum\limits_{m = 1}^k {w_m^T w_m } + C\sum\limits_{i = 1}^l {\xi _i } } \\ {w_{y{}_i}^T \phi \left( {x_i } \right) - w_m^T \phi \left( {x_i } \right) \ge e_i^m - \xi _i ,i = 1,...,l} \\ \end{array}} \right.\;\;\;(4)$$где $e_i^m \equiv 1 - \delta _{y_i ,m}$ и
$$\delta _{y_i ,m} \equiv \left\{ {\begin{array}{*{20}c} {1{\rm }if{\rm }y_i = m} \\ {0{\rm }if{\rm }y_i \ne m} \\ \end{array}} \right.$$Тогда решающая функция:
$$\mathop {\arg \max \left( {w_m^T \phi \left( x \right)} \right)}\limits_{m = 1,...,k}$$В (4)
$$\xi _i = \left( {\mathop {\max \left( {w_m^T \phi \left( {x_i } \right) + e_i^m } \right) - w_y^T \phi \left( {x_i } \right)}\limits_m } \right)_ +$$где $\left( . \right)_ + \equiv \max \left( {.,0} \right),\xi _i \ge 0$ когда $y_i = m,e_i^m = 0$
Двойственная задача (4) такова:
$$\mathop {\min }\limits_\alpha f\left( \alpha \right) = \frac{1}{2}\sum\limits_{i = 1}^l {\sum\limits_{j = 1}^l {K_{i,j} } } \bar \alpha _i^T \bar \alpha _J + \sum\limits_{i = 1}^l {\bar \alpha _i^T \bar e_i }\;\;\;(5)$$$$\sum\limits_{m = 1}^k {\alpha _i^m } = 0,i = 1,...,l\;\;\;(5a)$$$$\left\{ {\begin{array}{*{20}c} {\alpha _i^m \le 0,{\rm }if{\rm }y_i \ne m} \\ {\alpha _i^m \le C,{\rm }if{\rm }y_i = m} \\ {i = 1,....,l,{\rm }m = 1,...k} \\ \end{array}} \right.\;\;\;(5b)$$Где $K_{i,j} \equiv \phi \left( {x_i } \right)^T \phi \left( {x_j } \right)$ , $\bar \alpha {}_i \equiv \left[ {\alpha _i^1 ,....,\alpha _i^k } \right]^T , \wedge \bar e_i \equiv \left[ {e_i^1 ,....,e_i^k } \right]^T$
Тогда $w_m = \sum\limits_{i = 1}^l {\alpha _i^m } \phi \left( {x_i } \right)$ . Если записать $\alpha \equiv \left[ {\alpha _1^1 ,....,\alpha _1^k ,....,\alpha _l^1 ,....,\alpha _l^k } \right]^T$ и $e \equiv \left[ {e_1^1 ,....,e_1^k ,....,e_l^1 ,....,e_l^k } \right]^T$
тогда двойную целевую функцию можно записать как:
$$\frac{1}{2}\alpha ^T \left( {K \otimes I} \right)\alpha + e^T \alpha$$где $I$ — единичная матрица размера $k$ на $k$, а $ \otimes$ — произведение Кронекера. Поскольку $K$ положительно полуопределен, $K\otimes I$, гессиан двойственной целевой функции также является положительно полуопределенным. Это еще один способ объяснить, что (5) представляет собой задачу выпуклой оптимизации.
Функция принятия решения:
$$\mathop {\arg \max }\limits_{m = 1,...,k} \sum\limits_{i = 1}^l {\alpha _i^m K\left( {x_i ,x} \right)}$$Если выбирать в рабочем наборе $k$ переменных, связанных с одним и тем же $x_i$. То есть $\alpha _i^1 ,....,\alpha _i^k$ элементы рабочего набора, выбор индекса $i$ которого будет обсуждаться ниже. Тогда подзадача:
$$\left\{ {\begin{array}{*{20}c} {\min \frac{1}{2}A\bar \alpha _i^T \bar \alpha _i + B^T \bar \alpha _i } \\ {\sum\limits_{i = 1}^k {\alpha _i^m = 0} } \\ {\alpha _i^m \le C_{y_i }^m ,{\rm }m = 1,....,k} \\ \end{array}} \right.\;\;\;(6)$$Где $A = K_{i,i}$ и $B = \bar e_i + \sum\limits_{j \ne i} {K_{j,i} } \bar \alpha _j$
Кроме того, $\bar C_{y_i }^m ,m = 1,....,k$ — вектор размером k на 1, все элементы которого равны нулю, за исключением того, что $y_i$-й компонент равен $C$.
Основная причина такой постановки в том, что (6) представляет собой очень простую задачу.Для (6) был предложен алгоритм,который используется ниже.Градиент двойной целевой функции равен:
$$\left[ {\begin{array}{*{20}c} {\sum\limits_{j = 1}^l {K_{1,j} \alpha _j^1 + e_1^1 } } \\ \begin{array}{l} ... \\ \sum\limits_{j = 1}^l {K_{1,j} \alpha _j^k + e_1^k } \\ \sum\limits_{j = 1}^l {K_{2,j} \alpha _j^1 + e_2^1 } \\ ... \\ \sum\limits_{j = 1}^l {K_{2,j} \alpha _j^k + e_2^k } \\ ... \\ \end{array} \\ \end{array}} \right]$$Тогда $B$, вектор $k$ на 1, можно вычислить по информации градиента следующим образом:
$$B_m = \frac{{\partial f\left( \alpha \right)}}{{\partial \alpha _i^m }} - K_{i,i} \alpha _i^m = \frac{{\partial f\left( \alpha \right)}}{{\partial \alpha _i^m }} - A\alpha _i^m ,m = 1,....,k$$Во время итераций важно всегда обновлять градиент. Это делается после нового $\alpha _i^1 ,....,\alpha _i^k$, который получается с помощью (6) и ,следовательно, требуется $O(kl)$ операций.
Далее мы обсудим выбор рабочего набора и условие остановки метода декомпозиции. Условие ККТ требует наличия $b_1 ,....,b_l$ и $\lambda _1^1 \ge 0,....,\lambda _l^k \ge 0$ таких, что для всех $i = 1,....,l,m = 1,....,k$,
$$\sum\limits_{j = 1}^l {K_{i,j} } \alpha _j^m + e_i^m - b_i = - \lambda _i^m {\rm } \wedge {\rm }\lambda _i^m \left( {\bar C_{y_i }^m - \alpha _i^m } \right) = 0$$Тогда для всех $i = 1,....,l,m = 1,....,k$,
$$\sum\limits_{j = 1}^l {K_{i,j} } \alpha _j^m + e_i^m - b_i \left\{ {\begin{array}{*{20}c} { = 0{\rm }if{\rm }\alpha _i^m {\rm < \bar C}_{{\rm y}_{\rm i} }^{\rm m} {\rm }} \\ { \le 0{\rm }if{\rm }\alpha _i^m {\rm = \bar C}_{{\rm y}_{\rm i} }^{\rm m} } \\ \end{array}} \right.$$Мы можем переписать это как
$$\mathop {{\rm max}}\limits_{\alpha _i^m \le C_{y_i }^m } \left( {\sum\limits_{j = 1}^l {K_{i,j} } \alpha _j^m + e_i^m } \right) \le b_i \le \mathop {{\rm min}}\limits_{\alpha _i^m \le C_{y_i }^m } \left( {\sum\limits_{j = 1}^l {K_{i,j} } \alpha _j^m + e_i^m } \right)\;\;\;(7)$$Затем в ходе итераций выбираем следующий рабочий набор $\left\{ {\alpha _i^1 ,....,\alpha _i^k } \right\}$ из
$$\arg \max \left( {\mathop {{\rm max}}\limits_{\alpha _i^m \le C_{y_i }^m } \left( {\sum\limits_{j = 1}^l {K_{i,j} } \alpha _j^m + e_i^m } \right) - \mathop {{\rm min}}\limits_{\alpha _i^m \le C_{y_i }^m } \left( {\sum\limits_{j = 1}^l {K_{i,j} } \alpha _j^m + e_i^m } \right)} \right)\;\;\;(8)$$Другими словами, среди $lk$-компонентных групп переменных выберем ту, которая имеет наибольшее нарушение условия ККТ. Тогда решение подзадачи (6) будет гарантировать строгое уменьшение целевой функции двойственной задачи.
Следуя (7), критерием остановки может быть:
$$\mathop {\max }\limits_i \left( {\mathop {{\rm max}}\limits_{\alpha _i^m \le C_{y_i }^m } \left( {\sum\limits_{j = 1}^l {K_{i,j} } \alpha _j^m + e_i^m } \right) - \mathop {{\rm min}}\limits_{\alpha _i^m \le C_{y_i }^m } \left( {\sum\limits_{j = 1}^l {K_{i,j} } \alpha _j^m + e_i^m } \right)} \right) < \varepsilon\;\;\;(9)$$где $\varepsilon$ останавливающий допуск
Сходимость описанного метода декомпозиции доказана так как предел (9) стремиться к нулю при числе реализаций стремящемся к бесконечности.Следовательно, за конечное число итераций метод декомпозиции останавливается, поскольку (9) выполняется.
Алгоритм SVC реализован в виде одного из пакетов модуля sklearn.svm. Для его использования необходимо загрузить пакет:
from sklearn.svm import SVC
Реализация основана на libsvm. Время подгонки масштабируется как минимум квадратично с количеством выборок и может быть непрактичным, если выборки составляют десятки тысяч. Поддержка мультиклассов осуществляется по схеме «один против одного».
Вызов:
SVC(C=1.0, kernel='rbf', degree=3, gamma='scale', coef0=0.0, shrinking=True, probability=False, tol=0.001, cache_size=200, class_weight=None, verbose=False, max_iter=-1, decision_function_shape='ovr', break_ties=False, random_state=None)
Параметры:
C float, default=1.0 -Параметр регуляризации. Сила регуляризации обратно пропорциональна C. Должна быть строго положительной. Наказание представляет собой штраф l2 в квадрате.
kernel {'linear', 'poly', 'rbf', 'sigmoid', 'precomputed'} or callable, default='rbf' -Указывает тип ядра, который будет использоваться в алгоритме. Если ничего не указано, будет использоваться «rbf».
degree int, default=3 -Степень полиномиальной ядерной функции («поли»). Должно быть неотрицательным. Игнорируется всеми остальными ядрами.
gamma {'scale', 'auto'} or float, default='scale' - Коэффициент ядра для «rbf», 'poly' и 'sigmoid'.
если gamma='scale'передается (по умолчанию), то в качестве значения gamma используется 1/(n_features * X.var()),
если «auto», используется 1/n_features
если плавающее значение, оно должно быть неотрицательным.
coef0 float, default=0.0 - Независимый член в функции ядра. Это имеет значение только для 'poly' и 'sigmoid'
shrinking bool, default=True - Использовать ли эвристику сжатия.
probability bool, default=False -Включить ли оценку вероятности. Это должно быть включено до вызова fit, это замедлит работу этого метода, поскольку внутри него используется 5-кратная перекрестная проверка и predict_probaможет быть несовместимо с predict.
tol float, default=1e-3 -Допуск критерия остановки.
cache_size float, default=200 -Укажите размер кэша ядра (в МБ).
class_weight dict or 'balanced', default=None - Установите для параметра C класса i значение class_weight[i]C для SVC. Если он не указан, все классы должны иметь вес один. «Сбалансированный» режим использует значения y для автоматической корректировки весов, обратно пропорциональных частотам классов во входных данных как .n_samples / (n_classes p.bincount(y))
verbose bool, default=False -Включить подробный вывод. Обратите внимание, что этот параметр использует настройку времени выполнения каждого процесса в libsvm, которая, если она включена, может работать неправильно в многопоточном контексте.
max_iter int, default=-1 -Жесткое ограничение на количество итераций в решателе или -1 для отсутствия ограничений.
decision_function_shape {'ovo', 'ovr'}, default='ovr' -Возвращать ли функцию принятия решения «один на один» («ovr») формы (n_samples, n_classes), как и все другие классификаторы, или исходную функцию принятия решения «один на один» («ovo») из libsvm, которая имеет форму (n_samples) , n_классов * (n_classes - 1)/2). Однако обратите внимание, что внутри компании «один на один» («ovo») всегда используется как многоклассовая стратегия для обучения моделей; матрица ovr строится только из матрицы ovo. Параметр игнорируется для двоичной классификации.
break_ties bool, default=False -Если true decision_function_shape='ovr'и количество классов > 2, прогнозирование разорвет связи в соответствии со значениями достоверности Decision_function ; в противном случае возвращается первый класс среди связанных классов. Обратите внимание, что разрыв связей требует относительно высоких вычислительных затрат по сравнению с простым прогнозированием.
random_state int, RandomState instance or None, default=None -Управляет генерацией псевдослучайных чисел для перетасовки данных для оценок вероятности. Игнорируется, когда probability имеет значение False. Передайте int для воспроизводимого вывода при нескольких вызовах функций.
Атрибуты :
сlass_weight_ ndarray of shape (n_classes,)-Множители параметра C для каждого класса. Рассчитывается на основе class_weightпараметра.
classes_ ndarray of shape (n_classes,)-Метки классов.
coef_ ndarray of shape (n_classes * (n_classes - 1) / 2, n_features)-Веса, присвоенные объектам, когда kernel="linear".
dual_coef_ ndarray of shape (n_classes -1, n_SV) -Двойные коэффициенты опорного вектора в функции решения, умноженные на их целевые значения. Для мультикласса коэффициент для всех классификаторов 1 на 1. Расположение коэффициентов в мультиклассовом случае несколько нетривиально.
fit_status_ intfit_status_int -0, если установлен правильно, 1 в противном случае (вызовет предупреждение)
intercept_ ndarray of shape (n_classes * (n_classes - 1) / 2,)- Константы в функции решения.
n_features_in_ int -Количество функций, наблюдаемых во время подгонки
feature_names_in_ ndarray of shape (n_features_in_,)-Названия функций, видимых во время подгонки . Определяется только в том случае, если X имена объектов состоят из строк.
n_iter_ ndarray of shape (n_classes * (n_classes - 1) // 2,)-Количество итераций, выполняемых процедурой оптимизации для соответствия модели. Форма этого атрибута зависит от количества оптимизированных моделей, что, в свою очередь, зависит от количества классов.
support_ ndarray of shape (n_SV) -Индексы опорных векторов.
support_vectors_ ndarray of shape (n_SV, n_features) -Опорные векторы. Пустой массив, если ядро рассчитано заранее.
n_support_ ndarray of shape (n_classes,), dtype=int32 -Количество опорных векторов для каждого класса.
probA_ ndarray of shape (n_classes * (n_classes - 1) / 2) -Параметр, полученный при масштабировании Платта, когда probability=True.
probB_ ndarray of shape (n_classes * (n_classes - 1) / 2) -Параметр, полученный при масштабировании Платта, когда probability=True.
shape_fit_ tuple of int of shape (n_dimensions_of_X,) -Размеры массива обучающего вектора X.
Методы :
decision_function(X) -Оцените функцию решения для образцов в X.
Параметры :Форма, подобная массиву X (n_samples, n_features) -Входные образцы.
Возвращает :X ndarray формы (n_samples, n_classes * (n_classes-1)/2) -Возвращает функцию решения выборки для каждого класса модели. Если Decision_function_shape='ovr', форма имеет вид (n_samples, n_classes).
fit(X, y[, sample_weight]) -Подберите модель SVM в соответствии с данными обучения.
Параметры :
X {массив, разреженная матрица} формы (n_samples, n_features) или (n_samples, n_samples) Обучающие векторы, где n_samples– количество выборок, а n_features– количество признаков. Для ядра = «предварительно вычислено» ожидаемая форма X равна (n_samples, n_samples).
y массивообразной формы (n_samples,) Целевые значения (метки классов в классификации, действительные числа в регрессии).
sample_weight имеет форму массива (n_samples), по умолчанию = нет Вес каждой выборки. Измените масштаб C для каждого образца. Более высокие веса вынуждают классификатора уделять больше внимания этим моментам
Возвращает : self object - Установленный оценщик.
get_metadata_routing() -Получите маршрутизацию метаданных этого объекта.
get_params([deep]) -Получите параметры для этой оценки.
predict(X) -Выполните классификацию выборок в X.
Параметры : X {массив, разреженная матрица} формы (n_samples, n_features) или (n_samples_test, n_samples_train)- Для ядра = «предварительно вычислено» ожидаемая форма X — (n_samples_test, n_samples_train).
Возвращает : y_pred ndarray формы (n_samples,) -Метки классов для образцов в X.
predict_log_proba(X) -Вычислите логарифмические вероятности возможных результатов для выборок в X.
Модель должна иметь информацию о вероятности, рассчитанную во время обучения: соответствует атрибуту, probabilityустановленному в значение True.
Параметры : Форма, подобная массиву X (n_samples, n_features) или (n_samples_test, n_samples_train)-Для ядра = «предварительно вычислено» ожидаемая форма X — (n_samples_test, n_samples_train).
Возвращает : Набор форм (n_samples, n_classes) -Возвращает логарифмические вероятности выборки для каждого класса в модели. Столбцы соответствуют классам в отсортированном порядке, как они указаны в атрибутеclass_ .
predict_proba(X) -Вычислите вероятности возможных результатов для выборок в X.
Модель должна иметь информацию о вероятности, рассчитанную во время обучения: соответствует атрибуту, probabilityустановленному в значение True.
Параметры : Форма, подобная массиву X (n_samples, n_features) -Для ядра = «предварительно вычислено» ожидаемая форма X — (n_samples_test, n_samples_train).
Возвращает : Набор форм (n_samples, n_classes) -Возвращает вероятность выборки для каждого класса модели. Столбцы соответствуют классам в отсортированном порядке, как они указаны в атрибутеclass_ .
score(X, y[, sample_weight]) -Возвращает среднюю точность данных испытаний и меток.
Параметры :
Форма, подобная массиву X (n_samples, n_features)-Тестовые образцы.
y массивообразной формы (n_samples,) или (n_samples, n_outputs)-Настоящие этикетки для X.
sample_weight имеет форму массива (n_samples), по умолчанию = нет -Образцы весов.
Возвращает : score float -Средняя точность
set_fit_request(.[, sample_weight]) -Метаданные запроса, передаваемые в fitметод.
set_params(*.params) - Установите параметры этой оценки.
set_score_request(*[, sample_weight]) -Метаданные запроса, передаваемые в score метод.
Особенности реализаци и установка параметров
Машины опорных векторов в scikit-learn поддерживают как плотные ( numpy.ndarrayи конвертируемые в них numpy.asarray) так и разреженные (любые scipy.sparse) выборочные векторы в качестве входных данных. Однако, чтобы использовать SVM для прогнозирования разреженных данных, он должен быть адаптирован к таким данным. Для оптимальной производительности используйте C-упорядоченный numpy.ndarray(плотный) или scipy.sparse.csr_matrix(разреженный) с dtype=float64
SVC представляют собой алгоритм, способный выполнять бинарную и многоклассовую классификацию набора данных (в scikit-learn реализовано еще два алгоритма классификации опорных векторов NuSVC и LinearSVC, но мы их не будем рассматривать).Функция решения SVM зависит от некоторого подмножества обучающих данных, называемых опорными векторами. Некоторые свойства этих опорных векторов можно найти в атрибутах support_vectors_и support_.SVC может реализовать подход «один против одного» для классификации нескольких классов. Он строит набор классификаторов, каждый из которых обучает данные из двух классов. Чтобы обеспечить согласованный интерфейс с другими классификаторами, осуществляется монотонное преобразование результатов классификаторов «один против одного» в решающую функцию формы «один против остальных» .n_classes * (n_classes - 1) / 2decision_function_shape(n_samples, n_classes).
Советы по практическому использованию
Избегание копирования данных : для SVC,если данные, передаваемые в определенные методы, не имеют непрерывного порядка C и двойной точности, они будут скопированы перед вызовом базовой реализации SVRC
Размер кэша ядра : Для SVC размер кэша ядра оказывает сильное влияние на время выполнения крупных задач. Если у вас достаточно оперативной памяти, рекомендуется установить более высокое значение, чем значение по умолчанию 200 (МБ), например 500 (МБ) или 1000 (МБ)
Настройка C : C =1 по умолчанию, что является разумным выбором по умолчанию. Если у Вас много зашумленных наблюдений, вам следует уменьшить его: уменьшение C соответствует большей регуляризации.
Алгоритмы машины опорных векторов не являются масштабно-инвариантными, поэтому, настоятельно рекомендуется масштабировать данные. Например, масштабируйте каждый атрибут входного вектора X до [0,1] или [-1,+1] или стандартизируйте его, чтобы оно имело среднее значение 0 и дисперсию 1. Обратите внимание, что такое же масштабирование должно быть применено к тестовому вектору, чтобы получить значимые результаты. Это можно легко сделать, используя Pipeline:
Случайность базовых реализаций : Базовая реализация SVCи использует генератор случайных чисел только для перемешивания данных для оценки вероятности (если probabilityустановлено значение True). Эту случайность можно контролировать с помощью random_state параметра. Если probability установлено значение, False эти оценки не являются случайными и random_state не влияют на результаты.
Функции ядра
Функция ядра может быть любой из следующих:
linear: $\left\langle {x,x'} \right\rangle$
polynomial: $\left( {\gamma \left\langle {x,x'} \right\rangle + r} \right)^d$ ,где $d$ указывается параметром degree, $r$ - coef0.
rbf: $\exp \left( { - \gamma \left\| {x - x'} \right\|^2 } \right)$ , где $\gamma$ указывается параметром gamma, должно быть больше 0.
sigmoid: $\tanh \left( {\gamma \left\langle {x,x'} \right\rangle + r} \right)$ , где $r$ указывается coef0.
Различные ядра задаются параметром kernel
а.Параметры ядра RBF
При обучении SVM с помощью ядра радиальной базисной функции (RBF) необходимо учитывать два параметра: C и gamma. Параметр C, общий для всех ядер SVM, сочетает неправильную классификацию обучающих примеров с простотой поверхности принятия решений. Низкий уровень C делает поверхность решения гладкой, а высокий C уровень направлен на правильную классификацию всех обучающих примеров. gamma определяет, какое влияние имеет один обучающий пример. Чем больше gamma показатель, тем ближе должны быть к нему другие примеры. Правильный выбор C и gamma имеет решающее значение для производительности SVM. Рекомендуется использовать GridSearchCVс, чтобы выбрать хорошие значения C и gamma экспоненциально далеких друг от друга.
б. Пользовательские ядра
Вы можете определить свои собственные ядра, либо задав ядро как функцию Python, либо предварительно вычислив матрицу Грамма(Gram matrix).
Классификаторы с пользовательскими ядрами ведут себя так же, как и любые другие классификаторы, за исключением того:
Поле support_vectors_теперь пусто, в нем хранятся только индексы опорных векторов.support_
Ссылка (а не копия) первого аргумента метода fit() сохраняется для дальнейшего использования. Если этот массив изменится между использованием fit()и predict()вы получите неожиданные результаты.
Как обычно, используем SVC для решения задачи классификации регионов РФ по типу экономики.Обучающая выборка содержит регионы шести классов,следовательно,SVC должен осуществлять многоклассовую классификацию. При этом по умолчанию будет использоваться метод «один против одного» (OvO) и все остальные праметры также будут иметь значения по умолчанию. Ниже приведен соотвествующий python скрипт. В результате его работы при разбиении регионов на обучающую ти тестовую последовательности в соотношении 0.9б 0.1 получена 100 процентная точность классификации. Построенные кривые обучения при росте объма обучающей выборки стремятся друг к другу и к уровню средней точности близкой к единице
#Классификация SVC
import warnings
import numpy as np
import scipy.stats as st
from pandas import Series, DataFrame
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import plotly
import plotly.express as px
import plotly.graph_objs as go
from sklearn.svm import SVC
#from sklearn.svm import NuSVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
warnings.simplefilter('ignore')
#ввод исходных данных из файла
Regdata =pd.ExcelFile('REG_RU_03.xlsx')
Regtab1 =Regdata.parse('dan04')
#print(Regtab1)
ind=np.arange(0,len(Regtab1), 1)
Reg1df=DataFrame(Regtab1,index=ind,columns=['Name','PI_N','Pcx_N','PP_N','Claster'])
Reg1df = np.round(Reg1df,decimals = 2)
Reg2df=Reg1df[['PI_N','Pcx_N','PP_N']]
Reg1df
y=Reg1df['Claster']
y=np.array(y)
X=np.array (Reg2df)
#нормирование значений элементов массива X
SUMX=X[:,0] +X[:,1] + X[:,2]
X[:,0] =(X[:,0] /SUMX)*100
X[:,1] =(X[:,1] /SUMX)*100
X[:,2] =(X[:,2] /SUMX)*100
#выделение обучающей и тренировочной последовательностей
X_train, X_test, y_train, y_test = train_test_split ( X , y , test_size=0.1, random_state=25)
print('Фактические метки классов на тесте')
print(y_test)
#Обучение классификатора
#clf = make_pipeline(StandardScaler(), NuSVC())
clf = make_pipeline(StandardScaler(), SVC(gamma='scale'))
clf.fit(X_train, y_train)
#проверка на тестовой последовательности
y_pred =clf.predict(X_test)
print('Прогнозные метки классов на тесте')
print(y_pred)
#Оценка качества классификации
from sklearn.metrics import accuracy_score
eplus = accuracy_score(y_test, y_pred)
print('Bepнocть: %.2f' %eplus)
print('Матрица путаницы')
import matplotlib.pyplot as plt
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
cm = confusion_matrix(y_test, y_pred, labels=clf.classes_)
disp = ConfusionMatrixDisplay(confusion_matrix=cm,display_labels=clf.classes_)
disp.plot()
plt.show()
# ПОСТРОЕНИЕ КРИВЫХ ОБУЧЕНИЯ ==============================================
train_ndf=[]
train_meandf=[]
test_meandf=[]
from sklearn.model_selection import learning_curve
#gnb = GaussianNB()
train_size_abs, train_scores, test_scores = learning_curve(
clf, X, y, train_sizes=np.linspace (0.1, 1, 50) )
for train_size, cv_train_scores, cv_test_scores in zip(train_size_abs, train_scores, test_scores):
train_ndf.append(train_size)
train_meandf.append(cv_train_scores.mean())
test_meandf.append(cv_test_scores.mean())
#print(f"{train_size} образцы использовались для обучения модели")
#print(f"Средняя точность обучения {cv_train_scores.mean():.2f}")
#print(f"Средняя точность теста {cv_test_scores.mean():.2f}")
train_n=DataFrame(train_ndf,columns=['train_size'])
train_mean=DataFrame(train_meandf,columns=['train'])
test_mean=DataFrame(test_meandf,columns=['test'])
tab_LC=pd.concat([train_n,train_mean,test_mean],axis=1)
plt.figure(figsize=(10, 6))
plt.plot(tab_LC.train_size,tab_LC.train,color='green', linewidth=2.0,label='train')
plt.plot(tab_LC.train_size,tab_LC.test,color='r', linewidth=2.0,label='test')
plt.xlabel(r'$trainsize$ размер обучающей выборки',fontsize=18)
plt.ylabel('Средняя точность',fontsize=18)
plt.title(r'Кривые обучения SVC', fontsize=18)
plt.legend()
plt.grid(True)
plt.show()
Фактические метки классов на тесте [0 5 4 0 1 1 5 2 5] Прогнозные метки классов на тесте [0 5 4 0 1 1 5 2 5] Bepнocть: 1.00 Матрица путаницы
#ПОСТРОЕНИЕ КРИВЫХ ОБУЧЕНИЯ С ИСПОЛЬЗОВАНИЕМ LearningCurveDisplay
import numpy as np
import scipy.stats as st
from pandas import Series, DataFrame
import pandas as pd
from sklearn.datasets import load_digits
from sklearn.naive_bayes import GaussianNB
import matplotlib.pyplot as plt
from sklearn.model_selection import LearningCurveDisplay
from sklearn.utils import shuffle
#ввод исходных данных из файла
Regdata =pd.ExcelFile('REG_RU_03.xlsx')
Regtab1 =Regdata.parse('dan04')
#print(Regtab1)
ind=np.arange(0,len(Regtab1), 1)
Reg1df=DataFrame(Regtab1,index=ind,columns=['Name','PI_N','Pcx_N','PP_N','Claster'])
Reg1df = np.round(Reg1df,decimals = 2)
Reg2df=Reg1df[['PI_N','Pcx_N','PP_N']]
Reg1df
y=Reg1df['Claster']
y=np.array(y)
X=np.array (Reg2df)
#нормирование значений элементов массива X
SUMX=X[:,0] +X[:,1] + X[:,2]
X[:,0] =(X[:,0] /SUMX)*100
X[:,1] =(X[:,1] /SUMX)*100
X[:,2] =(X[:,2] /SUMX)*100
X, y = shuffle(X, y, random_state=0)
LearningCurveDisplay.from_estimator( make_pipeline(StandardScaler(), SVC(gamma='auto')), X, y, train_sizes=np.linspace (0.1, 1, 50), cv=5)
plt.show()
Классификатор машины опорных векторов SVC реализован в R внескодьких пакетах рассмотрим его реализацию в пакете 'caret'
Необходимо загрузить пакет: library(caret)
Пакет Caret предоставляет метод createDataPartition() для разделения данных на обучающий и тестовый наборы, мы его используем ниже в нашем R скрипте. Мы также будем использовать метод summary() . Это даст нам общее представление о диапазоне атрибутов нашего набора данных.
Обучение модели SVM
Пакет Caret предоставляет метод train() для обучения наших данных различным алгоритмам. Нам просто нужно передать разные значения параметров для разных алгоритмов. Перед методом train() мы сначала воспользуемся методом trainControl(). Он контролирует вычислительные нюансы метода train()
Мы устанавливаем 3 параметра метода trainControl(). Параметр «method» содержит подробную информацию о методе повторной выборки. Мы можем установить «метод» со многими значениями, такими как «boot», «boot632», «cv», «repeatedcv», «LOOCV», «LGOCV» и т. д. мы будем использовать cv, то есть повторную перекрестную проверку.
Параметр «number» содержит количество итераций передискретизации. Параметр «repeats» содержит полные наборы сверток, которые необходимо вычислить для нашей повторной перекрестной проверки. Мы используем номер настройки =10 и повторы =3. Этот метод trainControl() возвращает список и он передается в метод train().
Полное описание метода trainControl():
trainControl( method = "boot",number = ifelse(grepl("cv", method), 10, 25), repeats = ifelse(grepl("[d_]cv$", method), 1, NA), p = 0.75,search = "grid",initialWindow = NULL,horizon = 1,fixedWindow = TRUE,skip = 0,verboseIter = FALSE, returnData = TRUE,returnResamp = "final",savePredictions = FALSE,classProbs = FALSE,summaryFunction = defaultSummary, selectionFunction = "best",preProcOptions = list(thresh = 0.95, ICAcomp = 3, k = 5, freqCut = 95/5, uniqueCut = 10, cutoff = 0.9),sampling = NULL,index = NULL,indexOut = NULL,indexFinal = NULL,timingSamps = 0, predictionBounds = rep(FALSE, 2),seeds = NA, adaptive = list(min = 5, alpha = 0.05, method = "gls", complete = TRUE), trim = FALSE, allowParallel = TRUE)
Аргументы:
method Метод повторной выборки: boot, boot632, cv, repeatedcv, LOOCV, LGOCV(для повторного разделения обучения/теста), none(подгоняет только одну модель ко всему обучающему набору), oob(только для случайного леса, деревьев в мешках, земли в мешках, гибкого дискриминантного анализа в мешках или условного дерева модели леса), "adaptive_cv", "adaptive_boot"или"adaptive_LGOCV"
number Либо количество сверток, либо количество итераций повторной выборки.
*repeats Только для повторной k-кратной перекрестной проверки: количество полных наборов сверток для вычисления
verboseIter Логично распечатать журнал тренировок.
returnData Логичное сохранение данных
returnResamp Строка символов, указывающая, какую часть итоговых показателей после повторной выборки следует сохранить. Значения могут быть «окончательными», «всеми» или «нет».
savePredictions Логичное сохранять прогнозы для каждой повторной выборки
p Для перекрестной проверки исключения группы: процент обучения
initialWindow, horizon, fixedWindow возможные аргументы createTimeSlices
classProbs логичный; следует ли вычислять вероятности классов для моделей классификации (вместе с прогнозируемыми значениями) при каждой повторной выборке?
summaryFunction функция для вычисления показателей производительности по повторным выборкам. Аргументы функции должны быть такими же, как и в defaultSummary.
selectionFunction функция, используемая для выбора оптимального параметра настройки. Это может быть имя функции или сама функция. bestПодробности и другие варианты смотрите здесь.
preProcOptions Список опций для перехода к preProcess. Тип предварительной обработки (например, центрирование, масштабирование и т. д.) передается через preProcопцию в train.
index список с элементами для каждой итерации передискретизации. Каждый элемент списка представляет собой образец строк, используемый для обучения на этой итерации.
indexOut список (такой же длины, как и index), который определяет, какие семплы сохраняются для каждой повторной выборки. Если , то используется NULLуникальный набор выборок, не содержащийся в .index
timingSamps количество выборок обучающего набора, которые будут использоваться для измерения времени прогнозирования выборок (ноль означает, что время прогнозирования не следует оценивать.
predictionBounds логический или числовой вектор длины 2 (только регрессия). Если это логично, прогнозы можно ограничить так, чтобы они находились в пределах результатов обучающего набора. Например, значение c(TRUE, FALSE)будет ограничивать только нижний предел прогнозов. Если числовое, можно использовать конкретные границы. Например, если c(10, NA)значения ниже 10 будут прогнозироваться как 10 (без ограничения в верхней части).
seeds необязательный набор целых чисел, который будет использоваться для установки начального числа на каждой итерации повторной выборки. Это полезно, когда модели выполняются параллельно. Значение NAостановит установку начального числа в рабочих процессах, а значение NULLустановит начальные числа с использованием случайного набора целых чисел. Альтернативно можно использовать список. В списке должны быть B+1элементы, где B— количество повторных выборок. Первыми Bэлементами списка должны быть векторы целых чисел длины Mгде M– количество оцениваемых моделей. Последний элемент списка должен быть одним целым числом (для окончательной модели).
adaptive список, используемый, когда methodесть "adaptive_cv", "adaptive_boot"или "adaptive_LGOCV".
allowParallel если параллельный бэкэнд загружен и доступен, должна ли функция его использовать?
Полное описание метода train(): Подбор прогнозирующих моделей по различным параметрам настройки
Эта функция устанавливает сетку параметров настройки для ряда процедур классификации и регрессии, соответствует каждой модели и рассчитывает показатель производительности на основе повторной выборки.
train(x,y,method = "rf",preProcess = NULL,weights = NULL,metric = ifelse(is.factor(y), "Accuracy", "RMSE"), maximize = ifelse(metric %in% c("RMSE", "logLoss", "MAE", "logLoss"), FALSE, TRUE), trControl = trainControl(), tuneGrid = NULL,tuneLength = ifelse(trControl$method == "none", 1, 3))
train(form, data,weights,subset, na.action = na.fail, contrasts = NULL)
train(x,data, method = "rf",metric = ifelse(is.factor(y_dat), "Accuracy", "RMSE"), maximize = ifelse(metric %in% c("RMSE", "logLoss", "MAE"), FALSE, TRUE),trControl = trainControl(), tuneGrid = NULL,tuneLength = ifelse(trControl$method == "none", 1, 3))
Аргументы:
x Для метода по умолчанию — xэто объект, в котором образцы расположены в строках, а объекты — в столбцах. Это может быть простая матрица, кадр данных или другой тип (например, разреженная матрица), но он должен иметь имена столбцов (см. подробности ниже). Предварительная обработка с использованием preProcessаргумента поддерживает только матрицы или фреймы данных. При использовании метода рецепта xэто должен быть неподготовленный recipeобъект, описывающий условия модели (т. е. результат, предикторы и т. д.), а также любую предварительную обработку, которая должна быть выполнена с данными. Это альтернативный подход к указанию модели. Обратите внимание, что при использовании метода рецепта любые переданные ему аргументы preProcess будут игнорироваться.
y Числовой или факторный вектор, содержащий результат для каждой выборки.
method Строка, указывающая, какую модель классификации или регрессии использовать.
preProcess Вектор-строка, определяющий предварительную обработку данных предиктора. Текущие возможности: «BoxCox», «YeoJohnson», «expoTrans», «center», «scale», «range», «knnImpute», «bagImpute», «medianImpute», «pca», «ica» и «spatialSign». . По умолчанию предварительная обработка отсутствует.
weights Числовой вектор весов вариантов. Этот аргумент повлияет только на модели, которые допускают веса вариантов.
metric Строка, указывающая, какая сводная метрика будет использоваться для выбора оптимальной модели. По умолчанию возможными значениями являются «RMSE» и «Rsquared» для регрессии и «Точность» и «Каппа» для классификации.
maximize Логично: должна ли метрика быть максимизированной или минимизированной?
trControl Список значений, которые определяют, как действует эта функция.
tuneGrid Кадр данных с возможными значениями настройки. Столбцы называются так же, как и параметры настройки.
tuneLength Целое число, обозначающее степень детализации сетки параметров настройки. По умолчанию этот аргумент представляет собой количество уровней для каждого параметра настройки, которое должно быть сгенерировано train. Если trainControl есть опция search = "random", это максимальное количество комбинаций параметров настройки, которые будут созданы в результате случайного поиска.
form Формула видаy ~ x1 + x2 + ...
data Кадр данных, из которого предпочтительно брать переменные, указанные в formulaили .recipe
subset Вектор индекса, определяющий случаи, которые будут использоваться в обучающей выборке
na.action Функция, определяющая действие, которое необходимо предпринять в случае обнаружения NA. Действием по умолчанию является сбой процедуры. Альтернативой является na.omit, что приводит к отклонению случаев с пропущенными значениями любой требуемой переменной.
contrasts Список контрастов, которые будут использоваться для некоторых или всех факторов, выступающих в качестве переменных в формуле модели.
Значения
Возвращается список классов, trainсодержащий:
method Выбранная модель.
modelType Идентификатор типа модели.
results Кадр данных о частоте ошибок обучения и значениях параметров настройки.
bestTune Кадр данных с окончательными параметрами.
call Вызов (совпадающей) функции с расширенными точками
dots Список, содержащий любые... значения, переданные исходному вызову.
metric Строка, указывающая, какая сводная метрика будет использоваться для выбора оптимальной модели.
control Список параметров управления.
preProcess Либо NULLили объект класса preProcess
finalModel Подходящий объект с использованием лучших параметров
trainingData Фрейм данных
resample Фрейм данных со столбцами для каждого показателя производительности. Каждая строка соответствует каждой повторной выборке. Если запрашиваются методы перекрестной проверки с исключением одного или оценки из пакета, это будет NULL. Аргумент returnResampконтролирует trainControl, какая часть результатов повторной выборки сохраняется.
perfNames Вектор символов показателей производительности, создаваемых суммирующей функцией.
maximize Логическая переработка аргументов функции.
yLimits Диапазон результатов обучающего набора.
times Список времени выполнения: everythingпредназначен для всего вызова train, finalдля окончательной подгонки модели и, опционально, predictionдля времени прогнозирования новых выборок
Подробности
train может использоваться для настройки моделей путем выбора параметров сложности, связанных с оптимальной статистикой повторной выборки. Для конкретной модели создается сетка параметров (если таковая имеется), и модель обучается на несколько разных данных для каждой возможной комбинации параметров настройки. По каждому набору данных рассчитывается эффективность отложенных выборок, а среднее и стандартное отклонение суммируются для каждой комбинации. Комбинация с оптимальной статистикой повторной выборки выбирается в качестве окончательной модели, и весь обучающий набор используется для соответствия окончательной модели.
Предикторами x могут быть практически любые объекты, если базовая функция подгонки модели может работать с классом объектов. Функция была разработана для работы с простыми матрицами и входными данными в виде фреймов, поэтому некоторые функции могут не работать (например, предварительная обработка). При использовании строковых ядер вектор символьных строк следует преобразовать в матрицу с одним столбцом.
Используем функции trainControl и train из пакета caret с моделью svmRadial для классификации все тех же регионов РФ по типу экономики. Ниже приведен R скрипт, в котором реализована процедура классификации регионов РФ с использованием радиальной SVM в train.При 90 процентах обучающей выборки лучшая оценка на тесте Accuracy = 0.8
# Классификация машина опорных векторов (SVM)
options(warn=-1)
library(class)
library(gmodels)
library(openxlsx)
library(caret)
library(ggplot2)
library(GGally)
library(psych)
#library(ggpubr)
library(reshape)
library(gmodels)
#ЗАГРУЗКА ИЗ EXSEL ПЕВИЧНЫХ ДАННЫХ
N=6 # номер листа с данными
x <-read.xlsx("REG_RU_03.xlsx", sheet = N)
#x
xreg <-data.frame(X1=x$PI_N,X2=x$Pcx_N,X3=x$PP_N,Class=x$Claster)
for (i in 1:81)
{
if(xreg$Class[i]==0){xreg$Class[i]='A'}
if(xreg$Class[i]==1){xreg$Class[i]='B'}
if(xreg$Class[i]==2){xreg$Class[i]='C'}
if(xreg$Class[i]==3){xreg$Class[i]='D'}
if(xreg$Class[i]==4){xreg$Class[i]='E'}
if(xreg$Class[i]==5){xreg$Class[i]='F'}
}
xreg[,'Class']<-factor(xreg[,'Class'])
xreg_f <-xreg[,'Class']
xregSum =xreg[,'X1']+xreg[,'X2']+xreg[,'X3']
xreg[,'X1']=xreg[,'X1']/xregSum
xreg[,'X2']=xreg[,'X2']/xregSum
xreg[,'X3']=xreg[,'X3']/xregSum
xstr_nor <-xreg[,1:3]
xstr_nor <-cbind(xstr_nor,xreg_f)
xstr_nor <-cbind(x$Name,xstr_nor)
summary(xstr_nor)
cutoff <- createDataPartition(xstr_nor$xreg_f, p=0.90, list=FALSE)
# выберите 20% данных для проверки
testdf <- xstr_nor[-cutoff,]
# использовать оставшиеся 90% данных для обучения и тестирования модели
traindf <- xstr_nor[cutoff,]
# Код для обучения SVM
set.seed(1234)
# установите 10-кратную перекрестную проверку с AU, чтобы выбрать для нас то, что мы называем лучшей моделью
control <- trainControl(method="cv",number=10,repeats=3,classProbs = TRUE)
metric <- "Accuracy"
model <- train(xreg_f ~., data = traindf[,2:5], method = "svmRadial",
tuneLength = 8,preProc = c("center","scale"),
metric=metric, trControl=control)
model
plot(model)
# validate our model
predict <- predict(model, newdata = testdf)
reg.TEST <-cbind(testdf,predict)
print('Прогноз классов на тесте')
reg.TEST
print('Матрица путаницы и точность модели')
confusionMatrix(predict, testdf$xreg_f)
CrossTable(x=testdf$xreg_f,y=predict,prob.chisq = TRUE)
x$Name X1 X2 X3
Length:81 Min. :0.000000 Min. :0.00000 Min. :0.1032
Class :character 1st Qu.:0.006346 1st Qu.:0.05418 1st Qu.:0.5246
Mode :character Median :0.036948 Median :0.11214 Median :0.7194
Mean :0.146064 Mean :0.18179 Mean :0.6721
3rd Qu.:0.196209 3rd Qu.:0.26045 3rd Qu.:0.8547
Max. :0.880111 Max. :0.85494 Max. :0.9872
xreg_f
A:18
B:11
C:26
D: 3
E:15
F: 8
Support Vector Machines with Radial Basis Function Kernel 76 samples 3 predictor 6 classes: 'A', 'B', 'C', 'D', 'E', 'F' Pre-processing: centered (3), scaled (3) Resampling: Cross-Validated (10 fold) Summary of sample sizes: 68, 69, 67, 69, 67, 70, ... Resampling results across tuning parameters: C Accuracy Kappa 0.25 0.7460317 0.6751545 0.50 0.7067460 0.6234728 1.00 0.7585317 0.6939659 2.00 0.7335317 0.6598368 4.00 0.7335317 0.6655214 8.00 0.7085317 0.6349603 16.00 0.7460317 0.6796974 32.00 0.7335317 0.6622196 Tuning parameter 'sigma' was held constant at a value of 2.925726 Accuracy was used to select the optimal model using the largest value. The final values used for the model were sigma = 2.925726 and C = 1.
[1] "Прогноз классов на тесте"
| x$Name | X1 | X2 | X3 | xreg_f | predict | |
|---|---|---|---|---|---|---|
| <chr> | <dbl> | <dbl> | <dbl> | <fct> | <fct> | |
| 5 | Ивановская область | 0.0051546392 | 0.08333333 | 0.9115120 | C | C |
| 19 | Республика Карелия | 0.3576938693 | 0.02111246 | 0.6211937 | E | B |
| 22 | Вологодская область | 0.0007455268 | 0.04473161 | 0.9545229 | C | C |
| 34 | Волгоградская область | 0.0323066780 | 0.16859753 | 0.7990958 | A | A |
| 73 | Забайкальский край | 0.6633165829 | 0.08967917 | 0.2470043 | B | B |
[1] "Матрица путаницы и точность модели"
Confusion Matrix and Statistics
Reference
Prediction A B C D E F
A 1 0 0 0 0 0
B 0 1 0 0 1 0
C 0 0 2 0 0 0
D 0 0 0 0 0 0
E 0 0 0 0 0 0
F 0 0 0 0 0 0
Overall Statistics
Accuracy : 0.8
95% CI : (0.2836, 0.9949)
No Information Rate : 0.4
P-Value [Acc > NIR] : 0.08704
Kappa : 0.7222
Mcnemar's Test P-Value : NA
Statistics by Class:
Class: A Class: B Class: C Class: D Class: E Class: F
Sensitivity 1.0 1.000 1.0 NA 0.0 NA
Specificity 1.0 0.750 1.0 1 1.0 1
Pos Pred Value 1.0 0.500 1.0 NA NaN NA
Neg Pred Value 1.0 1.000 1.0 NA 0.8 NA
Prevalence 0.2 0.200 0.4 0 0.2 0
Detection Rate 0.2 0.200 0.4 0 0.0 0
Detection Prevalence 0.2 0.400 0.4 0 0.0 0
Balanced Accuracy 1.0 0.875 1.0 NA 0.5 NA
Cell Contents
|-------------------------|
| N |
| Chi-square contribution |
| N / Row Total |
| N / Col Total |
| N / Table Total |
|-------------------------|
Total Observations in Table: 5
| predict
testdf$xreg_f | A | B | C | Row Total |
--------------|-----------|-----------|-----------|-----------|
A | 1 | 0 | 0 | 1 |
| 3.200 | 0.400 | 0.400 | |
| 1.000 | 0.000 | 0.000 | 0.200 |
| 1.000 | 0.000 | 0.000 | |
| 0.200 | 0.000 | 0.000 | |
--------------|-----------|-----------|-----------|-----------|
B | 0 | 1 | 0 | 1 |
| 0.200 | 0.900 | 0.400 | |
| 0.000 | 1.000 | 0.000 | 0.200 |
| 0.000 | 0.500 | 0.000 | |
| 0.000 | 0.200 | 0.000 | |
--------------|-----------|-----------|-----------|-----------|
C | 0 | 0 | 2 | 2 |
| 0.400 | 0.800 | 1.800 | |
| 0.000 | 0.000 | 1.000 | 0.400 |
| 0.000 | 0.000 | 1.000 | |
| 0.000 | 0.000 | 0.400 | |
--------------|-----------|-----------|-----------|-----------|
E | 0 | 1 | 0 | 1 |
| 0.200 | 0.900 | 0.400 | |
| 0.000 | 1.000 | 0.000 | 0.200 |
| 0.000 | 0.500 | 0.000 | |
| 0.000 | 0.200 | 0.000 | |
--------------|-----------|-----------|-----------|-----------|
Column Total | 1 | 2 | 2 | 5 |
| 0.200 | 0.400 | 0.400 | |
--------------|-----------|-----------|-----------|-----------|