SHiP

Python bindings for the SHiP (Similarity-Hierarchical-Partitioning) clustering framework.

SHiP is a flexible and modular clustering library that constructs and analyzes similarity-based hierarchical structures for data clustering. It is the official implementation of the methods introduced in the paper Ultrametric Cluster Hierarchies: I Want ‘em All!

Overview
The SHiP framework operates in three main stages:
1. Similarity Tree Construction
Build a tree that encodes proximity relationships between data points.
2. Hierarchy Construction
Derive clustering hierarchies (e.g., \(k\)-means, \(k\)-median) from the tree.
3. Partitioning
Select and apply a partitioning method (e.g., Elbow, fixed-K) to extract flat clusters.

SHiP allows users to mix and match components (trees, hierarchies, partitioning objectives) for fully customized clustering workflows.

Example

from SHiP import SHiP

ship = SHiP(data=data_points, treeType="DCTree")
labels = ship.fit_predict(hierarchy=2, partitioningMethod="Elbow")
Implementation
The core of the project is implemented in C++, with Python bindings provided via pybind11.

Classes

SHiP

class SHiP.SHiP

SHiP clustering class.

Constructs a SHiP object from input data.

__init__(self: SHiP.SHiP, data: object, treeType: object = <UltrametricTreeType.DCTree: 1>, hierarchy: int = 1, partitioningMethod: object = <PartitioningMethod.MedianOfElbows: 10>, config: dict = {}) None

Constructs a SHiP clustering object.

Parameters:
  • data (list[list[float]] or numpy.ndarray) – The dataset to be clustered, either as a nested list of floats or a 2D NumPy array (shape: (n_samples, n_features)).

  • treeType (Union[UltrametricTreeType, str], optional) – The ultrametric tree type used to construct the hierarchical structure. Can be specified as an enum member (e.g., UltrametricTreeType.DCTree) or as a string (e.g., "DCTree"). Defaults to DCTree.

  • hierarchy (int, optional) – Select hierarchy used when transforming the similarity structure. Controls how distances are scaled. (Distances to the center are taken to the power of hierarchy.) Default is 2.

  • partitioningMethod (Union[PartitioningMethod, str], optional) – Partitioning strategy to extract flat clusters from the hierarchy. Can be given as an enum (e.g., PartitioningMethod.Elbow) or as a string (e.g., "Elbow"). Defaults to Elbow.

  • config (dict[str, str], optional) – Additional configuration options, passed as a dictionary of string keys and values. Can be used to tweak internal parameters.

Notes

This constructor allows users to initialize SHiP in a highly flexible way. All inputs are validated and cast internally to their proper representations.

fit(self: SHiP.SHiP, hierarchy: object = None, partitioningMethod: object = None, config: dict = {}) None

Apply clustering by extracting a partition from the computed hierarchy.

This method applies a specified partitioning method (or the default) to produce a flat clustering from the internal ultrametric tree and associated hierarchy.

Parameters:
  • hierarchy (int, optional) – Which hierarchy (power exponent) to use for tree construction. If not provided, the value from initialization is used.

  • partitioningMethod (PartitioningMethod or str, optional) – The strategy used to extract a flat partition from the hierarchy. Can be a member of the PartitioningMethod enum or a corresponding string. If None, the default is used.

  • config (dict[str, str], optional) – Configuration dictionary for advanced or backend-specific parameters.

Returns:

Cluster labels assigned to each data point.

Return type:

list[int]

Raises:

ValueError – If the partitioning method is of an invalid type.

Notes

This function assumes the SHiP instance has already built a tree and hierarchy internally.

fit_predict(self: SHiP.SHiP, hierarchy: object = None, partitioningMethod: object = None, config: dict = {}) list[int]

Fit the SHiP model and return cluster labels.

This method performs all necessary steps to build the similarity tree, generate a clustering hierarchy, and extract a flat clustering using the specified partitioning method.

Parameters:
  • hierarchy (int, optional) – Which hierarchy (power exponent) to use for tree construction. If not provided, uses the default or value passed during initialization.

  • partitioningMethod (PartitioningMethod or str, optional) – Partitioning strategy used to flatten the hierarchy into clusters. Accepts either a PartitioningMethod enum value or a corresponding string. If not provided, the default is used.

  • config (dict[str, str], optional) – Dictionary of advanced or backend configuration options.

Returns:

A list of cluster labels corresponding to the input data points.

Return type:

list[int]

Raises:

ValueError – If an invalid partitioningMethod is provided.

Notes

This is a convenience method equivalent to calling .fit(…) followed by .labels_.

get_tree(self: SHiP.SHiP, hierarchy: int = 0) Tree

Retrieve the similarity tree constructed of a given hierarchy.

Parameters:

hierarchy (int, optional) – Get the ultrametric tree of hierarchy. Default is the base tree (hierarchy=0).

