Stateflow の使用によるクラス ラベルの予測
この例では、Stateflow® チャートをラベル予測に使用する方法を示します。この例では、fitcdiscr
を使用して判別分析モデルにフィッシャーのアヤメのデータセットについて学習をさせ、学習済みモデルを読み込んで新しいデータのラベルを予測するコード生成用の関数を定義します。この例の Stateflow チャートは、ストリーミング データを受け入れ、定義された関数を使用してラベルを予測します。
Statistics and Machine Learning Toolbox™ に含まれているフィッシャーのアヤメのデータセットには、150 本のアヤメの標本について種類 (species
) とがく片の長さ、がく片の幅、花弁の長さおよび花弁の幅の測定値 (meas
) が含まれています。このデータセットには、setosa、versicolor および virginica の 3 種類のそれぞれについて 50 個ずつの標本が含まれています。
フィッシャーのアヤメのデータセットを読み込みます。
load fisheriris
1、2 および 3 がそれぞれ setosa、versicolor および virginica に対応するインデックス ベクトルに species
を変換します。
species = grp2idx(species);
データを学習セットとテスト セットに分割します。
rng('default') % For reproducibility idx1 = randperm(150,75)'; idx2 = setdiff((1:150)',idx1); X = meas(idx1,:); Y = species(idx1,:); trainX = meas(idx2,:); trainY = species(idx2,:);
trainX
と trainY
を使用してモデルに学習をさせ、X
と Y
を使用して学習済みモデルをテストします。
2 次判別分析モデルに学習をさせます。
Mdl = fitcdiscr(trainX,trainY,'DiscrimType','quadratic');
Mdl
はClassificationDiscriminant
モデルです。コマンド ラインでは、Mdl
を使用して新しい観測値について予測を行うことができます。しかし、コード生成用の関数で入力引数として Mdl
を使用することはできません。saveLearnerForCoder
を使用して、関数内で読み込めるように Mdl
を準備します。
saveLearnerForCoder(Mdl,'DiscrIris');
saveLearnerForCoder
は Mdl
をコンパクトにして MAT ファイル DiscrIris.mat
に保存します。
予測された種類を Stateflow モデルの表示ボックスで表示するため、MATLAB® ファイル IrisSpecies.m
で classdef
ブロックを使用して列挙クラスを定義します。
classdef IrisSpecies < Simulink.IntEnumType enumeration Setosa(1) Versicolor(2) Virginica(3) end end
列挙型データの詳細については、列挙データ型の定義 (Stateflow)を参照してください。
学習済みモデルを使用して新しい測定データからアヤメの種類を予測する、mypredict.m
という名前の関数を定義します。この関数は以下を行う必要があります。
コード生成命令
%#codegen
を関数内に含める。アヤメの測定データを受け入れる。データは、行数以外は X と同等でなければなりません。
を使用して DiscrIris.mat を読み込む。
予測したアヤメの種類を返す。
function label = mypredict(X) %#codegen %MYPREDICT Predict species of iris flowers using discriminant model % mypredict predicts species of iris flowers using the compact % discriminant model in the file DiscrIris.mat. Rows of X correspond to % observations and columns correspond to predictor variables. label is % the predicted species. mdl = loadLearnerForCoder('DiscrIris'); labelTemp = predict(mdl,X); label = IrisSpecies(labelTemp); end
Simulink® モデル sf_countflowers.slx
を開きます。
sfName = 'sf_countflowers';
open_system(sfName);
Stateflow チャートに含まれている流れ図と Simulink モデルが Figure に表示されます。入力ノードで測定データが検出されると、データがチャートに送られます。チャートでは、アヤメの花の種類が予測され、各種類について花の本数がカウントされます。予測した種類がチャートからワークスペースに返され、モデル内の種類が一度に 1 つずつ表示されます。データ ストアのメモリ ブロック NumFlowers
に各種類の花の本数が格納されます。
このチャートでは、次のフィールドが含まれている fisheririsInput
という名前の構造体配列を入力データとして受け入れることを想定しています。
time
- 観測値がモデルに入力された時点。この例では、期間に 0 ~ 74 の整数を含めます。time
の方向は予測子データ内の観測値に対応しなければなりません。したがって、この例の場合はtime
が列ベクトルでなければなりません。signals
- 入力データを説明する、values
およびdimensions
というフィールドが含まれている 1 行 1 列の構造体配列。values
フィールドは予測子データの行列です。dimensions
フィールドは予測子変数の個数です。
アヤメの花の測定値用に適切な構造体配列を作成します。
fisheririsInput.time = (0:74)'; fisheririsInput.signals.dimensions = 4; fisheririsInput.signals.values = X;
ここで名前を fisheririsInput
から変更して、新しい名前をモデル内で指定できます。ただし、前述したフィールド名が構造体配列に含まれていることが Stateflow で想定されます。詳細については、データ構造体のルートレベル入力への読み込み (Simulink)を参照してください。
モデルをシミュレートします。
sim(sfName)
fisheririsInput
内のすべての観測値が一度に 1 つずつ処理された後で、モデルが Figure に表示されます。X(75,:)
について予測された種類は virginica です。X
内の setosa、versicolor および virginica の本数はそれぞれ 22、22 および 31 です。
変数 logsout
がワークスペースに表示されます。logsout
は、予測した種類が含まれている SimulinkData.Dataset
オブジェクトです。予測した種類のデータをシミュレーション ログから抽出します。
labelSF = logsout.getElement(1).Values.Data;
predict
を使用してコマンド ラインで種類を予測します。
labelCMD = predict(Mdl,X);
sf_countflowers
で予測した種類を、コマンド ラインで predict
を呼び出すことにより得られた種類と比較します。
isequal(labelCMD,labelSF)
ans = logical
1
isequal
は、すべての入力が等しい場合に logical 1 (true
) を返します。この比較により、予期される結果を sf_countflowers
が返すことを確認します。
Simulink Coder™ のライセンスもある場合、Simulink の sf_countflowers.slx
またはコマンド ラインからrtwbuild
(Simulink Coder)を使用して C コードを生成できます。詳細は、モデル用 C コードの生成 (Simulink Coder)を参照してください。
参考
loadLearnerForCoder
| saveLearnerForCoder
| predict
| slbuild
(Simulink)