Этот пример показывает, как сгенерировать код для классификации данных с помощью модели машины вектора поддержки (SVM). Обучите модель с помощью числовых и категориальных предикторов.
Поскольку генерация кода не поддерживает категориальные предикторы, используйте dummyvar
, чтобы преобразовать категориальные предикторы в числовые фиктивные переменные прежде, чем соответствовать классификатору SVM. При передаче новых данных обученной модели необходимо предварительно обработать данные подобным образом.
Загрузите набор данных patients
. Составьте таблицу с помощью числовых переменных Systolic
и Diastolic
. Каждая строка таблицы соответствует различному пациенту.
load patients
tbl = table(Diastolic,Systolic);
head(tbl)
ans=8×2 table
Diastolic Systolic
_________ ________
93 124
77 109
83 125
75 117
80 122
70 121
88 130
82 115
Преобразуйте переменную Gender
в переменную categorical
. Порядок категорий в categoricalGender
важен, потому что это определяет порядок столбцов в данных о предикторе. Используйте dummyvar
, чтобы преобразовать категориальную переменную в матрицу нулей и единиц, где значение 1
в (i,j)
th запись указывает, что i
th пациент принадлежит j
th категория.
categoricalGender = categorical(Gender); orderGender = categories(categoricalGender)
orderGender = 2x1 cell array
{'Female'}
{'Male' }
dummyGender = dummyvar(categoricalGender);
Примечание: получившаяся матрица dummyGender
имеет неполный ранг. В зависимости от типа модели вы обучаетесь, этот дефицит ранга может быть проблематичным. Например, когда учебные линейные модели, удалите первый столбец фиктивных переменных.
Составьте таблицу, которая содержит фиктивную переменную dummyGender
с соответствующими переменными заголовками. Объедините эту новую таблицу с tbl
.
tblGender = array2table(dummyGender,'VariableNames',orderGender);
tbl = [tbl tblGender];
head(tbl)
ans=8×4 table
Diastolic Systolic Female Male
_________ ________ ______ ____
93 124 0 1
77 109 0 1
83 125 1 0
75 117 1 0
80 122 1 0
70 121 1 0
88 130 1 0
82 115 0 1
Преобразуйте переменную SelfAssessedHealthStatus
в переменную categorical
. Отметьте порядок категорий в categoricalHealth
и преобразуйте переменную в числовую матрицу с помощью dummyvar
.
categoricalHealth = categorical(SelfAssessedHealthStatus); orderHealth = categories(categoricalHealth)
orderHealth = 4x1 cell array
{'Excellent'}
{'Fair' }
{'Good' }
{'Poor' }
dummyHealth = dummyvar(categoricalHealth);
Составьте таблицу, которая содержит dummyHealth
с соответствующими переменными заголовками. Объедините эту новую таблицу с tbl
.
tblHealth = array2table(dummyHealth,'VariableNames',orderHealth);
tbl = [tbl tblHealth];
head(tbl)
ans=8×8 table
Diastolic Systolic Female Male Excellent Fair Good Poor
_________ ________ ______ ____ _________ ____ ____ ____
93 124 0 1 1 0 0 0
77 109 0 1 0 1 0 0
83 125 1 0 0 0 1 0
75 117 1 0 0 1 0 0
80 122 1 0 0 0 1 0
70 121 1 0 0 0 1 0
88 130 1 0 0 0 1 0
82 115 0 1 0 0 1 0
Третья строка tbl
, например, соответствует пациенту с этими характеристиками: диастолическое кровяное давление 83, систолическое кровяное давление 125, розетка и хорошее самооцененное состояние здоровья.
Поскольку все значения в tbl
являются числовыми, можно преобразовать таблицу в матричный X
.
X = table2array(tbl);
Обучите классификатор SVM с помощью X
. Задайте переменную Smoker
как ответ.
Y = Smoker; Mdl = fitcsvm(X,Y);
Сгенерируйте код, который загружает классификатор SVM, берет новые данные о предикторе в качестве входного параметра, и затем классифицирует новые данные.
Сохраните классификатор SVM в файл с помощью saveCompactModel
.
saveCompactModel(Mdl,'SVMClassifier')
saveCompactModel
сохраняет классификатор в двоичный файл MATLAB® SVMClassifier.mat
как массив структур в текущей папке.
Задайте функцию точки входа mySVMPredict
, который берет новые данные о предикторе в качестве входного параметра. В функции загрузите классификатор SVM при помощи loadCompactModel
, и затем передайте загруженный классификатор predict
.
type mySVMPredict.m % Display contents of mySVMPredict.m file
function label = mySVMPredict(X) %#codegen Mdl = loadCompactModel('SVMClassifier'); label = predict(Mdl,X); end
Примечание: Если вы нажимаете кнопку, расположенную в верхнем правом разделе этой страницы, и открываете этот пример в MATLAB, затем MATLAB открывает папку в качестве примера. Эта папка включает файл функции точки входа mySVMPredict.m
.
Сгенерируйте код для mySVMPredict
при помощи codegen
. Задайте тип данных и размерности новых данных о предикторе при помощи coder.typeof
так, чтобы сгенерированный код принял массив переменного размера.
codegen mySVMPredict -args {coder.typeof(X,[Inf 8],[1 0])}
Проверьте, что mySVMPredict
и файл MEX возвращают те же результаты для данных тренировки.
label = predict(Mdl,X); mylabel = mySVMPredict(X); mylabel_mex = mySVMPredict_mex(X); verifyMEX = isequal(label,mylabel,mylabel_mex)
verifyMEX = logical
1
Чтобы предсказать метки для новых данных, необходимо сначала предварительно обработать новые данные. Если при запуске сгенерированный код в среде MATLAB, можно выполнить шаги предварительной обработки, описанные в этом разделе. Если вы развертываете сгенерированный код вне среды MATLAB, шаги предварительной обработки могут отличаться. В любом случае необходимо гарантировать, что новые данные имеют те же столбцы как данные тренировки X
.
В этом примере возьмите третьих, четвертых, и пятых пациентов в наборе данных patients
. Предварительно обработайте данные для этих пациентов так, чтобы получившаяся числовая матрица совпадала с формой данных тренировки.
Преобразуйте категориальные переменные в фиктивные переменные. Поскольку новые наблюдения не могут включать значения от всех категорий, необходимо задать те же категории как те используемые во время обучения и поддержать тот же порядок категории. В MATLAB передайте упорядоченный массив ячеек названий категории, сопоставленных с соответствующей переменной данных тренировки (в этом примере, orderGender
для гендерных значений и orderHealth
для самооцененных значений состояния здоровья).
newcategoricalGender = categorical(Gender(3:5),orderGender); newdummyGender = dummyvar(newcategoricalGender); newcategoricalHealth = categorical(SelfAssessedHealthStatus(3:5),orderHealth); newdummyHealth = dummyvar(newcategoricalHealth);
Объедините все новые данные в числовую матрицу.
newX = [Diastolic(3:5) Systolic(3:5) newdummyGender newdummyHealth]
newX = 3×8
83 125 1 0 0 0 1 0
75 117 1 0 0 1 0 0
80 122 1 0 0 0 1 0
Обратите внимание на то, что newX
соответствует точно третьим, четвертым, и пятым строкам матричного X
.
Проверьте, что mySVMPredict
и файл MEX возвращают те же результаты для новых данных.
newlabel = predict(Mdl,newX); newmylabel = mySVMPredict(newX); newmylabel_mex = mySVMPredict_mex(newX); newverifyMEX = isequal(newlabel,newmylabel,newmylabel_mex)
newverifyMEX = logical
1
ClassificationSVM
| categorical
| codegen
| coder.Constant
| coder.typeof
| dummyvar
| loadCompactModel
| saveCompactModel