Returns:

The ultrametric tree representation (internal C++ structure or Python-wrapped equivalent) used in the SHiP clustering hierarchy.

Return type:

Tree

Notes

This method is useful for inspecting or debugging the tree structure before or after clustering. Depending on the backend, it may return a tree object or a data structure that represents the tree in a format suitable for downstream analysis.

property config

Additional configuration options.

Dictionary of string-based key-value pairs.

Example:

from SHiP import SHiP

ship = SHiP(data=data_points, treeType="DCTree", config={"min_points": 5})
labels = ship.fit_predict(hierarchy=2, partitioningMethod="K", config={"k": 10})
property hierarchy

Use the tree of this z-hierarchy for partitioning.

Defines the z-hierarchy to extract or work with.

property labels_

Cluster labels assigned to each input point.

Available after calling .fit() or .fit_predict().

property partitioningMethod

Use this strategy to extract clusters from the hierarchy.

Can be set using a PartitioningMethod enum or its string representation.

property partitioning_runtime

Time spent during the partitioning phase (in microseconds).

property treeType

The ultrametric tree type used in clustering.

Specifies the ultrametric tree type used to construct the hierarchy (e.g., DCTree, CoverTree, etc.).

property tree_construction_runtime

Dictionary containing the time spent for constructing the tree (key=0) and the z-hierarchies (key=z) (in microseconds).


Tree

class SHiP.Tree
__init__(*args, **kwargs)
distance_matrix(self: SHiP.Tree) numpy.ndarray[numpy.float64]

Generate the ultrametric distance matrix from the tree.

The matrix is symmetric and encodes the pairwise distances between all data points based on their lowest common ancestor in the hierarchy.

Returns:

A 2D distance matrix.

Return type:

np.array

Notes

This function does not care about the exact structure of the tree, hence for faster speed one can change the tiebreaker_method to “random”:

from SHiP import SHiP

ship = SHiP(data=data_points, treeType="DCTree", config={"tiebreaker_method": "random"})
dists = ship.get_tree().distance_matrix()

Note that using the get_tree() method without specifying the hierarchy will always return the base tree (hierarchy=0).

get_elbow_k(self: SHiP.Tree, triangle: bool = True) int

Compute the optimal number of clusters k using the Elbow method.

Parameters:

triangle (bool, optional) – Whether to use the new triangle Elbow method. Defaults to True.

Returns:

The estimated optimal number of clusters.

Return type:

int

to_json(self: SHiP.Tree, fast_index: bool = False) str

Serialize the tree structure to a JSON string.

Parameters:

fast_index (bool, optional) – Whether to include additional indexing information for faster leave node extracting. Defaults to False.

Returns:

The JSON-encoded representation of the tree.

Return type:

str

property config

Configuration dictionary passed during tree creation.

Contains algorithm-specific parameters and settings.

property cost_decreases

Cost decreases between successive merges.

Encodes the cost decreases at each merging step (can be lower than n).

property costs

List of merge costs at each step in the tree.

Encodes the cost at which each merge occurred.

property hierarchy

Used hierarchy of the tree.

Which z was used to build the tree (e.g., z=0 (\(k\)-center), z=1 (\(k\)-median), z=2 (\(k\)-means)).

property index_order

Ordering of the leave nodes according to the tree structure.

Maps original data point indices to their position in the tree (left to right).

property root

Root node of the tree.

This is the entry point to traverse the full hierarchical structure.

property sorted_nodes

List of tree nodes sorted by merge cost.

Useful for analyzing the tree structure and extracting intermediate clusters.

property tree_type

Used ultrametric tree type.

Indicates the ultrametric tree type used to build the tree (e.g., DCTree, KDTree).


Node

class SHiP.Node
__init__(*args, **kwargs)
to_json(self: SHiP.Node, fast_index: bool = False) str

Serialize the node to a JSON-compatible structure.

Parameters:

fast_index (bool, optional): Whether to include additional indexing information for faster leave node extracting. Defaults to False.

Returns:

The JSON-encoded representation of the tree.

Return type:

str

property children

List of child nodes.

For leaf nodes, this list is empty. For internal nodes, it contains two or more children.

property cost

Cost (distance or merging cost) at this node.

Represents the dissimilarity between the merged clusters.

property high

End index in the index_order array.

Used to efficiently extract all leave nodes of this node.

property id

Unique identifier of the node.

Typically corresponds to the merge order or original data point index.

property level

Depth of the node in the tree.

The root has the lowest level 0.

property low

Start index in the index_order array.

Used to efficiently extract all leave nodes of this node.

property parent

Parent node in the tree hierarchy.

Points to the node resulting from merging this node with a sibling.

property size

Number of original data points (leave nodes) in the subtree rooted at this node.