Skip to content

Navigation Menu

Sign in
Sign up

[BUG] HDBSCAN treats min_samples as excluding the point itself despite documented inclusive semantics #8545

Open
Labels
? - Needs TriageNeed team to review and classify bugSomething isn't working

Description

Describe the bug

cuml.cluster.HDBSCAN labels all samples as noise for a dataset containing two clearly separated three-point clusters when both min_cluster_size=3 and min_samples=3.

cuML returns:

[-1 -1 -1 -1 -1 -1]

The equivalent sklearn.cluster.HDBSCAN call returns the two expected clusters:

[0 0 0 1 1 1]

Both the cuML HDBSCAN documentation and the scikit-learn HDBSCAN documentation state that min_samples includes the point itself. The observed cuML result appears to require an additional neighboring point, which is inconsistent with the documented parameter semantics.

Steps/Code to reproduce bug

cuML reproducer:

import numpy as np
from cuml.cluster import HDBSCAN
print(HDBSCAN(min_cluster_size=3,min_samples=3,).fit_predict(np.array([[0., 0.],[1., 0.],[0., 1.],[10., 10.],[11., 10.],[10., 11.],])))

Output:

[-1 -1 -1 -1 -1 -1]

For comparison, the equivalent scikit-learn code:

import numpy as np
from sklearn.cluster import HDBSCAN
print(HDBSCAN(min_cluster_size=3,min_samples=3,).fit_predict(np.array([[0., 0.],[1., 0.],[0., 1.],[10., 10.],[11., 10.],[10., 11.],])))

Output:

[0 0 0 1 1 1]

Expected behavior

With min_cluster_size=3 and min_samples=3, each compact group of three points should be eligible to form a cluster because the min_samples count includes the point itself.

cuML should therefore identify the two separated clusters, equivalent up to label permutation to:

[0 0 0 1 1 1]

It should not mark all six points as noise.

Environment details (please complete the following information):

  • Environment location: Docker
  • Linux Distro/Architecture: Ubuntu 24.04 / x86_64
  • GPU Model/Driver: NVIDIA GeForce RTX 4090 / 595.71.05
  • CUDA: 13.2
  • Method of cuDF & cuML install: conda

conda list:

conda list
# packages in environment at /opt/conda/envs/rapids-26.08:
#
# Name Version Build Channel
# Name Version Build Channel
python 3.14.6 h242f9ac_102_cp314 conda-forge
numpy 2.4.6 py314h2b28147_0 conda-forge
scipy 1.16.3 py314hf07bd8e_2 conda-forge
scikit-learn 1.9.0 np2py314hf09ca88_0 conda-forge
rapids 26.08.00 cuda13_260806_c2656556 rapidsai
cuml 26.08.00 cuda13_cp311_abi3_260805_265b9da6 rapidsai
libcuml 26.08.00 cuda13_260805_265b9da6 rapidsai
cudf 26.08.00 cuda13_cp311_abi3_260805_ff5b362d rapidsai
libraft 26.08.00 cuda13_260805_ebf92684 rapidsai
libraft-headers 26.08.00 cuda13_260805_ebf92684 rapidsai
pylibraft 26.08.00 cuda13_cp311_abi3_260805_ebf92684 rapidsai
cuvs 26.08.01 cuda13_cp311_abi3_260806_25b1be43 rapidsai
libcuvs 26.08.01 cuda13_260806_25b1be43 rapidsai
cupy 14.1.1 py314hdea9c46_0 conda-forge
cupy-core 14.1.1 py314hcd3b49b_0 conda-forge
numba 0.64.0 py314h8169c2f_0 conda-forge
numba-cuda 0.30.4 py314h42812f9_0 conda-forge
rmm 26.08.00 cuda13_cp311_abi3_260805_42d059f1 rapidsai
librmm 26.08.00 cuda13_260805_42d059f1 rapidsai
cuda-version 13.3 hcbadf70_3 conda-forge
cuda-bindings 13.3.1 py314h42812f9_1 conda-forge
cuda-cudart 13.3.29 hecca717_0 conda-forge
cuda-nvrtc 13.3.33 hecca717_0 conda-forge
libcublas 13.6.0.2 h676940d_0 conda-forge
libcusolver 12.2.6.9 h676940d_0 conda-forge
libcusparse 12.8.2.51 hecca717_0 conda-forge
libcurand 10.4.3.29 h676940d_0 conda-forge

Additional context

The input consists of two identical triangular configurations separated by a large distance:

cluster 1: [0, 0], [1, 0], [0, 1]
cluster 2: [10, 10], [11, 10], [10, 11]

Each group contains exactly three samples, matching min_cluster_size=3. For every point, the neighborhood needed by min_samples=3 consists of the point itself and the two other members of its group.

The cuML documentation describes min_samples as:

The number of samples in a neighborhood for a point to be considered as a core point. This includes the point itself.

Scikit-learn documents the same inclusive behavior. Therefore, passing the same parameter values should not introduce the one-sample offset associated with implementations where min_samples excludes the point itself.

The labels themselves need not use the exact numeric identifiers shown by scikit-learn; any permutation representing two three-point clusters would be correct. The issue is that cuML returns only the noise label -1.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ? - Needs TriageNeed team to review and classify bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      AltStyle によって変換されたページ (->オリジナル) /