KNN Search ブロックを使用して最近傍を探索
この例では、KNN Searchブロックを使用して Simulink® で最近傍を特定する方法を示します。このブロックは、クエリ点を受け入れ、最近傍探索モデル オブジェクト (ExhaustiveSearcher
またはKDTreeSearcher
) を使用して、観測データ内の k
個の最近傍点を返します。この例を完了するには、用意されている Simulink モデルを使用することも、新しいモデルを作成することもできます。
探索モデル オブジェクトの作成
フィッシャーのアヤメのデータ セットを読み込みます。150 本のアヤメについて 2 つの花弁の測定値が含まれる数値行列 X
を作成します。
load fisheriris
X = meas(:,3:4);
ExhaustiveSearcher
最近傍探索モデル オブジェクトを作成します。
searcher = ExhaustiveSearcher(X);
用意されている Simulink モデルを開く
この例では、KNN Searchブロックを含む Simulink モデル slexKNNSearchExample.slx
が用意されています。この Simulink モデルを開くことも、次のセクションの説明に従って新しいモデルを作成することもできます。
Simulink モデル slexKNNSearchExample.slx
を開きます。
open_system("slexKNNSearchExample")
Simulink モデルを開くと、Simulink モデルを読み込む前に、ソフトウェアがコールバック関数 PreLoadFcn
のコードを実行します。slexKNNSearchExample
の PreLoadFcn
コールバック関数には、学習済みモデルの searcher
変数がワークスペースにあるかどうかをチェックするコードが含まれています。ワークスペースに変数がない場合、PreLoadFcn
は標本データを読み込み、最近傍探索モデル オブジェクトを作成し、Simulink モデルの入力信号 (クエリ点) を作成します。コールバック関数を表示するには、[モデル化] タブの [設定] セクションで、[モデル設定] をクリックし、[モデル プロパティ] を選択します。次に、[コールバック] タブで、[モデルのコールバック] ペインのコールバック関数 PreLoadFcn
を選択します。
Simulink モデルの作成
新しい Simulink モデルを作成するには、[空のモデル] テンプレートを開き、Statistics and Machine Learning Toolbox™ ライブラリの [Cluster Analysis] セクションから KNN Search ブロックを追加します。
KNN Search ブロックをダブルクリックして、[ブロック パラメーター] ダイアログ ボックスを開きます。オブジェクトを含むワークスペース変数の名前を指定することにより、最近傍探索モデル オブジェクトをブロックにインポートします。既定の変数名は searcher
です。これは、コマンド ラインで作成したオブジェクトです。ダイアログ ボックスの [選択した最近傍探索モデル] セクションに、searcher
オブジェクトの探索方法が表示されます。
[最近傍距離の出力端子を追加する] チェック ボックスをオンにして、2 番目の出力端子 D を追加します。各クエリ点に対する 2 つの最近傍を探索するために、[最近傍の数] テキスト ボックスに「2」と入力します。距離計量は既に既定値 euclidean
に設定されています。[OK] をクリックします。
1 つの Inport ブロックを追加して KNN Search ブロックの入力に接続し、2 つの Outport ブロックを追加して KNN Search ブロックの出力に接続します。Outport 1 ブロックをクリックし、ブロック名を indices
に設定します。同様に、Outport 2 のブロック名を distances
に設定します。
出力信号を入力信号と同じ長さに指定するには、Inport ブロックをダブルクリックし、[Inport] ダイアログ ボックスの [実行] タブで [サンプル時間] を 1 に設定します。[OK] をクリックします。
コマンド ラインで、クエリ点のセットを行列の形式で作成します。各行にはクエリ点、各列には測定変数の値が含まれます。
Xquery = [3.8 1.4;
6.3 2.5;
2.1 0.5]; % Define three query points
Simulink モデルの構造体配列の形式で、入力信号を作成します。構造体配列には、次のフィールドが含まれていなければなりません。
time
— クエリ点がモデルに入力された時点。方向はXquery
行列内のクエリ点に対応しなければなりません。この例の場合はtime
が列ベクトルでなければなりません。signals
—values
フィールドとdimensions
フィールドが含まれている、入力クエリ点を説明する 1 行 1 列の構造体配列。values
は測定値の行列、dimensions
は測定変数の個数です。
最近傍のクエリ用に適切な構造体配列を作成します。
modelInput.time = (0:length(Xquery)-1)'; modelInput.signals(1).values = Xquery; modelInput.signals(1).dimensions = size(Xquery,2);
ワークスペースから信号データをインポートします。
Simulink で [コンフィギュレーション パラメーター] ダイアログ ボックスを開く。[モデル化] タブの [設定] セクションで、[モデル設定] ボタンの上半分をクリック。
[データのインポート/エクスポート] ペインで [入力] チェック ボックスをオンにし、隣のテキスト ボックスに「
modelInput
」と入力。[ソルバー] ペインの [シミュレーション時間] で、[終了時間] を
modelInput.time(end)
に設定。[ソルバーの選択] で、[タイプ] をFixed-step
に、[ソルバー] をdiscrete (no continuous states)
に設定。これらの設定により、modelInput
の各クエリ点についてのシミュレーションをモデルで実行できます。[OK] をクリックします。
詳細は、シミュレーションのための信号データの読み込み (Simulink)を参照してください。
モデルを Simulink で slexKNNSearchExample.slx
として保存します。
モデルをシミュレーション
モデルをシミュレートします。
simOut = sim("slexKNNSearchExample");
Inport ブロックでは、クエリ点を検出すると、その点を KNN Search ブロックに送ります。シミュレーション データ インスペクター (Simulink)を使用して、Outport ブロックのログ データを表示できます。
シミュレートした最近傍点のインデックスと距離をワークスペースにエクスポートします。
Ind_sig = simOut.yout.getElement(1); Index_val = squeeze(Ind_sig.Values.Data); distance_sig = simOut.yout.getElement(2); D_val = distance_sig.Values.Data;
クエリ点と最近傍の可視化
観測データ点の散布図を作成します。クエリ点と各クエリ点についての最近傍点をプロットします。
gscatter(X(:,1),X(:,2),species) axis equal hold on plot(Xquery(:,1),Xquery(:,2),"kx",Markersize=10,Linewidth=2) plot(X(Index_val,1),X(Index_val,2),"ro",Markersize=10) legend("setosa","versicolor","virginica","query point", ... "neighbor","Location","southeast") hold off
参考
KNN Search | createns
| knnsearch
| ExhaustiveSearcher
| KDTreeSearcher