SCPP · Soft Clustering Python Package
42 soft, fuzzy, possibilistic, evidential, graph, document and deep clustering algorithms — behind one estimator protocol.
Hard clustering forces every point into exactly one group. Real data rarely cooperates: a document belongs to several topics, a node joins several communities, a cell sits between two types. Soft clustering assigns degrees of membership instead — and the methods that do it are scattered across decades of papers, each with its own interface, notation and output convention.
SCPP collects 42 of them into one library, behind one protocol, with a benchmarking suite that lets you compare them on equal terms.
✨ Highlights
| 🧩 One protocol, 42 algorithms | Every estimator exposes memberships_, labels_, centers_ and n_clusters after fit, whatever the method consumes — a feature matrix, a graph, raw documents, or an ensemble of partitions. |
| 🔬 Checked, not asserted | A conformance suite fits all 42 estimators on every commit and verifies the contract: membership shape, the partition constraint where the formulation imposes one, out-of-sample behaviour, sklearn.clone round-tripping, and reproducibility under a fixed random_state. Exclusions are a hard CI failure. |
| 📊 Benchmarking included | Runtime, memory, scalability and clustering quality, over 20 datasets and 12 validity metrics — shipped inside the package, and actually run: see benchmarks/ for the cross-family comparison and the agreement checks against scikit-fuzzy and scikit-learn. |
| 🪶 Light by default | A base install is numpy, scipy, scikit-learn and typeguard — enough to fit 38 of the 42 estimators. PyTorch and pandas live behind extras you opt into. |
| 🏷️ Typed | Ships py.typed; hints are checked at runtime by typeguard and visible to your type checker. |
📦 Installation
pip install soft-clustering
Optional extras, separated by what they are needed for:
| Extra | Install | Provides | Needed for |
|---|---|---|---|
| (base) | pip install soft-clustering |
numpy, scipy, scikit-learn, typeguard | Fitting any of the 38 non-deep estimators |
deep |
pip install "soft-clustering[deep]" |
torch, torch_geometric | CDCGS, DMoN, NOCD, RDFKC |
bench |
pip install "soft-clustering[bench]" |
pandas, psutil, tabulate | Running soft_clustering.benchmarking |
baselines |
pip install "soft-clustering[baselines]" |
scikit-fuzzy | Agreement checks against third-party implementations |
docs |
pip install "soft-clustering[docs]" |
sphinx, myst-parser | Building the documentation |
dev |
pip install -e ".[dev,deep]" |
pytest, pytest-cov, matplotlib | Developing and testing |
Requires Python 3.10 or newer.
🚀 Quick start
import numpy as np
from soft_clustering import FCM
rng = np.random.default_rng(0)
X = np.vstack([rng.normal([0, 0], 0.4, (100, 2)),
rng.normal([4, 4], 0.4, (100, 2))])
model = FCM(n_clusters=2, random_state=0).fit(X)
model.memberships_ # (200, 2) degrees of membership, rows sum to 1
model.labels_ # (200,) arg-max hard assignment
model.centers_ # (2, 2) cluster prototypes
model.n_clusters # 2 the partition actually produced
>>> np.round(model.memberships_[:3], 3)
[[0. 1. ]
[0.003 0.997]
[0.001 0.999]]
Every estimator follows the same shape, so swapping the method is a one-word change:
from soft_clustering import ECM, GK, PCM, RoughKMeans
for cls in (GK, PCM, ECM, RoughKMeans):
model = cls(n_clusters=2).fit(X)
print(f"{cls.__name__:20s} {model.memberships_.shape}")
n_clusters is accepted by every estimator regardless of the spelling used in
the original paper (c, k, n_topics, n_communities, …), and estimators
that discover the cluster count themselves report it in n_clusters after
fitting.
🧩 Algorithm catalogue
Grouped by what the algorithm consumes. ⚡ marks estimators requiring the
deep extra.
Feature matrix — 26 estimators
FCM |
Fuzzy C-Means | The canonical membership-based method |
PCM |
Possibilistic C-Means | Typicalities; rows need not sum to 1 |
PFCM |
Possibilistic Fuzzy C-Means | Combines memberships and typicalities |
GK |
Gustafson–Kessel | Adaptive per-cluster covariance |
ECM |
Evidential C-Means | Belief masses over sets of clusters |
KFCM |
Kernelized Fuzzy C-Means | Kernel-space distances |
SKFCM |
Spatially-Constrained Kernelized FCM | Adds an image neighbourhood term |
KFCCL |
Kernel-based Fuzzy Competitive Learning | Competitive-learning update |
CAFCM |
Collaborative Annealing FCM | Deterministic annealing |
CAFHFCM |
Centroid Auto-Fused Hierarchical FCM | Fuses centroids hierarchically |
ENTROPYFCM |
Entropy c-Means | Entropy regularisation in place of the fuzzifier |
AFCM |
AFCM with full graph embedding | Graph-regularised memberships |
AFCMSimple |
AFCM without graph embedding | The unregularised variant |
AFCMAdaptive |
Adaptive FCM for image segmentation | Operates on a single image |
FCC |
Fuzzy Color Clustering | Fuzzy colour spheres in CIELAB space |
RPFKM |
Robust Projected Fuzzy K-Means | Joint dimensionality reduction for noisy, high-dimensional data |
SFCMEP |
Semi-supervised Fuzzy Clustering with Membership Prior | Consumes a partially labelled target vector |
FeMIFuzzy |
Federated Multiple Imputation Fuzzy Clustering | Consumes per-client matrices |
RoughKMeans |
Rough K-Means | Lower and upper approximations |
SCM |
Subtractive Clustering Method | Determines the cluster count itself |
SoftDBSCANGM |
Soft DBSCAN with Gaussian mixtures | Density-based, discovers k |
SoftKSC |
Soft Kernel Spectral Clustering | Semi-supervised; two non-parallel hyperplanes |
GMM |
Gaussian Mixture (EM) | Responsibilities as memberships |
BGMM |
Beta-Gaussian Mixture Model | Two aligned views |
MBMM |
Multivariate Beta Mixture Model | For data on the unit interval |
RDFKC ⚡ |
Robust Deep Fuzzy K-Means | Image tensors |
Graphs and networks — 6 estimators
BIGCLAM |
Cluster Affiliation Model for Big Networks | Overlapping communities at scale |
BayesianNMF |
Bayesian NMF for overlapping communities | Automatic relevance determination |
MMSB ⚡ |
Mixed Membership Stochastic Blockmodel | Generative blockmodel |
NOCD ⚡ |
Neural Overlapping Community Detection | GNN + Bernoulli–Poisson |
DMoN ⚡ |
Deep Modularity Networks | Modularity-optimising pooling |
CDCGS ⚡ |
Community Detection via Gumbel Softmax | Differentiable assignment |
Documents and text — 5 estimators
LDA |
Latent Dirichlet Allocation | Topic–word and document–topic factors |
PLSI |
Probabilistic Latent Semantic Indexing | Likelihood-based topic model |
SISC |
Similarity-Based Soft Clustering | Discovers the cluster count |
KMART |
Modified Fuzzy ART for documents | Adaptive resonance |
WBSC |
Word-Based Soft Clustering | Word-driven soft assignment |
Ensembles and consensus — 3 estimators
SCSPA |
Soft CSPA | Similarity-based consensus over soft partitions |
SHBGF |
Soft HBGF | Bipartite graph consensus over concatenated memberships |
SMCLA |
Soft MCLA | Groups clusters into meta-clusters |
Each algorithm has its own documentation page with parameters, usage and the primary reference: full API reference →
📊 Benchmarking
The benchmarking suite ships inside the package, so it is available straight after installation — no cloning required.
pip install "soft-clustering[bench]"
from soft_clustering import FCM, GK, PCM
from soft_clustering.benchmarking import (
ClusteringBenchmark,
ClusteringQualityBenchmark,
RuntimeBenchmark,
get_dataset,
)
X, y = get_dataset("iris")
results = ClusteringBenchmark(
models=[
FCM(n_clusters=3, random_state=0),
GK(n_clusters=3, random_state=0),
PCM(n_clusters=3, random_state=0),
],
benchmarks=[RuntimeBenchmark(n_repeats=3), ClusteringQualityBenchmark()],
).run(X, y)
model fit_time_sec ari nmi partition_coefficient
FuzzyCMeans 0.001 0.729 0.750 0.783
GustafsonKessel 0.009 0.743 0.758 0.727
PossibilisticCMeans 0.003 0.531 0.696 0.256
| Backend | Measures |
|---|---|
⏱️ RuntimeBenchmark |
Fit and predict time, with repeats and standard deviation |
💾 MemoryBenchmark |
Resident set size sampled during the fit, so transient allocations are caught |
📈 ScalabilityBenchmark |
Runtime and memory as the sample count grows |
🎯 ClusteringQualityBenchmark |
Silhouette, Calinski–Harabasz, Davies–Bouldin; ARI and NMI when labels are given; partition coefficient and entropy |
Also included: 20 datasets (bundled, synthetic and OpenML) via
get_dataset, and 12 validity metrics usable on their own — partition
coefficient, modified partition coefficient, partition entropy, Xie–Beni,
fuzzy compactness and separation, plus the standard hard-clustering indices.
📚 Documentation
- Documentation site — API reference, one page per algorithm, benchmarking guide
example/— a runnable script for every estimatortests/— including the shared protocol conformance suite
🧪 Development
git clone https://github.com/soft-clustering/soft-clustering.git
cd soft-clustering
pip install -e ".[dev,deep]"
pytest # tests
pytest --cov=soft_clustering --cov-report=term-missing # with coverage
ruff check soft_clustering tests example tools # lint
black --check soft_clustering tests example tools # formatting
sphinx-build -b html -W docs/source docs/_build/html # docs, warnings are errors
See CONTRIBUTING.md for the estimator protocol and what adding an algorithm involves.
📖 Citation
This package accompanies a paper submitted to the JMLR MLOSS track.
- Paper: arXiv:2607.19620
@misc{rezaee2026scppunifiedpythonlibrary,
title={SCPP: A Unified Python Library for Soft Clustering},
author={Kiyan Rezaee and Morteza Ziabakhsh and Artin Bahrampour and
Seyed Mohammad Ghoreishi and Asal Khaje and Ali Sajedifar and
Manny Chalak and Ava Zerafatangiz and Sadegh Eskandari},
year={2026},
eprint={2607.19620},
archivePrefix={arXiv},
primaryClass={cs.LG},
url={https://arxiv.org/abs/2607.19620},
}
GitHub's Cite this repository button reads
CITATION.cff and will produce this for you.
🤝 Contributing
Contributions, bug reports and algorithm proposals are all welcome.
- Contributing guidelines
- Code of conduct
- Security policy — please report vulnerabilities privately
- Open an issue
⚖️ License
Distributed under the terms of the MIT license.
Metadata
Release files for soft-clustering 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| soft_clustering-0.2.0.tar.gz | 9.6 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| soft_clustering-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 9.7 MB
Release files / soft_clustering-0.2.0.tar.gz
| Download URL | soft_clustering-0.2.0.tar.gz |
|---|---|
| Size | 9.6 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ad89d0ec937d4c923ff2165e5f4d9c51cb8ba9eaa5e59bfbddc0ad744368c8df
|
|
BLAKE2b-256 checksum How to use checksums |
9a4312ac83b9b15b22ba2575d637b115f032ac248625532735ebf7deba3abcf4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|
Release files / soft_clustering-0.2.0-py3-none-any.whl
| Download URL | soft_clustering-0.2.0-py3-none-any.whl |
|---|---|
| Size | 138.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
015b437fbc2b2caa455a1baeacec6472dff6c09086b4ef16993df23d200d1a6f
|
|
BLAKE2b-256 checksum How to use checksums |
508d50013584e23cc14baa7399e7f7e48ba54767544ee5d74f1add81cfb8a3f1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.6
|