Main Content

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,:);

trainXtrainY を使用してモデルに学習をさせ、XY を使用して学習済みモデルをテストします。

2 次判別分析モデルに学習をさせます。

Mdl = fitcdiscr(trainX,trainY,'DiscrimType','quadratic');

MdlClassificationDiscriminantモデルです。コマンド ラインでは、Mdl を使用して新しい観測値について予測を行うことができます。しかし、コード生成用の関数で入力引数として Mdl を使用することはできません。saveLearnerForCoderを使用して、関数内で読み込めるように Mdl を準備します。

saveLearnerForCoder(Mdl,'DiscrIris');

saveLearnerForCoderMdl をコンパクトにして MAT ファイル DiscrIris.mat に保存します。

予測された種類を Stateflow モデルの表示ボックスで表示するため、MATLAB® ファイル IrisSpecies.mclassdef ブロックを使用して列挙クラスを定義します。

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);

sf_countflowers_sim_open_system.png

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)

sf_countflowers_sim.png

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)を参照してください。

参考

| | | (Simulink)

関連するトピック