Nearest Neighbor Classifier#
This topic demonstrates the process of creating an updatable empty k-nearest neighbor model using Core ML Tools.
Create the Classifier#
Create the classifier and apply its properties:
number_of_dimensions = 128 from coremltools.models.nearest_neighbors import KNearestNeighborsClassifierBuilder builder = KNearestNeighborsClassifierBuilder(input_name='input', output_name='output', number_of_dimensions=number_of_dimensions, default_class_label='defaultLabel', number_of_neighbors=3, weighting_scheme='inverse_distance', index_type='linear') builder.author = 'Core ML Tools Example' builder.license = 'MIT' builder.description = 'Classifies {} dimension vector based on 3 nearest neighbors'.format(number_of_dimensions) builder.spec.description.input[0].shortDescription = 'Input vector to classify' builder.spec.description.output[0].shortDescription = 'Predicted label. Defaults to \'defaultLabel\'' builder.spec.description.output[1].shortDescription = 'Probabilities / score for each possible label.' builder.spec.description.trainingInput[0].shortDescription = 'Example input vector' builder.spec.description.trainingInput[1].shortDescription = 'Associated true label of each example vector'
Note
An empty
knn
model is updatable by default:# By default an empty knn model is updatable builder.is_updatable
True
Confirm that the number of dimensions are set correctly:
# Let's confirm the number of dimension is set correctly builder.number_of_dimensions
128
Set the Number of Neighbors Value#
Verify the current number of neighbors value:
# Let's check what the value of 'numberOfNeighbors' is builder.number_of_neighbors
3
Note
The number of neighbors is bounded by the default range:
# The number of neighbors is bounded by the default range... builder.number_of_neighbors_allowed_range()
(1, 1000)
If you set the number of neighbors to a value outside of this default range, an
ValueError
will occur as shown in the Out tab:# If we try to set the number of neighbors to a value outside of this range builder.number_of_neighbors = 1001
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-17-e8bea591e72c> in <module> 1 # If we try to set the number of neighbors to a value outside of this range ----> 2 builder.number_of_neighbors = 1001 ~/eng/sources/coreml/coremltools/coremltools/models/nearest_neighbors/builder.py in number_of_neighbors(self, number_of_neighbors) 312 self.spec.kNearestNeighborsClassifier.numberOfNeighbors.defaultValue = number_of_neighbors 313 else: --> 314 raise ValueError('number_of_neighbors is not within range bounds') 315 else: 316 spec_values = self.spec.kNearestNeighborsClassifier.numberOfNeighbors.set.values ValueError: number_of_neighbors is not within range bounds
Change the bounds for the number of neighbors. Individual values can be set for the
numberOfNeighbors
parameter:# Instead of a range, you can a set individual values that are valid for the numberOfNeighbors parameter. builder.set_number_of_neighbors_with_bounds(3, allowed_set={ 1, 3, 5 })
Verify change using the
number_of_neighbors_allowed_set()
method.# Check out the results of the previous operation builder.number_of_neighbors_allowed_set()
{1, 3, 5}
The number of neighbors value can now be set without an error:
# And now if you attempt to set it to an invalid value... builder.number_of_neighbors = 4
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-20-98c77c72c722> in <module> 1 # And now if you attempt to set it to an invalid value... ----> 2 builder.number_of_neighbors = 4 ~/eng/sources/coreml/coremltools/coremltools/models/nearest_neighbors/builder.py in number_of_neighbors(self, number_of_neighbors) 320 self.spec.kNearestNeighborsClassifier.numberOfNeighbors.defaultValue = number_of_neighbors 321 return --> 322 raise ValueError('number_of_neighbors is not an allowed value') 323 324 def set_number_of_neighbors_with_bounds(self, number_of_neighbors, allowed_range=None, allowed_set=None): ValueError: number_of_neighbors is not valid
If desired, you can revert back to a valid range:
# And of course you can go back to a valid range
builder.set_number_of_neighbors_with_bounds(3, allowed_range=(1, 30))
Set the Index Type#
Verify the current index type:
# Let's see what the index type is builder.index_type
'linear'
Set the index and leaf size:
# Let's set the index to kd_tree with leaf size of 30 builder.set_index_type('kd_tree', 30) builder.index_type
'kd_tree'
Save the model:
mlmodel_updatable_path = './UpdatableKNN.mlmodel' # Save the updated spec from coremltools.models import MLModel mlmodel_updatable = MLModel(builder.spec) mlmodel_updatable.save(mlmodel_updatable_path)