HDBSCAN
UDTF: cuml_hdbscan
Official cuML reference: Python API
cuML HDBSCAN fits density-based clusters and returns query-local labels and membership probabilities.
Quickstart
Register the relations referenced by the parenthesized SELECT clauses below. For metadata validation, the descriptor names input_vectors.
SELECT id, cluster_id, probability
FROM cuml_hdbscan(
input => (SELECT id, d0, d1 FROM t),
min_cluster_size => 5
)
ORDER BY row_ordinal;
Inputs
Each relation argument is a parenthesized SELECT subquery. Metadata validation resolves a registered table or view for the same role without scanning its rows. See ML Inputs for the ID, Float32 feature, null, finite-value, and runtime-dimension contract.
Vector element types
Arguments and options
Scalar SQL arguments
SQL value argument schemas
Vector binding shapes
Each relation subquery projects a non-null id and either non-null Float32 feature columns in dimension order or one non-null vector list column of non-null Float32 values. For classification, training also projects non-null Int32 label; regression requires non-null finite Float32 label. The predict relation omits it.
The list-column shape excludes other feature columns. See ML Inputs for the allowed list containers and runtime checks.
Output
Concrete schemas are call-specific. Run gpu_validate_call against registered relations to inspect the output schema after the actual ID types and literal options are validated.
Examples
- EMBER2024
- MerRec marketplace
This example uses the EMBER2024 demo dataset.
Which missed Win32 files should an analyst group for batch review?
A security analyst needs to organize 3,225 Win32 samples that initially
escaped antivirus detection. This query projects each sample's
512 byte and byte-entropy histogram features (f7 through f518) to 16 PCA
components, then fits HDBSCAN with min_cluster_size = 30 and min_samples = 10. The family labels do not enter either fit; SQL joins them after clustering
to summarize the resulting groups.
The capture contains seven clusters and 508 rows assigned to noise (cluster_id = -1). HDBSCAN keeps those noise rows in the output. Cluster IDs are local to
this fit. The 930-file cluster contains 736 snackarcin files, 193
opensupdater files, and one file without a family label. The 1,005-file
cluster has 734 family-labeled files, 547 of them malicord. These family
counts describe the families present within each fitted group.
All challenge files are positive examples, so this cohort cannot measure a
false-positive rate.
The SQL returns one row per cluster. example_sha256 is the minimum SHA-256
within that cluster's most common labeled family. It provides an audit link;
the query does not compute a representative sample. The complete capture
preserves the full SHA values.
Download the JSON capture, including the SQL, all eight result rows, query ID, and execution conditions.
WITH reduced AS (
SELECT id, pc_0, pc_1, pc_2, pc_3, pc_4, pc_5, pc_6, pc_7,
pc_8, pc_9, pc_10, pc_11, pc_12, pc_13, pc_14, pc_15
FROM cuvs_pca(
input => (
SELECT v.id, v.histogram AS vector
FROM ember_research_vectors_challenge v
JOIN ember_metadata_challenge m ON m.id = v.id
WHERE m.file_type = 'Win32'
ORDER BY v.id
),
n_components => 16
)
), assignments AS (
SELECT id, cluster_id
FROM cuml_hdbscan(
input => (SELECT * FROM reduced ORDER BY id),
min_cluster_size => 30,
min_samples => 10
)
), family_counts AS (
SELECT a.cluster_id, m.family, COUNT(*) AS files,
MIN(m.sha256) AS example_sha256
FROM assignments a
JOIN ember_metadata_challenge m ON m.id = a.id
GROUP BY a.cluster_id, m.family
), ranked AS (
SELECT *,
SUM(files) OVER (PARTITION BY cluster_id) AS cluster_files,
SUM(CASE WHEN family <> '' THEN files ELSE 0 END)
OVER (PARTITION BY cluster_id) AS family_labeled_files,
ROW_NUMBER() OVER (
PARTITION BY cluster_id
ORDER BY CASE WHEN family = '' THEN 1 ELSE 0 END,
files DESC, family
) AS family_rank
FROM family_counts
)
SELECT cluster_id, cluster_files, family_labeled_files,
family AS most_common_family, files AS most_common_family_files,
example_sha256
FROM ranked
WHERE family_rank = 1
ORDER BY cluster_files DESC, cluster_id;
The query orders the input by id, which fixes the input sequence represented
by this capture. It does not guarantee identical fitted memberships or label
numbers across hardware and software environments. The observed execution
used a dedicated EMBER server and had partial_native disposition: PCA and
HDBSCAN ran on the GPU; the statement also included CPU window processing.
The saved runtime observation identifies this execution path.
This example uses the MerRec dataset and graph capture page and its ordered category-share definition.
Which captured audiences have concentrated preferences, and which have mixed profiles?
The map joins saved UMAP coordinates, HDBSCAN assignments, and view counts by
user ID. Its question is descriptive: whether category preferences form a few
concentrated groups among users with at least 20 item_view events in this
October capture. The category features use view events before
2023-10-21, expressed in SQL as event_time < TIMESTAMP '2023-10-21'.
Repeated views of one item count as separate events. The five assigned groups
contain 603 users. HDBSCAN leaves 1,316 of the 1,919 rows as noise, and those
rows remain available in the map filter.
UMAP used the 17 square-root-transformed category shares to fit its two display dimensions. HDBSCAN used the same 17 square-root-transformed shares in the original 17-dimensional space. Its labels are local to this fit. The 15-neighbor trustworthiness score against the original 17-dimensional input is 0.96464; that value describes this embedding and is not a business outcome.
HDBSCAN membership strength: 0.000
Top categories by share of view events
The average squared feature shares within the five assigned groups emphasize
Electronics, Toys & Collectibles, Kids, Women, and Men. Squaring restores each
category's share of a user's item_view events. The rates below are cluster
means from the vector validation capture.
Reviewing group sizes and leading categories can guide which category-specific campaign variants to test, while conversion outcomes remain unmeasured.
Point distances on the map have no calibrated conversion meaning. The
HDBSCAN probability field is cluster membership strength. These saved groups
describe one browsing capture; they do not establish marketing response or
uplift. Download the full point capture,
including all 1,919 users, category shares, source hashes, and query IDs.
The map's UMAP coordinates came from query
bf5b54b8-6b76-4ebd-af66-e0c8c6100544.
The assignments came from query
1daad9d5-6b74-41cc-8e27-9cad3fa8f78c.
Saved UMAP SQL
SELECT *
FROM cuml_umap(
input => (
SELECT
id,
COALESCE(women, CAST(0 AS REAL)) AS women,
COALESCE(toys, CAST(0 AS REAL)) AS toys,
COALESCE(kids, CAST(0 AS REAL)) AS kids,
COALESCE(men, CAST(0 AS REAL)) AS men,
COALESCE(home, CAST(0 AS REAL)) AS home,
COALESCE(electronics, CAST(0 AS REAL)) AS electronics,
COALESCE(beauty, CAST(0 AS REAL)) AS beauty,
COALESCE(vintage, CAST(0 AS REAL)) AS vintage,
COALESCE(books, CAST(0 AS REAL)) AS books,
COALESCE(sports, CAST(0 AS REAL)) AS sports,
COALESCE(other, CAST(0 AS REAL)) AS other,
COALESCE(handmade, CAST(0 AS REAL)) AS handmade,
COALESCE(garden, CAST(0 AS REAL)) AS garden,
COALESCE(arts, CAST(0 AS REAL)) AS arts,
COALESCE(pets, CAST(0 AS REAL)) AS pets,
COALESCE(office, CAST(0 AS REAL)) AS office,
COALESCE(tools, CAST(0 AS REAL)) AS tools
FROM mr_tastes
ORDER BY id
),
n_components => 2,
n_neighbors => 30,
min_dist => 0.1,
random_state => 42
)
ORDER BY id;
Saved HDBSCAN SQL
SELECT *
FROM cuml_hdbscan(
input => (
SELECT
id,
COALESCE(women, CAST(0 AS REAL)) AS women,
COALESCE(toys, CAST(0 AS REAL)) AS toys,
COALESCE(kids, CAST(0 AS REAL)) AS kids,
COALESCE(men, CAST(0 AS REAL)) AS men,
COALESCE(home, CAST(0 AS REAL)) AS home,
COALESCE(electronics, CAST(0 AS REAL)) AS electronics,
COALESCE(beauty, CAST(0 AS REAL)) AS beauty,
COALESCE(vintage, CAST(0 AS REAL)) AS vintage,
COALESCE(books, CAST(0 AS REAL)) AS books,
COALESCE(sports, CAST(0 AS REAL)) AS sports,
COALESCE(other, CAST(0 AS REAL)) AS other,
COALESCE(handmade, CAST(0 AS REAL)) AS handmade,
COALESCE(garden, CAST(0 AS REAL)) AS garden,
COALESCE(arts, CAST(0 AS REAL)) AS arts,
COALESCE(pets, CAST(0 AS REAL)) AS pets,
COALESCE(office, CAST(0 AS REAL)) AS office,
COALESCE(tools, CAST(0 AS REAL)) AS tools
FROM mr_tastes
ORDER BY id
),
min_cluster_size => 30,
min_samples => 10
)
ORDER BY id;
Limits
- Validation resolves named tables or views and reads schemas only; it does not execute relation scans or GPU work.
- Execution relation arguments require parenthesized subqueries; dry-run validation accepts registered named relations only.
- Only Float32 features are supported; L2SqrtExpanded distance and brute-force kNN are fixed.
- Empty input returns an empty result. Other inputs require min_samples < rows, min_cluster_size <= rows, and max_cluster_size <= rows; row-dependent conditions are checked at execution.
- Cluster ID -1 denotes noise. The fit and output are query-local.
To dry-run validate relation metadata, column types, and options without execution, see gpu_validate_call.