Main Content

Find Nearest Neighbors Using KNN Search Block

Since R2023b

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 the Xquery 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 fields values and dimensions, where values is a matrix of measurement values, and dimensions 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 to Fixed-step, and set Solver to discrete (no continuous states). These settings enable the model to run the simulation for each query point in modelInput. 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

| | | |

Related Topics