knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(rnndescent)

A lot of distance functions are implemented in rnndescent, which you can specify in every function which needs them with the metric parameter. Technically not all of these are metrics, but let's just let that slide. Typical are "euclidean" or "cosine" the latter being more common for document-based data. For binary data, "hamming" or "jaccard" might be a good place to start.

The metrics here are a subset of those offered by the PyNNDescent Python package which in turn reproduces those in the scipy.spatial.distance module of SciPy. Many of the binary distances seem to have definitions shared with [@choi2010survey] so you may want to look in that reference for an exact definition.

For non-sparse data, the following variants are available with preprocessing: this trades memory for a potential speed up during the distance calculation. Some minor numerical differences should be expected compared to the non-preprocessed versions:

Specialized Binary Metrics

Some metrics are intended for use with binary data. This means that:

The metrics you can use with binary data are:

Here's an example of using binary data stored as 0s and 1s with the "hamming" metric:

set.seed(42)
binary_data <- matrix(sample(c(0, 1), 100, replace = TRUE), ncol = 10)
head(binary_data)
nn <- brute_force_knn(binary_data, k = 4, metric = "hamming")

Now let's convert it to a logical matrix:

logical_data <- binary_data == 1
head(logical_data)
logical_nn <- brute_force_knn(logical_data, k = 4, metric = "hamming")

The results will be the same:

all.equal(nn, logical_nn)

but on a real-world dataset, the logical version will be much faster.

References



jlmelville/rnndescent documentation built on April 19, 2024, 8:26 p.m.