FEA Bisecting K-Means - #20031
Conversation
|
As @TomDLT suggested here: #14214 (comment) could you please add a motivation / documentation as why this is a good addition? |
|
@adrinjalali to be honest I treated it as improvement of K-means basing on those documents |
|
@scikit-learn/core-devs we need a decision on whether to include this algorithm or not. To me it clearly passes the inclusion criteria. |
| ----- | ||
| That algorithm will not work if n_cluster is smaller than 2. | ||
|
|
||
| Also it might be inefficient when n_cluster is equal to 2 |
There was a problem hiding this comment.
If there is a good reference for this algorithm, here might be a good place to add it.
There was a problem hiding this comment.
FYI @GaelVaroquaux we're moving towards having the references in the user guide (this PR will need a user guide entry BTW) instead of the docstrings: when there are 5 references in a docstring it's impossible to know which one referes to which part of the algorithm. When the references are in the UG, we can clearly link each section to its relevant reference / paper. See e.g. how it's done for the SGD user guide: https://scikit-learn.org/stable/modules/sgd.html
There was a problem hiding this comment.
Well that's a pity. It's really useful to look at a docstring and know exactly which algorithm it implements (there are so many grey areas).
My comment was actually driven by those grey areas. I would genuinely like to know specifically which algorithm the code is implementing as I am reading the code.
There was a problem hiding this comment.
Docstrings often have 5+ references with zero context. Some of these references are about the algoirthm in general, and some can be about a single detail / parameter / solver. Unless you already know what you're looking for, finding which paper you should read is hard. Having the refs in the UG with proper links helps: see #16296 in prticular
properly link to the reference section throughout the text
+1 After investigating which specific algorithm this is (it comes with various names), I agree that it should be included. It is well cited (but that does not suffice to make me enthusiastic). More importantly, it fills in nicely a niche for which we have no tool in scikit-learn. Indeed, experience shows that such approach is preferable to agglomerative clustering if the number of clusters is small compared to the number of data points (that's a comment that could be added to the docs to help users decide which algorithm investigate). |
Co-authored-by: Gael Varoquaux <[email protected]>
Co-authored-by: Gael Varoquaux <[email protected]>
Co-authored-by: Gael Varoquaux <[email protected]>
Co-authored-by: Gael Varoquaux <[email protected]>
Co-authored-by: Gael Varoquaux <[email protected]>
|
@GaelVaroquaux, @NicolasHug - I would be glad if you could tell me what can I do about that error |
Have you verified that with a short test? If |
|
@NicolasHug Sparse Data should work now ( maybe should be done in more efficient way, but for now I don't have idea how). Would you mind to take a look at error with |
|
@jeremiedbb Thanks for helping with that. Seems good to go |
jeremiedbb
left a comment
There was a problem hiding this comment.
Thanks a lot @michalkrawczyk ! LGTM after these last comments are addressed.
@TomDLT there were many changes since your approval. Does it still stand ? You might want to take another look.
TomDLT
left a comment
There was a problem hiding this comment.
Great!
I like the new clean tree implementation.
ogrisel
left a comment
There was a problem hiding this comment.
Here is some feedback. I would have liked more editorial guidance in the user guide for the pro and cons of bisecting k-means vs k-means or vs agglomerative clustering. For the latter, the computation advantage is obvious when one wants to retrieve a small number of clusters. But then we currently have no way to retrieve the hierarchical information between the clusters.
However I am not sure for which kind of data / number of clusters bisecting k-means would be more favorable than traditional k-means. Any idea?
| km64 = BisectingKMeans(n_clusters=3, random_state=0).fit(X) | ||
| km32 = BisectingKMeans(n_clusters=3, random_state=0).fit(X.astype(np.float32)) | ||
|
|
||
| assert_allclose(km32.cluster_centers_, km64.cluster_centers_) |
There was a problem hiding this comment.
Assuming this is not already tested elsewhere.
| assert_allclose(km32.cluster_centers_, km64.cluster_centers_) | |
| assert_allclose(km32.cluster_centers_, km64.cluster_centers_) | |
| assert km32.cluster_centers_.dtype == np.float32 | |
| assert km64.cluster_centers_.dtype == np.float64 |
There was a problem hiding this comment.
This is tested in test_dtype_preserved
| Coordinates of cluster centers. If the algorithm stops before fully | ||
| converging (see ``tol`` and ``max_iter``), these will not be | ||
| consistent with ``labels_``. | ||
|
|
There was a problem hiding this comment.
It would be great to also record another attribute that would encode the cluster hierarchy.
Not sure how to do that but it would be nice to have a way to plot a truncated dendrogram as we do for AgglomerativeClustering in this example for instance:
We could even extend this example to make it "notebook-style" with two subsection, the first one with the existing content and the second one to show how to build a truncated dendrogram for bisecting k-means.
There was a problem hiding this comment.
The hierarchical structure is encoded in the _bisecting_tree attribute which is private for now. I wasn't sure if we should make it public or not because we might not want to expose such implementation details. Maybe we can add a method that returns the appropriate structure to pass to the scipy dendogram plot function ?
There was a problem hiding this comment.
Maybe we can add a method that returns the appropriate structure to pass to the scipy dendogram plot function?
Excellent suggestion. This should be done similarly for AgglomerativeClustering and the example should be simplified accordingly. Let's do that in a follow-up PR instead of making this one more complex.
|
@ogrisel I added some hints in the user guide about the differences with regular KMeans, regarding efficiency and quality of the results. What do you think ? |
|
As discussed irl with @glemaitre, let's merge to not delay the release process. We can still push more documentation if needed before the release is effective. |
|
Thanks @michalkrawczyk ! 🚀 |
|
Nice |
|
Thanks to @jeremiedbb, @TomDLT, @jjerphan and others for helping me out with that! |
|
Thank you for this contribution, @michalkrawczyk. |
This is already a nice contribution to scikit-learn. |
|
Hurray!! That's a big one.
|
|
Thank you very much, @michalkrawczyk and all the others who helped on this merge! |
Co-authored-by: Gael Varoquaux <[email protected]> Co-authored-by: Tom Dupré la Tour <[email protected]> Co-authored-by: Julien Jerphanion <[email protected]> Co-authored-by: Jérémie du Boisberranger <[email protected]>
Reference Issues/PRs
Propositon to resolve #14214 issue (Since I don't see any other pull request at it is almost 2 years old)
What does this implement/fix? Explain your changes.
Implements Bisecting K-Means Algorithms