Find Nearest Neighbors Using KNN Search Block
This example shows how to use the KNN Search block to determine nearest neighbors in Simulink®. The block accepts a query point and returns the k
nearest neighbor points in the observational data using a nearest neighbor searcher object (ExhaustiveSearcher
or KDTreeSearcher
). To complete this example, you can use the provided Simulink model, or create a new model.
Create Searcher Object
Load the Fisher iris data set. Create a numeric matrix X
that contains two petal measurements for 150 irises.
load fisheriris
X = meas(:,3:4);
Create an ExhaustiveSearcher
nearest neighbor searcher object.
searcher = ExhaustiveSearcher(X);
Open Provided Simulink Model
This example provides the Simulink model slexKNNSearchExample.slx
, which includes the KNN Search block. You can open the Simulink model or create a new model as described in the next section.
Open the Simulink model slexKNNSearchExample.slx
.
open_system("slexKNNSearchExample")
If you open the Simulink model, then the software runs the code in the PreLoadFcn
callback function before loading the Simulink model. The PreLoadFcn
callback function of slexKNNSearchExample
includes code to check if your workspace contains the searcher
variable for the trained model. If the workspace does not contain the variable, PreLoadFcn
loads the sample data, creates the nearest neighbor searcher object, and creates an input signal (query points) for the Simulink model. To view the callback function, in the Setup section on the Modeling tab, click Model Settings and select Model Properties. Then, on the Callbacks tab, select the PreLoadFcn
callback function in the Model callbacks pane.
Create Simulink Model
To create a new Simulink model, open the Blank Model template and add the KNN Search block from the Cluster Analysis section of the Statistics and Machine Learning Toolbox™ library.
Double-click the KNN Search block to open the Block Parameters dialog box. Import a nearest neighbor searcher object into the block by specifying the name of a workspace variable that contains the object. The default variable name is searcher
, which is the object you created at the command line. The Selected Nearest Neighbor Searcher section of the dialog box displays the search method of the searcher
object.
Select the Add output port for nearest neighbor distances check box to add the second output port D. Enter 2 in the Number of nearest neighbors text box to search for the two nearest neighbors to each query point. The distance metric is already set to the default value euclidean
. Click OK.
Add an Inport block and connect it to the input of the KNN Search block, then add two Outport blocks and connect them to the outputs of the KNN Search block. Click the Outport 1 block and set the block name to indices
. Similarly, set the Outport 2 block name to distances
.
To specify that the output signals have the same length as the input signal, double-click the Inport block and set Sample time to 1 on the Execution tab of the Inport dialog box. Click OK.
At the command line, create a set of query points in the form of a matrix. Each row contains a query point, and each column contains a measurement variable value.
Xquery = [3.8 1.4;
6.3 2.5;
2.1 0.5]; % Define three query points
Create an input signal in the form of a structure array for the Simulink model. The structure array must contain these fields:
time
— The points in time at which the query points enter the model. The orientation must correspond to the query points in theXquery
matrix. In this example,time
must be a column vector.signals
— A 1-by-1 structure array describing the input query points and containing the fieldsvalues
anddimensions
, wherevalues
is a matrix of measurement values, anddimensions
is the number of measurement variables.
Create an appropriate structure array for nearest neighbor queries.
modelInput.time = (0:length(Xquery)-1)'; modelInput.signals(1).values = Xquery; modelInput.signals(1).dimensions = size(Xquery,2);
Import the signal data from the workspace:
Open the Configuration Parameters dialog box in Simulink. In the Setup section of the Modeling tab, click the top half of the Model Settings button.
In the Data Import/Export pane, select the Input check box and enter
modelInput
in the adjacent text box.In the Solver pane, under Simulation time, set Stop time to
modelInput.time(end)
. Under Solver selection, set Type toFixed-step
, and set Solver todiscrete (no continuous states)
. These settings enable the model to run the simulation for each query point inmodelInput
. Click OK.
For more details, see Load Signal Data for Simulation (Simulink).
Save the model as slexKNNSearchExample.slx
in Simulink.
Simulate Model
Simulate the model.
simOut = sim("slexKNNSearchExample");
When the Inport block detects a query point, it directs the point into the KNN Search block. You can use the Simulation Data Inspector (Simulink) to view the logged data of the Outport blocks.
Export the simulated nearest neighbor point indices and distances to the workspace.
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;
Visualize Query Points and Nearest Neighbors
Create a scatter plot of the observational data points. Plot the query points and the nearest neighbor points for each query point.
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
See Also
KNN Search | createns
| knnsearch
| ExhaustiveSearcher
| KDTreeSearcher