Можно использовать машину вектора поддержки (SVM), когда данные имеют точно два класса. SVM классифицирует данные путем нахождения лучшей гиперплоскости, которая разделяет все точки данных одного класса от тех из другого класса. Гиперплоскость best для SVM означает тот с самым большим margin между этими двумя классами. Поле означает максимальную ширину плиты, параллельной гиперплоскости, которая не имеет никаких внутренних точек данных.
support vectors является точками данных, которые являются самыми близкими к отделяющейся гиперплоскости; эти точки находятся на контуре плиты. Следующая фигура иллюстрирует эти определения, с + указание на точки данных типа 1, и – указание на точки данных типа-1.
Математическая Формулировка: Основной. Это обсуждение следует за Hastie, Тибширэни и Фридманом [1] и Кристьанини и Шейв-Тейлор [2].
Данные для обучения являются набором точек (векторы) xj наряду с их категориями yj. Для некоторой размерности d, xj ∊ Rd и yj = ±1. Уравнение гиперплоскости
где β ∊ Rd и b является вещественным числом.
Следующая проблема задает гиперплоскость разделения best (т.е. контур решения). Найдите β и b, которые минимизируют || β || таким образом это для всех точек данных (xj, yj),
Векторами поддержки является xj на контуре, тех для который
Для математического удобства проблема обычно дается как эквивалентная проблема минимизации . Это - проблема квадратичного программирования. Оптимальное решение включает классификацию векторного z можно следующим образом:
classification score и представляет расстояние, которое z от контура решения.
Математическая Формулировка: Двойной. В вычислительном отношении более просто решить двойную проблему квадратичного программирования. Чтобы получить двойное, возьмите положительные множители Лагранжа αj, умноженный на каждое ограничение, и вычтите из целевой функции:
где вы ищете стационарную точку LP по β и b. Устанавливая градиент LP к 0, вы добираетесь
(1) |
Занимая место в LP, вы получаете двойной LD:
который вы максимизируете по αj ≥ 0. В целом многие αj 0 в максимуме. Ненулевой αj в решении двойной проблемы задает гиперплоскость, столь же замеченную в уравнении 1, который дает β как сумма αjyjxj. Точками данных xj, соответствующий ненулевому αj, является support vectors.
Производная LD относительно ненулевого αj 0 в оптимуме. Это дает
В частности, это дает значение b в решении путем взятия любого j с ненулевым αj.
Двойной является стандартная проблема квадратичного программирования. Например, решатель quadprog
Optimization Toolbox™ решает этот тип проблемы.
Ваши данные не могут допускать отделяющуюся гиперплоскость. В этом случае SVM может использовать soft margin, означая гиперплоскость, которая разделяет многих, но не все точки данных.
Существует две стандартных формулировки мягких полей. Оба включают добавляющие слабые переменные ξj и параметр штрафа C.
Проблема 1 нормы L:
таким образом, что
1 норма L называет использование ξj слабыми переменными вместо их квадратов. Три опции решателя SMO
, ISDA
и L1QP
fitcsvm
минимизируют проблему 1 нормы L.
Проблема 2-нормы L:
подвергните тем же ограничениям.
В этих формулировках вы видите, что увеличение C помещает больше веса в слабые переменные ξj, означая попытки оптимизации сделать более строгое разделение между классами. Эквивалентно, сокращение C к 0 делает misclassification менее важный.
Математическая Формулировка: Двойной. Для более легких вычислений считайте L 1 двойной проблемой к этой мягко-граничной формулировке. Используя множители Лагранжа μj, функция, чтобы минимизировать для проблемы 1 нормы L:
где вы ищете стационарную точку LP по β, b и положительному ξj. Устанавливая градиент LP к 0, вы добираетесь
Эти уравнения приводят непосредственно к двойной формулировке:
подвергните ограничениям
Итоговый набор неравенств, 0 ≤ αj ≤ C, показывает, почему C иногда называется box constraint. C сохраняет допустимые значения множителей Лагранжа αj в “поле”, ограниченной области.
Уравнение градиента для b дает решению b с точки зрения набора ненулевого αj, которые соответствуют векторам поддержки.
Можно записать и решить двойную из проблемы 2-нормы L аналогичным способом. Для получения дополнительной информации смотрите Кристьанини и Шейв-Тейлора [2], Глава 6.
Реализация fitcsvm. Обеими двойными мягко-граничными проблемами являются проблемы квадратичного программирования. Внутренне, fitcsvm
имеет несколько различных алгоритмов для решения проблем.
Для или бинарной классификации одного класса, если вы не устанавливаете часть ожидаемых выбросов в данных (см. OutlierFraction
), затем решатель по умолчанию является Последовательной минимальной оптимизацией (SMO). SMO минимизирует проблему с одной нормой рядом минимизаций 2D точки. Во время оптимизации SMO уважает линейное ограничение и явным образом включает член в модели смещения. SMO относительно быстр. Для получения дополнительной информации на SMO, см. [3].
Для бинарной классификации, если вы устанавливаете часть ожидаемых выбросов в данных, затем решатель по умолчанию является Итеративным Одним Алгоритмом Данных. Как SMO, ISDA решает проблему с одной нормой. В отличие от SMO, ISDA минимизирует рядом на минимизациях с одной точкой, не уважает линейное ограничение и явным образом не включает член в модели смещения. Для получения дополнительной информации на ISDA, см. [4].
Для или бинарной классификации одного класса, и если у вас есть лицензия Optimization Toolbox, можно принять решение использовать quadprog
, чтобы решить проблему с одной нормой. quadprog
использует большую память, но решает квадратичные программы в высокой степени точности. Для получения дополнительной информации см. Определение Квадратичного программирования (Optimization Toolbox).
Некоторые бинарные проблемы классификации не имеют простой гиперплоскости как полезного критерия разделения. Для тех проблем существует вариант математического подхода, который сохраняет почти всю простоту SVM разделение гиперплоскости.
Этот подход использует эти результаты теории репродуцирования ядер:
Существует класс функций G (x 1, x 2) со следующим свойством. Существует линейный пробел S и функциональный φ, сопоставляющий x с S, таким образом что
G (x 1, x 2) = <φ (x 1), φ (x 2)>.
Скалярное произведение происходит на пробеле S.
Этот класс функций включает:
Многочлены: Для некоторого положительного целочисленного p,
G (x 1, x 2) = (1 + x 1′x2) p.
Радиальная (Гауссова) основная функция:
G (x 1, x 2) = exp (– ∥x1–x2) ∥2).
Многоуровневый perceptron или сигмоидальный (нейронная сеть): Для положительного числа p 1 и отрицательное число p 2,
G (x 1, x 2) = tanh (p 1x1′x2 + p 2).
Не каждый набор p 1 и p 2 урожая допустимое ядро репродуцирования.
fitcsvm
не поддерживает сигмоидальное ядро. Вместо этого можно задать сигмоидальное ядро и задать его при помощи аргумента пары "имя-значение" 'KernelFunction'
. Для получения дополнительной информации смотрите Train Классификатор SVM Используя Пользовательское Ядро.
Математический подход с помощью ядер полагается на вычислительный метод гиперплоскостей. Все вычисления для классификации гиперплоскостей используют не что иное как скалярные произведения. Поэтому нелинейные ядра могут использовать идентичные вычисления и алгоритмы решения, и получить классификаторы, которые нелинейны. Получившиеся классификаторы являются гиперповерхностями на некотором пробеле S, но пробел S не должен быть идентифицирован или исследован.
Как с любым контролируемая модель изучения, вы сначала обучаете машину вектора поддержки, и затем пересекаетесь, подтверждают классификатор. Используйте обученную машину, чтобы классифицировать (предсказывают) новые данные. Кроме того, чтобы получить удовлетворительную прогнозирующую точность, можно использовать различные функции ядра SVM, и необходимо настроить параметры функций ядра.
Обучайтесь, и опционально пересекитесь, подтверждают, классификатор SVM с помощью fitcsvm
. Наиболее распространенный синтаксис:
SVMModel = fitcsvm(X,Y,'KernelFunction','rbf',... 'Standardize',true,'ClassNames',{'negClass','posClass'});
Входные параметры:
X
Матрица данных о предикторе, где каждая строка является одним наблюдением и каждым столбцом, является одним предиктором.
Y
Массив класса маркирует каждой строкой, соответствующей значению соответствующей строки в X
. Y
может быть категориальным, символом, или массивом строк, логическим или числовым вектором или массивом ячеек из символьных векторов.
KernelFunction
— Значением по умолчанию является 'linear'
для изучения 2D класса, которое разделяет данные гиперплоскостью. Значение 'gaussian'
(или 'rbf'
) является значением по умолчанию для изучения одного класса и задает, чтобы использовать Гауссово (или радиальная основная функция) ядро. Важный шаг, чтобы успешно обучить классификатор SVM должен выбрать соответствующую функцию ядра.
Standardize
— Отметьте указание, должно ли программное обеспечение стандартизировать предикторы перед обучением классификатор.
ClassNames
— Различает отрицательные и положительные классы или задает который классы включать в данные. Отрицательный класс является первым элементом (или строка символьного массива), например, 'negClass'
, и положительный класс является вторым элементом (или строка символьного массива), например, 'posClass'
. ClassNames
должен быть совпадающим типом данных как Y
. Это - хорошая практика, чтобы задать имена классов, особенно если вы сравниваете производительность различных классификаторов.
Получившаяся, обученная модель (SVMModel
) содержит оптимизированные параметры из алгоритма SVM, позволяя вам классифицировать новые данные.
Для большего количества пар "имя-значение" можно использовать, чтобы управлять обучением, видеть страницу с описанием fitcsvm
.
Классифицируйте новые данные с помощью predict
. Синтаксис для классификации новых данных с помощью обученного классификатора SVM (SVMModel
):
[label,score] = predict(SVMModel,newX);
Итоговый вектор, label
, представляет классификацию каждой строки в X
. score
является n-by-2 матрица мягких очков. Каждая строка соответствует строке в X
, который является новым наблюдением. Первый столбец содержит музыку к наблюдениям, классифицируемым на отрицательный класс, и второй столбец содержит наблюдения очков, классифицируемые на положительный класс.
Чтобы оценить апостериорные вероятности, а не очки, сначала передайте обученный классификатор SVM (SVMModel
) fitPosterior
, который соответствует счету к функции преобразования апостериорной вероятности к очкам. Синтаксис:
ScoreSVMModel = fitPosterior(SVMModel,X,Y);
Свойство ScoreTransform
классификатора ScoreSVMModel
содержит оптимальную функцию преобразования. Передайте ScoreSVMModel
predict
. Вместо того, чтобы возвращать очки, выходной аргумент, score
содержит апостериорные вероятности наблюдения, классифицируемого отрицательно (столбец 1 score
) или положительный (столбец 2 score
) класс.
Используйте аргумент пары "имя-значение" 'OptimizeHyperparameters'
fitcsvm
, чтобы найти значения параметров, которые минимизируют потерю перекрестной проверки. Имеющими право параметрами является 'BoxConstraint'
, 'KernelFunction'
, 'KernelScale'
, 'PolynomialOrder'
и 'Standardize'
. Для примера смотрите, Оптимизируют Подгонку Классификатора SVM Используя Байесовую Оптимизацию. Также можно использовать функцию bayesopt
, как показано в Оптимизируют перекрестный Подтвержденный Классификатор SVM Используя bayesopt. Функция bayesopt
позволяет большей гибкости настраивать оптимизацию. Можно использовать функцию bayesopt
, чтобы оптимизировать любые параметры, включая параметры, которые не имеют право оптимизировать, когда вы используете функцию fitcsvm
.
Можно также попытаться настроить параметры классификатора вручную согласно этой схеме:
Передайте данные fitcsvm
и установите аргумент пары "имя-значение" 'KernelScale','auto'
. Предположим, что обученная модель SVM называется SVMModel
. Программное обеспечение использует эвристическую процедуру, чтобы выбрать шкалу ядра. Эвристическая процедура использует подвыборку. Поэтому, чтобы воспроизвести результаты, установите seed случайных чисел с помощью rng
перед обучением классификатор.
Крест подтверждает классификатор путем передачи его crossval
. По умолчанию программное обеспечение проводит 10-кратную перекрестную проверку.
Передайте перекрестную подтвержденную модель SVM kfoldLoss
, чтобы оценить и сохранить ошибку классификации.
Переобучите классификатор SVM, но настройте аргументы пары "имя-значение" 'KernelScale'
и 'BoxConstraint'
.
BoxConstraint
— Одна стратегия состоит в том, чтобы попробовать геометрическую последовательность параметра ограничения поля. Например, примите 11 значений от 1e-5
до 1e5
фактором 10. Увеличение BoxConstraint
может сократить число векторов поддержки, но также и может увеличить учебное время.
KernelScale
— Одна стратегия состоит в том, чтобы попробовать геометрическую последовательность параметра сигмы RBF, масштабируемого в исходной шкале ядра. Сделайте это:
Получая исходную шкалу ядра, например, ks
, с помощью записи через точку: ks = SVMModel.KernelParameters.Scale
.
Используйте в качестве новых факторов шкал ядра оригинала. Например, умножьте ks
на эти 11 значений 1e-5
к 1e5
, увеличивающемуся фактором 10.
Выберите модель, которая приводит к самой низкой ошибке классификации. Вы можете хотеть далее совершенствовать свои параметры, чтобы получить лучшую точность. Запустите со своих начальных параметров и выполните другой шаг перекрестной проверки, на этот раз с помощью фактора 1,2.
Этот пример показывает, как сгенерировать нелинейный классификатор с Гауссовой функцией ядра. Во-первых, сгенерируйте один класс точек в единичном диске в двух измерениях и другой класс точек в кольце от радиуса 1 к радиусу 2. Затем генерирует классификатор на основе данных с Гауссовым радиальным ядром основной функции. Линейный классификатор по умолчанию является очевидно неподходящим для этой проблемы, поскольку модель циркулярная симметричный. Установите параметр ограничения поля на Inf
делать строгую классификацию, не имея в виду неправильно классифицированных учебных точек. Другие функции ядра не могут работать с этим строгим ограничением поля, поскольку они могут не мочь обеспечить строгую классификацию. Даже при том, что rbf классификатор может разделить классы, результат может быть перетренирован.
Сгенерируйте 100 точек, равномерно распределенных в единичном диске. Для этого сгенерируйте радиус r как квадратный корень из универсальной случайной переменной, сгенерируйте угол t однородно в (0, ), и помещенный точка в (r, потому что (t), r sin (t)).
rng(1); % For reproducibility r = sqrt(rand(100,1)); % Radius t = 2*pi*rand(100,1); % Angle data1 = [r.*cos(t), r.*sin(t)]; % Points
Сгенерируйте 100 точек, равномерно распределенных в кольце. Радиус снова пропорционален квадратному корню, на этот раз квадратный корень из равномерного распределения от 1 до 4.
r2 = sqrt(3*rand(100,1)+1); % Radius t2 = 2*pi*rand(100,1); % Angle data2 = [r2.*cos(t2), r2.*sin(t2)]; % points
Постройте точки и постройте круги радиусов 1 и 2 для сравнения.
figure; plot(data1(:,1),data1(:,2),'r.','MarkerSize',15) hold on plot(data2(:,1),data2(:,2),'b.','MarkerSize',15) ezpolar(@(x)1);ezpolar(@(x)2); axis equal hold off
Поместите данные в одну матрицу и сделайте вектор классификаций.
data3 = [data1;data2]; theclass = ones(200,1); theclass(1:100) = -1;
Обучите классификатор SVM с набором KernelFunction
к 'rbf'
и набором BoxConstraint
к Inf
. Постройте контур решения и отметьте векторы поддержки.
%Train the SVM Classifier cl = fitcsvm(data3,theclass,'KernelFunction','rbf',... 'BoxConstraint',Inf,'ClassNames',[-1,1]); % Predict scores over the grid d = 0.02; [x1Grid,x2Grid] = meshgrid(min(data3(:,1)):d:max(data3(:,1)),... min(data3(:,2)):d:max(data3(:,2))); xGrid = [x1Grid(:),x2Grid(:)]; [~,scores] = predict(cl,xGrid); % Plot the data and the decision boundary figure; h(1:2) = gscatter(data3(:,1),data3(:,2),theclass,'rb','.'); hold on ezpolar(@(x)1); h(3) = plot(data3(cl.IsSupportVector,1),data3(cl.IsSupportVector,2),'ko'); contour(x1Grid,x2Grid,reshape(scores(:,2),size(x1Grid)),[0 0],'k'); legend(h,{'-1','+1','Support Vectors'}); axis equal hold off
fitcsvm
генерирует классификатор, который является близко к кругу радиуса 1. Различие происходит из-за случайных данных тренировки.
Обучение с параметрами по умолчанию делает более близко круговой контур классификации, но тот, который неправильно классифицирует некоторые данные тренировки. Кроме того, значением по умолчанию BoxConstraint
является 1
, и, поэтому, существует больше векторов поддержки.
cl2 = fitcsvm(data3,theclass,'KernelFunction','rbf'); [~,scores2] = predict(cl2,xGrid); figure; h(1:2) = gscatter(data3(:,1),data3(:,2),theclass,'rb','.'); hold on ezpolar(@(x)1); h(3) = plot(data3(cl2.IsSupportVector,1),data3(cl2.IsSupportVector,2),'ko'); contour(x1Grid,x2Grid,reshape(scores2(:,2),size(x1Grid)),[0 0],'k'); legend(h,{'-1','+1','Support Vectors'}); axis equal hold off
Этот пример показывает, как использовать пользовательскую функцию ядра, такую как сигмоидальное ядро, чтобы обучить классификаторы SVM и настроить пользовательские параметры функции ядра.
Сгенерируйте случайный набор точек в модульном кругу. Маркируйте точки в первых и третьих квадрантах как принадлежащий положительному классу и тем во вторых и четвертых квадрантах в отрицательном классе.
rng(1); % For reproducibility n = 100; % Number of points per quadrant r1 = sqrt(rand(2*n,1)); % Random radii t1 = [pi/2*rand(n,1); (pi/2*rand(n,1)+pi)]; % Random angles for Q1 and Q3 X1 = [r1.*cos(t1) r1.*sin(t1)]; % Polar-to-Cartesian conversion r2 = sqrt(rand(2*n,1)); t2 = [pi/2*rand(n,1)+pi/2; (pi/2*rand(n,1)-pi/2)]; % Random angles for Q2 and Q4 X2 = [r2.*cos(t2) r2.*sin(t2)]; X = [X1; X2]; % Predictors Y = ones(4*n,1); Y(2*n + 1:end) = -1; % Labels
Отобразите данные на графике.
figure;
gscatter(X(:,1),X(:,2),Y);
title('Scatter Diagram of Simulated Data')
Запишите функцию, которая принимает две матрицы в пространстве признаков как входные параметры и преобразовывает их в матрицу Грамма использование сигмоидального ядра.
function G = mysigmoid(U,V) % Sigmoid kernel function with slope gamma and intercept c gamma = 1; c = -1; G = tanh(gamma*U*V' + c); end
Сохраните этот код как файл с именем mysigmoid
на вашем пути MATLAB®.
Обучите классификатор SVM с помощью сигмоидальной функции ядра. Это - хорошая практика, чтобы стандартизировать данные.
Mdl1 = fitcsvm(X,Y,'KernelFunction','mysigmoid','Standardize',true);
Mdl1
является классификатором ClassificationSVM
, содержащим предполагаемые параметры.
Отобразите данные на графике и идентифицируйте векторы поддержки и контур решения.
% Compute the scores over a grid d = 0.02; % Step size of the grid [x1Grid,x2Grid] = meshgrid(min(X(:,1)):d:max(X(:,1)),... min(X(:,2)):d:max(X(:,2))); xGrid = [x1Grid(:),x2Grid(:)]; % The grid [~,scores1] = predict(Mdl1,xGrid); % The scores figure; h(1:2) = gscatter(X(:,1),X(:,2),Y); hold on h(3) = plot(X(Mdl1.IsSupportVector,1),... X(Mdl1.IsSupportVector,2),'ko','MarkerSize',10); % Support vectors contour(x1Grid,x2Grid,reshape(scores1(:,2),size(x1Grid)),[0 0],'k'); % Decision boundary title('Scatter Diagram with the Decision Boundary') legend({'-1','1','Support Vectors'},'Location','Best'); hold off
Можно настроить параметры ядра в попытке улучшить форму контура решения. Эта сила также уменьшает misclassification уровень в выборке, но, необходимо сначала определить misclassification уровень из выборки.
Определите misclassification уровень из выборки при помощи 10-кратной перекрестной проверки.
CVMdl1 = crossval(Mdl1); misclass1 = kfoldLoss(CVMdl1); misclass1
misclass1 = 0.1350
misclassification уровень из выборки составляет 13,5%.
Запишите другой сигмоидальной функции, но Набору gamma = 0.5;
.
function G = mysigmoid2(U,V) % Sigmoid kernel function with slope gamma and intercept c gamma = 0.5; c = -1; G = tanh(gamma*U*V' + c); end
Сохраните этот код как файл с именем mysigmoid2
на вашем пути MATLAB®.
Обучите другой классификатор SVM с помощью настроенного сигмоидального ядра. Отобразите на графике данные и область решения, и определите misclassification уровень из выборки.
Mdl2 = fitcsvm(X,Y,'KernelFunction','mysigmoid2','Standardize',true); [~,scores2] = predict(Mdl2,xGrid); figure; h(1:2) = gscatter(X(:,1),X(:,2),Y); hold on h(3) = plot(X(Mdl2.IsSupportVector,1),... X(Mdl2.IsSupportVector,2),'ko','MarkerSize',10); title('Scatter Diagram with the Decision Boundary') contour(x1Grid,x2Grid,reshape(scores2(:,2),size(x1Grid)),[0 0],'k'); legend({'-1','1','Support Vectors'},'Location','Best'); hold off CVMdl2 = crossval(Mdl2); misclass2 = kfoldLoss(CVMdl2); misclass2
misclass2 = 0.0450
После сигмоидальной наклонной корректировки новый контур решения, кажется, обеспечивает лучшую подгонку в выборке и контракты уровня перекрестной проверки больше чем на 66%.
Этот пример показывает, как оптимизировать классификацию SVM с помощью функции fitcsvm
и пары "имя-значение" OptimizeHyperparameters
. Классификация работает над местоположениями точек из Гауссовой модели смеси. В Элементах Статистического Изучения, Hastie, Тибширэни и Фридмана (2009), страница 17 описывает модель. Модель начинается с генерации 10 базисных точек для "зеленого" класса, распределенного как 2D независимые нормали со средним значением (1,0) и модульное отклонение. Это также генерирует 10 базисных точек для "красного" класса, распределенного как 2D независимые нормали со средним значением (0,1) и модульное отклонение. Для каждого класса (зеленый и красный), сгенерируйте 100 случайных точек можно следующим образом:
Выберите базисную точку m соответствующего цвета однородно наугад.
Сгенерируйте независимую случайную точку с 2D нормальным распределением со средним значением m и отклонением I/5, где я - единичная матрица 2 на 2. В этом примере используйте отклонение I/50, чтобы показать преимущество оптимизации более ясно.
Сгенерируйте точки и классификатор
Сгенерируйте эти 10 базисных точек для каждого класса.
rng default % For reproducibility grnpop = mvnrnd([1,0],eye(2),10); redpop = mvnrnd([0,1],eye(2),10);
Просмотрите базисные точки.
plot(grnpop(:,1),grnpop(:,2),'go') hold on plot(redpop(:,1),redpop(:,2),'ro') hold off
Поскольку некоторые красные базисные точки близко к зеленым базисным точкам, может быть трудно классифицировать точки данных на основе одного только местоположения.
Сгенерируйте 100 точек данных каждого класса.
redpts = zeros(100,2);grnpts = redpts; for i = 1:100 grnpts(i,:) = mvnrnd(grnpop(randi(10),:),eye(2)*0.02); redpts(i,:) = mvnrnd(redpop(randi(10),:),eye(2)*0.02); end
Просмотрите точки данных.
figure plot(grnpts(:,1),grnpts(:,2),'go') hold on plot(redpts(:,1),redpts(:,2),'ro') hold off
Подготовка данных для классификации
Поместите данные в одну матрицу и сделайте векторный grp
, который маркирует класс каждой точки.
cdata = [grnpts;redpts];
grp = ones(200,1);
% Green label 1, red label -1
grp(101:200) = -1;
Подготовьте перекрестную проверку
Настройте раздел для перекрестной проверки. Этот шаг фиксирует составы и наборы тестов, которые оптимизация использует на каждом шаге.
c = cvpartition(200,'KFold',10);
Оптимизируйте подгонку
Чтобы найти хорошую подгонку, означая один с низкой потерей перекрестной проверки, устанавливают опции использовать Байесовую оптимизацию. Используйте тот же раздел перекрестной проверки c
во всей оптимизации.
Для воспроизводимости используйте функцию приобретения 'expected-improvement-plus'
.
opts = struct('Optimizer','bayesopt','ShowPlots',true,'CVPartition',c,... 'AcquisitionFunctionName','expected-improvement-plus'); svmmod = fitcsvm(cdata,grp,'KernelFunction','rbf',... 'OptimizeHyperparameters','auto','HyperparameterOptimizationOptions',opts)
|=====================================================================================================| | Iter | Eval | Objective | Objective | BestSoFar | BestSoFar | BoxConstraint| KernelScale | | | result | | runtime | (observed) | (estim.) | | | |=====================================================================================================| | 1 | Best | 0.345 | 1.3145 | 0.345 | 0.345 | 0.00474 | 306.44 | | 2 | Best | 0.115 | 0.35528 | 0.115 | 0.12678 | 430.31 | 1.4864 | | 3 | Accept | 0.52 | 0.2217 | 0.115 | 0.1152 | 0.028415 | 0.014369 | | 4 | Accept | 0.61 | 0.171 | 0.115 | 0.11504 | 133.94 | 0.0031427 | | 5 | Accept | 0.34 | 0.29595 | 0.115 | 0.11504 | 0.010993 | 5.7742 | | 6 | Best | 0.085 | 0.15931 | 0.085 | 0.085039 | 885.63 | 0.68403 | | 7 | Accept | 0.105 | 0.1389 | 0.085 | 0.085428 | 0.3057 | 0.58118 | | 8 | Accept | 0.21 | 0.15836 | 0.085 | 0.09566 | 0.16044 | 0.91824 | | 9 | Accept | 0.085 | 0.16942 | 0.085 | 0.08725 | 972.19 | 0.46259 | | 10 | Accept | 0.1 | 0.12942 | 0.085 | 0.090952 | 990.29 | 0.491 | | 11 | Best | 0.08 | 0.1279 | 0.08 | 0.079362 | 2.5195 | 0.291 | | 12 | Accept | 0.09 | 0.12806 | 0.08 | 0.08402 | 14.338 | 0.44386 | | 13 | Accept | 0.1 | 0.16421 | 0.08 | 0.08508 | 0.0022577 | 0.23803 | | 14 | Accept | 0.11 | 0.13686 | 0.08 | 0.087378 | 0.2115 | 0.32109 | | 15 | Best | 0.07 | 0.15868 | 0.07 | 0.081507 | 910.2 | 0.25218 | | 16 | Best | 0.065 | 0.19104 | 0.065 | 0.072457 | 953.22 | 0.26253 | | 17 | Accept | 0.075 | 0.16534 | 0.065 | 0.072554 | 998.74 | 0.23087 | | 18 | Accept | 0.295 | 0.13509 | 0.065 | 0.072647 | 996.18 | 44.626 | | 19 | Accept | 0.07 | 0.16723 | 0.065 | 0.06946 | 985.37 | 0.27389 | | 20 | Accept | 0.165 | 0.14667 | 0.065 | 0.071622 | 0.065103 | 0.13679 | |=====================================================================================================| | Iter | Eval | Objective | Objective | BestSoFar | BestSoFar | BoxConstraint| KernelScale | | | result | | runtime | (observed) | (estim.) | | | |=====================================================================================================| | 21 | Accept | 0.345 | 0.12943 | 0.065 | 0.071764 | 971.7 | 999.01 | | 22 | Accept | 0.61 | 0.13008 | 0.065 | 0.071967 | 0.0010168 | 0.0010005 | | 23 | Accept | 0.345 | 0.14775 | 0.065 | 0.071959 | 0.0010674 | 999.18 | | 24 | Accept | 0.35 | 0.1343 | 0.065 | 0.071863 | 0.0010003 | 40.628 | | 25 | Accept | 0.24 | 0.24631 | 0.065 | 0.072124 | 996.55 | 10.423 | | 26 | Accept | 0.61 | 0.17307 | 0.065 | 0.072068 | 958.64 | 0.0010026 | | 27 | Accept | 0.47 | 0.14341 | 0.065 | 0.07218 | 993.69 | 0.029723 | | 28 | Accept | 0.3 | 0.14363 | 0.065 | 0.072291 | 993.15 | 170.01 | | 29 | Accept | 0.16 | 0.39099 | 0.065 | 0.072104 | 992.81 | 3.8594 | | 30 | Accept | 0.365 | 0.14145 | 0.065 | 0.072112 | 0.0010017 | 0.044287 | __________________________________________________________ Optimization completed. MaxObjectiveEvaluations of 30 reached. Total function evaluations: 30 Total elapsed time: 47.9235 seconds. Total objective function evaluation time: 6.4153 Best observed feasible point: BoxConstraint KernelScale _____________ ___________ 953.22 0.26253 Observed objective function value = 0.065 Estimated objective function value = 0.072112 Function evaluation time = 0.19104 Best estimated feasible point (according to models): BoxConstraint KernelScale _____________ ___________ 985.37 0.27389 Estimated objective function value = 0.072112 Estimated function evaluation time = 0.16964
svmmod = ClassificationSVM ResponseName: 'Y' CategoricalPredictors: [] ClassNames: [-1 1] ScoreTransform: 'none' NumObservations: 200 HyperparameterOptimizationResults: [1x1 BayesianOptimization] Alpha: [77x1 double] Bias: -0.2352 KernelParameters: [1x1 struct] BoxConstraints: [200x1 double] ConvergenceInfo: [1x1 struct] IsSupportVector: [200x1 logical] Solver: 'SMO' Properties, Methods
Найдите потерю оптимизированной модели.
lossnew = kfoldLoss(fitcsvm(cdata,grp,'CVPartition',c,'KernelFunction','rbf',... 'BoxConstraint',svmmod.HyperparameterOptimizationResults.XAtMinObjective.BoxConstraint,... 'KernelScale',svmmod.HyperparameterOptimizationResults.XAtMinObjective.KernelScale))
lossnew = 0.0650
Эта потеря совпадает с потерей, о которой сообщают в оптимизации вывод под "Наблюдаемым значением целевой функции".
Визуализируйте оптимизированный классификатор.
d = 0.02; [x1Grid,x2Grid] = meshgrid(min(cdata(:,1)):d:max(cdata(:,1)),... min(cdata(:,2)):d:max(cdata(:,2))); xGrid = [x1Grid(:),x2Grid(:)]; [~,scores] = predict(svmmod,xGrid); figure; h = nan(3,1); % Preallocation h(1:2) = gscatter(cdata(:,1),cdata(:,2),grp,'rg','+*'); hold on h(3) = plot(cdata(svmmod.IsSupportVector,1),... cdata(svmmod.IsSupportVector,2),'ko'); contour(x1Grid,x2Grid,reshape(scores(:,2),size(x1Grid)),[0 0],'k'); legend(h,{'-1','+1','Support Vectors'},'Location','Southeast'); axis equal hold off
Этот пример показывает, как предсказать апостериорные вероятности моделей SVM по сетке наблюдений, и затем построить апостериорные вероятности по сетке. Графический вывод апостериорных вероятностей представляет контуры решения.
Загрузите ирисовый набор данных Фишера. Обучите классификатор с помощью лепестковых длин и ширин, и удалите virginica разновидности из данных.
load fisheriris classKeep = ~strcmp(species,'virginica'); X = meas(classKeep,3:4); y = species(classKeep);
Обучите классификатор SVM с помощью данных. Это - хорошая практика, чтобы задать порядок классов.
SVMModel = fitcsvm(X,y,'ClassNames',{'setosa','versicolor'});
Оцените оптимальную функцию преобразования счета.
rng(1); % For reproducibility
[SVMModel,ScoreParameters] = fitPosterior(SVMModel);
Warning: Classes are perfectly separated. The optimal score-to-posterior transformation is a step function.
ScoreParameters
ScoreParameters = struct with fields:
Type: 'step'
LowerBound: -0.8431
UpperBound: 0.6897
PositiveClassProbability: 0.5000
Оптимальная функция преобразования счета является ступенчатой функцией, потому что классы отделимы. Поля LowerBound
и UpperBound
ScoreParameters
указывают на более низкие и верхние конечные точки интервала очков, соответствующих наблюдениям в разделяющих класс гиперплоскостях (поле). Никакое учебное наблюдение не находится в пределах поля. Если новый счет находится в интервале, то программное обеспечение присваивает соответствующее наблюдение положительная апостериорная вероятность класса, т.е. значение в поле PositiveClassProbability
ScoreParameters
.
Задайте сетку значений на наблюдаемом пробеле предиктора. Предскажите апостериорные вероятности для каждого экземпляра в сетке.
xMax = max(X); xMin = min(X); d = 0.01; [x1Grid,x2Grid] = meshgrid(xMin(1):d:xMax(1),xMin(2):d:xMax(2)); [~,PosteriorRegion] = predict(SVMModel,[x1Grid(:),x2Grid(:)]);
Постройте положительную область апостериорной вероятности класса и данные тренировки.
figure; contourf(x1Grid,x2Grid,... reshape(PosteriorRegion(:,2),size(x1Grid,1),size(x1Grid,2))); h = colorbar; h.Label.String = 'P({\it{versicolor}})'; h.YLabel.FontSize = 16; caxis([0 1]); colormap jet; hold on gscatter(X(:,1),X(:,2),y,'mc','.x',[15,10]); sv = X(SVMModel.IsSupportVector,:); plot(sv(:,1),sv(:,2),'yo','MarkerSize',15,'LineWidth',2); axis tight hold off
В изучении 2D класса, если классы отделимы, то существует три области: тот, где наблюдения имеют положительную апостериорную вероятность класса 0
, тот, где это - 1
и другой, где это - положительная априорная вероятность класса.
Этот пример показывает, как определить, какой квадрант изображения форма занимает по образованию модель выходных кодов с коррекцией ошибок (ECOC), состоявшую из линейных бинарных учеников SVM. Этот пример также иллюстрирует потребление дискового пространства моделей ECOC, которые хранят векторы поддержки, их метки и предполагаемые коэффициенты.
Создайте набор данных
Случайным образом поместите круг с радиусом пять в 50 50 изображение. Сделайте 5 000 изображений. Создайте метку для каждого изображения, указывающего на квадрант, который занимает круг. Квадрант 1 находится в верхнем правом углу, квадрант 2 находится в верхнем левом углу, квадрант 3 находится в нижнем левом углу, и квадрант 4 находится в нижнем правом углу. Предикторы являются интенсивностью каждого пикселя.
d = 50; % Height and width of the images in pixels n = 5e4; % Sample size X = zeros(n,d^2); % Predictor matrix preallocation Y = zeros(n,1); % Label preallocation theta = 0:(1/d):(2*pi); r = 5; % Circle radius rng(1); % For reproducibility for j = 1:n; figmat = zeros(d); % Empty image c = datasample((r + 1):(d - r - 1),2); % Random circle center x = r*cos(theta) + c(1); % Make the circle y = r*sin(theta) + c(2); idx = sub2ind([d d],round(y),round(x)); % Convert to linear indexing figmat(idx) = 1; % Draw the circle X(j,:) = figmat(:); % Store the data Y(j) = (c(2) >= floor(d/2)) + 2*(c(2) < floor(d/2)) + ... (c(1) < floor(d/2)) + ... 2*((c(1) >= floor(d/2)) & (c(2) < floor(d/2))); % Determine the quadrant end
Постройте наблюдение.
figure; imagesc(figmat); h = gca; h.YDir = 'normal'; title(sprintf('Quadrant %d',Y(end)));
Обучите модель ECOC
Используйте 25%-ю выборку затяжки и задайте обучение и демонстрационные индексы затяжки.
p = 0.25; CVP = cvpartition(Y,'Holdout',p); % Cross-validation data partition isIdx = training(CVP); % Training sample indices oosIdx = test(CVP); % Test sample indices
Создайте шаблон SVM, который задает хранение векторов поддержки бинарных учеников. Передайте его и данные тренировки к fitcecoc
, чтобы обучить модель. Определите учебную демонстрационную ошибку классификации.
t = templateSVM('SaveSupportVectors',true); MdlSV = fitcecoc(X(isIdx,:),Y(isIdx),'Learners',t); isLoss = resubLoss(MdlSV)
isLoss = 0
MdlSV
является обученной моделью мультикласса ClassificationECOC
. Это хранит данные тренировки и векторы поддержки каждого бинарного ученика. Для больших наборов данных, таких как те в анализе изображения, модель может использовать большую память.
Определите сумму дискового пространства, которое использует модель ECOC.
infoMdlSV = whos('MdlSV');
mbMdlSV = infoMdlSV.bytes/1.049e6
mbMdlSV = 763.5919
Модель использует 1 477,5 Мбайт.
Повысьте эффективность модели
Можно оценить производительность из выборки. Можно также оценить, была ли модель сверхподходящей с уплотненной моделью, которая не содержит векторы поддержки, их связанные параметры и данные тренировки.
Отбросьте векторы поддержки и связанные параметры из обученной модели ECOC. Затем отбросьте данные тренировки из получившейся модели при помощи compact
.
Mdl = discardSupportVectors(MdlSV); CMdl = compact(Mdl); info = whos('Mdl','CMdl'); [bytesCMdl,bytesMdl] = info.bytes; memReduction = 1 - [bytesMdl bytesCMdl]/infoMdlSV.bytes
memReduction = 0.0626 0.9996
В этом случае отбрасывание векторов поддержки уменьшает потребление памяти приблизительно на 3%. Уплотнение и отбрасывание векторов поддержки уменьшают размер приблизительно на 99,99%.
Альтернативный способ управлять векторами поддержки состоит в том, чтобы сократить их количество во время обучения путем определения большего ограничения поля, такой как 100. Хотя модели SVM, которые используют меньше векторов поддержки, более желательны и используют меньше памяти, увеличивание значения ограничения поля имеет тенденцию увеличивать учебное время.
Удалите MdlSV
и Mdl
из рабочей области.
clear Mdl MdlSV;
Оцените демонстрационную производительность затяжки
Вычислите ошибку классификации выборки затяжки. Постройте выборку демонстрационных прогнозов затяжки.
oosLoss = loss(CMdl,X(oosIdx,:),Y(oosIdx)) yHat = predict(CMdl,X(oosIdx,:)); nVec = 1:size(X,1); oosIdx = nVec(oosIdx); figure; for j = 1:9; subplot(3,3,j) imagesc(reshape(X(oosIdx(j),:),[d d])); h = gca; h.YDir = 'normal'; title(sprintf('Quadrant: %d',yHat(j))) end text(-1.33*d,4.5*d + 1,'Predictions','FontSize',17)
oosLoss = 0
Модель не неправильно классифицирует демонстрационных наблюдений затяжки.
bayesopt
| fitcsvm
| kfoldLoss
[1] Hastie, T., Р. Тибширэни и Дж. Фридман. Элементы Статистического Изучения, второго выпуска. Нью-Йорк: Спрингер, 2008.
[2] Christianini, N. и Дж. Шейв-Тейлор. Введение, чтобы поддержать векторные машины и другое основанное на ядре изучение методов. Кембридж, Великобритания: Издательство Кембриджского университета, 2000.
[3] Вентилятор, R.-E., P.-H. Чен и C.-J. Лин. “Выбор рабочего набора с помощью информации о втором порядке для учебных машин вектора поддержки”. Журнал Исследования Машинного обучения, Vol 6, 2005, стр 1889–1918.
[4] Кекмен V, T.-M. Хуан и М. Вогт. “Итеративный Один Алгоритм Данных для Учебных Машин Ядра от Огромных Наборов данных: Теория и Производительность”. В Машинах Вектора Поддержки: Теория и Приложения. Отредактированный Липо Ваном, 255–274. Берлин: Springer-Verlag, 2005.