________________________________________________________________________

This file is part of Logtalk <https://logtalk.org/>
SPDX-FileCopyrightText: 1998-2026 Paulo Moura <pmoura@logtalk.org>
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
________________________________________________________________________


`knn_classifier`
=====

k-Nearest Neighbors classifier supporting multiple distance metrics,
weighting schemes, and both categorical and continuous features. This
is a lazy learning algorithm that classifies instances based on the
majority class among the k nearest training instances.

The library implements the `classifier_protocol` defined in the
`classification_protocols` library. It provides predicates for learning a
classifier from a dataset, using it to make predictions, and exporting
it as a list of predicate clauses or to a file.

Datasets are represented as objects implementing the `dataset_protocol`
protocol from the `classification_protocols` library. See `test_files`
directory for examples.


API documentation
-----------------

Open the [../../docs/library_index.html#knn_classifier](../../docs/library_index.html#knn_classifier)
link in a web browser.


Loading
-------

To load this library, load the `loader.lgt` file:

	| ?- logtalk_load(knn_classifier(loader)).


Testing
-------

To test this library predicates, load the `tester.lgt` file:

	| ?- logtalk_load(knn_classifier(tester)).


Features
--------

- **Multiple Distance Metrics**: Euclidean, Manhattan, Chebyshev, Minkowski.
- **Flexible Weighting**: Uniform, distance-based, and Gaussian weighting of neighbors.
- **Mixed Features**: Automatically handles categorical and continuous features.
- **Configurable Options**: k value, distance metric, and weighting scheme via predicate options.
- **Probability Estimation**: Provides confidence scores for predictions.
- **Classifier Export**: Learned classifiers can be exported as predicate clauses.


Usage
-----

### Learning a Classifier

    % Learn from a dataset object with default options (k=3, euclidean, uniform)
    | ?- knn_classifier::learn(my_dataset, Classifier).
    ...

    % Learn with custom options
    | ?- knn_classifier::learn(my_dataset, Classifier, [k(5), distance_metric(manhattan)]).
    ...

### Making Predictions

    % Predict class for a new instance
    | ?- Instance = [attr1-value1, attr2-value2, ...],
         knn_classifier::learn(my_dataset, Classifier),
         knn_classifier::predict(Classifier, Instance, PredictedClass).
    PredictedClass = ...
    ...

    % Predict with custom options
    | ?- knn_classifier::predict(Classifier, Instance, PredictedClass, [k(5), weight_scheme(distance)]).
    ...

    % Get probability distribution
    | ?- knn_classifier::predict_probabilities(Classifier, Instance, Probabilities).
    Probabilities = [class1-0.67, class2-0.33]
    ...

### Exporting the Classifier

Learned classifiers can be exported as a list of clauses or to a file for later use.

    % Export as predicate clauses
    | ?- knn_classifier::learn(my_dataset, Classifier),
         knn_classifier::export_to_clauses(my_dataset, Classifier, my_classifier, Clauses).
    Clauses = [my_classifier(...)]
    ...

    % Export to a file
    | ?- knn_classifier::learn(my_dataset, Classifier),
         knn_classifier::export_to_file(my_dataset, Classifier, my_classifier, 'classifier.pl').
    ...

### Using a learned classifier

Learned and saved classifiers can later be used for predictions without needing
to access the original training dataset.

    % Later, load the file and use the classifier
    | ?- consult('classifier.pl'),
         my_classifier(Classifier),
         Instance = [...],
         knn_classifier::predict(Classifier, Instance, Class).
    Class = ...
    ...


Options
-------

The following options can be passed to the `predict/4` and
`predict_probabilities/4` predicates:

- `k(K)`: Number of neighbors to consider (default: 3)
- `distance_metric(Metric)`: Distance metric to use. Options: `euclidean` (default), `manhattan`, `chebyshev`, `minkowski`
- `weight_scheme(Scheme)`: Weighting scheme for neighbor votes. Options: `uniform` (default), `distance`, `gaussian`


Classifier representation
-------------------------

The learned classifier is represented as a compound term:

    knn_classifier(AttributeNames, FeatureTypes, Instances)

Where:

- `AttributeNames`: List of attribute names in order
- `FeatureTypes`: List of types (`numeric` or `categorical`)
- `Instances`: List of `Values-Class` pairs (the training data in compact form)

When exported using `export_to_clauses/4` or `export_to_file/4`,
this classifier term is serialized directly as the single argument of the
generated predicate clause so that the exported model can be loaded and
reused as-is.


References
----------

1. Cover, T. & Hart, P. (1967). "Nearest neighbor pattern classification". IEEE Transactions on Information Theory.
2. Hastie, T., Tibshirani, R., & Friedman, J. (2009). "The Elements of Statistical Learning". Chapter 13.
3. Mitchell, T. (1997). "Machine Learning". Chapter 8: Instance-Based Learning.
