Re: Add low-memory special case for Euclidean single-linkage clustering

Julien Jerphanion <[email protected]> Wed, 05 Jul 2023 20:39:37 +0000
Newsgroups gmane.comp.python.scientific.devel
Message-ID <PLSzrUDL6XZ-BTQ9oVY7QPArQIU1aQ26PDA3qh5JtT2PH12jpFx90yjN3aLsYebId4Fpi-Ki5AV3IxUWg_AMML59MFh40Vrxxy5K2mDc7gQ=@jjerphan.xyz>
Hi Mathias,

Thank you for your proposal.

I think that \`sklearn.cluster.AgglomerativeClustering\`ยน implements what you propose.

This implementation also supports other dissimilarities such as the cosine dissimilarity and the Manhattan distance.

Best,
Julien.

1: https://scikit-learn.org/stable/modules/generated/sklearn.cluster.AgglomerativeClustering.html
\-------- Original Message --------
On Jul 5, 2023, 17:00, < [email protected]> wrote:

>
> Hi all Single-linkage clustering in scipy uses quadratic memory, even though it is relatively straightforward to implement using only linear memory. I'd like to propose adding a special case to use a linear-memory implementation for the specific case of single-linkage clustering with Euclidean distances, which would close GitHub issue scipy\#9031 ("Low memory version of single linkage clustering", July 2018). Specifically, I'd like to propose a "low-code" solution that doesn't involve implementing new complicated algorithms and data structures, but instead uses the existing public API of scipy, to minimize the risk of bugs and minimize future maintenance costs. I've implemented a proof of concept, and I'll volunteer to submit a PR if you'd like. scipy.cluster.hierarchy.linkage() computes hierarchical clustering with any distance metric and in any dimension of space and with multiple different definitions of distances between clusters. It is implemented by first computing the distance matrix with pdist() and then working with that, and this distance matrix is the reason that the current implementation uses quadratic memory. For single-linkage clustering, you don't need the full distance matrix, and scipy actually has all the parts to compute Euclidean single-linkage clustering with quite few lines of Python code, as follows: 1. Compute the Delaunay triangulation of the input points 2. Compute the MST (Minimum Spanning Tree) on the triangulation's edges 3. Convert the MST to a single-linkage hierarchical clustering Step 1 and 2 are implemented in scipy already; step 3 can be done in near-linear time using Union-Find (about 20 lines of code). Here's my proof of concept: https://github.com/Mortal/singlelinkage I would call this approach a "low-code" solution to scipy\#9031, as it doesn't need to involve new Cython (or C++ or ...) code. You could probably combine step 2 and 3 and implement it in Cython for some extra speed, but I don't think it's worth it. It would be nice to support other metrics besides the Euclidean, but that would require replacing step 1 with some other approach that leads to a linear-size distance graph that is a guaranteed superset of the MST, and I'm not sure what that looks like for arbitrary metrics. Would scipy welcome a low-code special case for hierarchical clustering using single linkage and Euclidean distances, to solve scipy\#9031? Cheers, Mathias \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_ SciPy-Dev mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3/lists/scipy-dev.python.org/ Member address: [email protected]

_______________________________________________
SciPy-Dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/scipy-dev.python.org/
Member address: [email protected]
publickey - EmailAddress([email protected]) - 0xDEDBF4EA.asc (application/pgp-keys, 3.1 KB)
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GopenPGP 2.7.1
Comment: https://gopenpgp.org

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
Dg==
=/cO6
-----END PGP PUBLIC KEY BLOCK-----
signature.asc (application/pgp-signature, 855 B)
-----BEGIN PGP SIGNATURE-----
Version: ProtonMail

wsFzBAEBCAAnBQJkpdUHCZBWtpCpfC41uBYhBN7b9Or9ieiZmPAnSVa2kKl8
LjW4AACSkg//XNYMQUQlzrexMQqs0HQTjikE2/2On1jbTSS/sfOdjbGaKHp0
UAgbaRQ0YHQc9mKLguWmV3MNVfPGnWnHSLYfXgbdA+kib94/oIiCJi8Y/3e4
TGhISdZhjcaT3RM2M3xh1Ah7Za+WCUhfT9H7RYBWOWpgpPv7CQjniPQvK3mD
+29n6kNcEWl5bF6iXmEY8sdSGuORtH8oup06s1b0gQVCiyyz9mJvFtt3L6y9
O45++w6xkteoE9E+rC1DsZh/mFUWTviALkotjiPfGb2LiQc5/KXmbaEhW8DX
PS/Vmc0efbgY7+gwOBGf+wucmx2uWTV+8m3kyRU6yiErXx5IKEWWc1Y/GPVJ
Rzxy3tWyCKKNh+X4sZbG58zexBkllKrCMJ33oNX4cC4nTv1U1fTxGww0XRbn
qea6hqBrxFJBBEy4r3oM/+lKDE2ENpotVkub+T30gRHZFIz6WyyZLIf1c0mT
zXlUihmHlZOoHJ54G2craDKRH8oGr3Oc/VmdP7OZZufNaONRCnISHw9/dHw+
FbJ0hoLhhRHomgnkplWHDK5vGLKaJoGjd1ZuuQLTFJO+6FllbIfv/E+7+lrM
aq8yP0wzOqdK37Z3qRGWdqn3kFpkGfMnjQtUhW8SRqYnkvG2ltIVB7zpEN9Y
r2BWbhhDOfsPIOIY4ev8onBo6ziqNytos8Y=
=1tDx
-----END PGP SIGNATURE-----