Uh oh!
There was an error while loading. Please reload this page.
[SPARK-18282][ML][PYSPARK] Add python clustering summaries for GMM and BKM - #15777
[SPARK-18282][ML][PYSPARK] Add python clustering summaries for GMM and BKM#15777sethah wants to merge 7 commits into
Conversation
There was a problem hiding this comment.
Before, this would throw a Py4JJavaError. I think it's slightly better to throw a RuntimeError here as is done in Scala.
There was a problem hiding this comment.
I think thats generally a good improvement, the Py4J errors are often confusing to end users.
There was a problem hiding this comment.
I like this change, we should always throw an exception easy to understand by users.
There was a problem hiding this comment.
We should test that hasSummary returns False when there is no summary available, and that summary throws an exception. The problem I'm having is that I'm not sure how to create this test case. The only way to get a model is by calling fit, which will produce a model with a summary. Calling model._call_java("setSummary", None) doesn't work either. Is there some way that I'm missing?
There was a problem hiding this comment.
It might make sense to update setSummary to treat null as empty (e.g. Option instead of Some)) for easy testing.
SparkQA
commented
Nov 5, 2016
Test build #68167 has finished for PR 15777 at commit
|
SparkQA
commented
Nov 5, 2016
Test build #68216 has finished for PR 15777 at commit
|
holdenk
commented
Nov 6, 2016
Thanks for working on this @sethah - more work towards increased parity is good :) |
sethah
commented
Nov 14, 2016
ping @yanboliang |
There was a problem hiding this comment.
per @holdenk's suggestion, I changed the setSummary to use Option.apply which treats null as None. This allows us to exercise the test case for hasSummary when summary == None. This was never tested in Scala either so I added unit tests for both Scala and Python.
There was a problem hiding this comment.
I'd more prefer to make the argument as Option[BisectingKMeansSummary] like:
private[clustering] def setSummary(summary: Option[BisectingKMeansSummary]): this.type = {
this.trainingSummary = summary
this
}
And test summary == None by:
model.setSummary(None)
assert(!model.hasSummary)
Since I think setSummary(null) and test whether it existing is very tricky. The type of summary is Option[BisectingKMeansSummary] and with None as default value, so setSummary(None) should make more sense for the scenario that the model does not have summary.
I saw the reason for make this change is that you want to call setSummary at Python side, and Python None would be converted to null in Scala. But I think this is private function, we don't need to run test across Scala and Python, since private function should not be called by users.
SparkQA
commented
Nov 14, 2016
Test build #68624 has finished for PR 15777 at commit
|
There was a problem hiding this comment.
I think we dont need to expose ClusteringSummary, for in the scala side ClusteringSummary is private in [clustering].
yanboliang
commented
Nov 15, 2016
@sethah I will take a look in a few days. Thanks. |
There was a problem hiding this comment.
I'd more prefer to make the argument as Option[BisectingKMeansSummary] like:
private[clustering] def setSummary(summary: Option[BisectingKMeansSummary]): this.type = {
this.trainingSummary = summary
this
}
And test summary == None by:
model.setSummary(None)
assert(!model.hasSummary)
Since I think setSummary(null) and test whether it existing is very tricky. The type of summary is Option[BisectingKMeansSummary] and with None as default value, so setSummary(None) should make more sense for the scenario that the model does not have summary.
I saw the reason for make this change is that you want to call setSummary at Python side, and Python None would be converted to null in Scala. But I think this is private function, we don't need to run test across Scala and Python, since private function should not be called by users.
There was a problem hiding this comment.
I like this change, we should always throw an exception easy to understand by users.
There was a problem hiding this comment.
Typo, should be BisectingKMeansSummary?
There was a problem hiding this comment.
Why we test this? Actually setSummary is private and it should not generate a model w/o summary in ordinary case. I think we should only test the public API for Python. Further more, if we want to test model w/o summary, we need to write a dummy Scala model w/o summary, and check hasSummary directly at Python side. I think if the Scala function is not public, we may not confirm Scala/Python compatibility, so testing is also not very make sense.
There was a problem hiding this comment.
This came out of a suggestion in the other PR to add KMeansSummary. Adding a hasSummary method implies that models can both have and not have summaries. How can we test that hasSummary works properly when we can only exercise one of its test cases?
Edit:hasSummary will return false if the model is saved and then loaded back since the summary is not saved with the model, so it doesn't always return true. We could test the hasSummary method by calling save/load but that seems expensive just to test a simple function.
There was a problem hiding this comment.
Yeah, after loading a saved model, the summary should be None and hasSummary return false. I think this is the correct test route, although with some extra cost. What about add hasSummary test at save/load doc test? Then it should not need extra cost.
There was a problem hiding this comment.
We can do it, though typically the doc tests are for things that we want to test that also illustrate functionality to the users. And @jkbradley seemed against adding it as a doc test here. I'll add it for now and we can revert it if we decide that's best.
There was a problem hiding this comment.
Yeah, I think it makes sense to add summary related doc tests for algorithms to illustrate the output of summary. So one more line to check hasSummary does not seam to have much impact. @jkbradley What's your opinion? Thanks.
There was a problem hiding this comment.
@yanboliang I switched it up. Let me know what you think
SparkQA
commented
Nov 16, 2016
Test build #68722 has finished for PR 15777 at commit
|
SparkQA
commented
Nov 17, 2016
Test build #68789 has finished for PR 15777 at commit
|
b6062b9 to
428348dCompareSparkQA
commented
Nov 17, 2016
Test build #68794 has finished for PR 15777 at commit
|
There was a problem hiding this comment.
@sethah Only last comment, otherwise, LGTM. I'd like to get this in before 2.1. Thanks.
| val copied = copyValues(new BisectingKMeansModel(uid, parentModel), extra) | ||
| if (trainingSummary.isDefined) copied.setSummary(trainingSummary.get) | ||
| copied.setParent(this.parent) | ||
| copied.setSummary(trainingSummary).setParent(this.parent) |
There was a problem hiding this comment.
This looks better. Could you make the change for Scala LiR, LoR, GLM and KMeans as well? I think they should be consistent. Thanks.
There was a problem hiding this comment.
Updated. I also added tests. Thanks for reviewing!
SparkQA
commented
Nov 21, 2016
Test build #68919 has finished for PR 15777 at commit
|
yanboliang
commented
Nov 21, 2016
LGTM, merged into master and branch-2.1. Thanks! |
…d BKM ## What changes were proposed in this pull request? Add model summary APIs for `GaussianMixtureModel` and `BisectingKMeansModel` in pyspark. ## How was this patch tested? Unit tests. Author: sethah <seth.hendrickson16@gmail.com> Closes#15777 from sethah/pyspark_cluster_summaries. (cherry picked from commit e811fbf) Signed-off-by: Yanbo Liang <ybliang8@gmail.com>
jkbradley
commented
Nov 21, 2016
@yanboliang I noticed the JIRA is still pending. Are there follow-up tasks? |
yanboliang
commented
Nov 22, 2016
No follow-up, forgetting to close it. Thanks for reminding. |
…d BKM ## What changes were proposed in this pull request? Add model summary APIs for `GaussianMixtureModel` and `BisectingKMeansModel` in pyspark. ## How was this patch tested? Unit tests. Author: sethah <seth.hendrickson16@gmail.com> Closesapache#15777 from sethah/pyspark_cluster_summaries.
What changes were proposed in this pull request?
Add model summary APIs for
GaussianMixtureModelandBisectingKMeansModelin pyspark.How was this patch tested?
Unit tests.