カテゴリカル予測子用のダミー変数の作成と C/C++ コードの生成
この例では、サポート ベクター マシン (SVM) モデルを使用してデータを分類するためのコードを生成する方法を示します。数値予測子と、符号化されたカテゴリカル予測子を使用してモデルに学習をさせます。SVM 分類器を当てはめる前に、dummyvar
を使用してカテゴリカル予測子を数値ダミー変数に変換します。新しいデータを学習済みモデルに渡す場合、同様の方法でデータを前処理しなければなりません。
あるいは、CategoricalPredictors
プロパティでカテゴリカル予測子が特定されている場合は、コードを生成するためにダミー変数を手動で作成する必要はありません。カテゴリカル予測子は自動的に処理されます。たとえば、table のデータを分類するためのコードの生成を参照してください。
データの前処理と SVM 分類器の学習
patients
データ セットを読み込みます。数値変数 Diastolic
および Systolic
を使用して table を作成します。table の各行は、異なる患者に対応しています。
load patients
tbl = table(Diastolic,Systolic);
head(tbl)
Diastolic Systolic _________ ________ 93 124 77 109 83 125 75 117 80 122 70 121 88 130 82 115
変数 Gender
を categorical
変数に変換します。予測子データの列の順序が決まるので、categoricalGender
内のカテゴリの順序は重要です。dummyvar
を使用して、カテゴリカル変数を 0 と 1 の行列に変換します。この行列の (i,j)
番目のエントリの値が 1
である場合、i
番目の患者は j
番目のカテゴリに属します。
categoricalGender = categorical(Gender); orderGender = categories(categoricalGender)
orderGender = 2x1 cell
{'Female'}
{'Male' }
dummyGender = dummyvar(categoricalGender);
メモ: 生成される行列 dummyGender
はランク落ちになります。学習を行うモデルのタイプによっては、このランク落ちが問題になる可能性があります。たとえば、線形モデルに学習をさせる場合、ダミー変数の 1 列目を削除します。
対応する変数見出しの付いたダミー変数 dummyGender
が含まれている table を作成します。この新しい table を tbl
と結合します。
tblGender = array2table(dummyGender,'VariableNames',orderGender);
tbl = [tbl tblGender];
head(tbl)
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
{'Excellent'}
{'Fair' }
{'Good' }
{'Poor' }
dummyHealth = dummyvar(categoricalHealth);
対応する変数見出しで dummyHealth
が含まれている table を作成します。この新しい table を tbl
と結合します。
tblHealth = array2table(dummyHealth,'VariableNames',orderHealth);
tbl = [tbl tblHealth];
head(tbl)
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
の 3 行目は、拡張期血圧が 83、収縮期血圧が 125、女性、健康状態の自己評価が良好である患者に対応します。
tbl
の値はすべて数値なので、table を行列 X
に変換できます。
X = table2array(tbl);
X
と自動カーネル スケールのガウス カーネル関数を使用して SVM 分類器に学習させます。応答として変数 Smoker
を指定します。
Y = Smoker; Mdl = fitcsvm(X,Y, ... 'KernelFunction','gaussian','KernelScale','auto');
C/C++ コードの生成
SVM 分類器を読み込んで、新しい予測子データを入力引数として受け入れてから、新しいデータを分類するコードを生成します。
saveLearnerForCoder
を使用して、SVM 分類器をファイルに保存します。
saveLearnerForCoder(Mdl,'SVMClassifier')
saveLearnerForCoder
は、現在のフォルダーの SVMClassifier.mat
という MATLAB® バイナリ ファイルに構造体配列として分類器を保存します。
新しい予測子データを入力引数として受け入れるエントリポイント関数 mySVMPredict
を定義します。この関数では、loadLearnerForCoder
を使用して SVM 分類器を読み込んで predict
に渡します。
function label = mySVMPredict(X) %#codegen Mdl = loadLearnerForCoder('SVMClassifier'); label = predict(Mdl,X); end
codegen
を使用して mySVMPredict
のコードを生成します。生成されるコードが可変サイズの配列を受け入れるようにするため、coder.typeof
を使用して新しい予測子データのデータ型と次元を指定します。
codegen mySVMPredict -args {coder.typeof(X,[Inf 8],[1 0])}
Code generation successful.
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
データ セットの 3 番目、4 番目および 5 番目の患者を使用します。これらの患者のデータを前処理して、生成される数値行列を学習データの形式と一致させます。
カテゴリカル変数をダミー変数に変換します。新しい観測値にすべてのカテゴリの値が含まれているとは限らないので、学習時に使用したものと同じカテゴリを同じ順序で指定する必要があります。MATLAB で、対応する学習データの変数 (この例では、性別の値に対する orderGender
と、健康状態の自己評価の値に対する orderHealth
) に関連付けられているカテゴリ名が順序付けられて格納されている cell 配列を渡します。
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
の 3 行目、4 行目 および 5 行目に厳密に対応することに注意してください。
mySVMPredict
と MEX ファイルが新しいデータに対して同じ結果を返すことを確認します。
newlabel = predict(Mdl,newX); newmylabel = mySVMPredict(newX); newmylabel_mex = mySVMPredict_mex(newX); newverifyMEX = isequal(newlabel,newmylabel,newmylabel_mex)
newverifyMEX = logical
1
参考
dummyvar
| categorical
| ClassificationSVM
| codegen
(MATLAB Coder) | coder.typeof
(MATLAB Coder) | loadLearnerForCoder
| coder.Constant
(MATLAB Coder) | saveLearnerForCoder