Uh oh!
There was an error while loading. Please reload this page.
[SPARK-17139][ML] Add model summary for MultinomialLogisticRegression - #15435
[SPARK-17139][ML] Add model summary for MultinomialLogisticRegression#15435WeichenXu123 wants to merge 11 commits into
Conversation
WeichenXu123
commented
Oct 11, 2016
@sethah This pr seems to be discussed about several details, I am pleasure to hear your opinion, thanks! |
SparkQA
commented
Oct 11, 2016
Test build #66748 has finished for PR 15435 at commit
|
sethah
commented
Oct 11, 2016
I'll try to take a look before too long. For now, I see there are no tests, could you please add tests, using the summary tests for binary classification as a guide? Thanks! |
SparkQA
commented
Oct 12, 2016
Test build #66804 has finished for PR 15435 at commit
|
SparkQA
commented
Oct 12, 2016
Test build #66805 has finished for PR 15435 at commit
|
sethah
commented
Oct 13, 2016
So I've been reading through some of the history with logistic regression summaries. There was a lot of discussion on how to design the abstractions for this, here and here. I'm reposting some of the relevant snippets (I will comment on them in a follow up): "We'll need to use traits to fix the multiple inheritance issue:" "Are we planning to have a MulticlassLogisticRegressionSummary inheriting from LogisticRegressionSummary in the future because without that I'm unable to understand how using a trait would help since there is no access to the predictions dataframe." "Yes, MulticlassLogisticRegressionSummary should be analogous to the binary version, with both inheriting from LogisticRegressionSummary." ... "Synced with @jkbradley offline. Summary: We should not require end users to perform any sort of downcasting in the stabilized API. This is OK for now since the API is still experimental. Eventually we could provide two methods, a summary : LogisticRegressionSummary and a binarySummary : BInaryLogisticRegressionSummary which errors when called on a multiclass LRModel. This will be easy to implement because summary is returning the base LogisticRegressionSummary class so will not require any public API change." |
sethah
commented
Oct 13, 2016
So, based on my interpretation of this and how this can actually work, we need to have: sealedtraitLogisticRegressionSummarysealedtraitLogisticRegressionTrainingSummaryclassMulticlassLogisticRegressionSummaryextendsLogisticRegressionSummaryclassMulticlassLogisticRegressionTrainingSummaryextendsMulticlassLogisticRegressionSummarywithLogisticRegressionTrainingSummaryclassBinaryLogisticRegressionSummaryextendsMulticlassLogisticRegressionSummaryclassBinaryLogisticRegressionTrainingSummaryextendsBinaryLogisticRegressionSummarywithLogisticRegressionTrainingSummaryThen, in defsummary:LogisticRegressionTrainingSummarydefbinarySummary:BinaryLogisticRegressionTrainingSummary= summary match {
caseb: BinaryLogisticRegressionTrainingSummary=> b
case _ =>thrownewException()
}And we avoid downcasting in the summary case since |
WeichenXu123
commented
Oct 15, 2016
@sethah Good suggestion. code updated, thanks! |
SparkQA
commented
Oct 15, 2016
Test build #67017 has finished for PR 15435 at commit
|
There was a problem hiding this comment.
Non-double numeric datatypes other than LongType maybe also needed to test. Any thoughts? @sethah
There was a problem hiding this comment.
@zhengruifeng Thanks for carefule review, because in the Summary class code we use labelValue.toDouble to do the cast so that we use one type LongType as the test is OK IMO, is there some possible case that LongType cast succeed but other legal numeric value will fails?
There was a problem hiding this comment.
Well, from a completeness standpoint I agree that it's better to test all the types that it's intended to work for. However, since it's just calling cast under the hood, it does seem a bit redundant. I'm ok leaving it as is, but I don't feel strongly about it.
sethah
commented
Oct 25, 2016
re-ping @jkbradley Would be great to get your thoughts on the above discussion since you were involved in the original design |
WeichenXu123
commented
Oct 26, 2016
@sethah jkbradley seems not online recently we can invite @yanboliang to give some advice. |
@sethah Thanks for pinging, and for bringing up those old design discussions (which are still the best options I know of). @WeichenXu123 sorry I've been slow to respond; I'm trying to keep up! I'll take a look at the PR. UPDATE: Regarding the class hierarchy above, the only one I'm not sure about is
I'm unsure here. What do you think? |
sethah
commented
Oct 26, 2016
@jkbradley Thanks for your input. I'm happy to review this, but wanted to get clarification before proceeding. I can take a look in the next couple of days. |
jkbradley
left a comment
There was a problem hiding this comment.
@sethah Sorry, didn't want to stomp on your review. I had started reviewing, but I'll just go ahead and submit these partial review comments. Thanks!
And thanks @WeichenXu123 for adding this.
There was a problem hiding this comment.
I'd actually just remove these 2 lines since they don't say anything useful.
There was a problem hiding this comment.
same here: remove these 2 lines since they don't say anything useful.
There was a problem hiding this comment.
Add Scala doc, especially saying that this will throw an exception when numClasses > 2.
There was a problem hiding this comment.
Don't use SparkException here; that's primarily for failures within Spark jobs AFAIK. I guess I'd use RuntimeException.
There was a problem hiding this comment.
Also, the current error doesn't really help the user. How about "Cannot create a binarySummary for a non-binary model (with numClasses = $numClasses). Use multinomialSummary instead."
There was a problem hiding this comment.
This is the only place where you need the probability2predictionUDF. Rather than passing a UDF or the model, I'd like us to modify findSummaryModelAndProbabilityCol to also set predictionCol if needed.
There was a problem hiding this comment.
These since tags should all be 2.1.0.
sethah
commented
Oct 26, 2016
@jkbradley No problems at all, it's always better to have more reviewers. |
WeichenXu123
commented
Oct 27, 2016
Now I am considering elemating the currently, the base interface And, whether should we make |
It seems that many metrics in |
@WeichenXu123 About breaking APIs: I'm OK adding predictionCol to LogisticRegressionSummary, even though I agree it technically breaks a public API:
So I don't see a way this could break a non-hack use case, but let me know if I'm not thinking of an edge case. @zhengruifeng I'm OK refactoring to create a MulticlassClassificationSummary (or MulticlassSummary?) now or later. Now does sound better. Let's keep it |
WeichenXu123
commented
Oct 28, 2016
All right. I will create a new class And thanks @zhengruifeng for good suggestion~ |
1bf5aa4 to
9c0e3feCompareSparkQA
commented
Nov 7, 2016
Test build #68283 has finished for PR 15435 at commit
|
9c0e3fe to
3b459f9CompareSparkQA
commented
Nov 7, 2016
Test build #68285 has finished for PR 15435 at commit
|
3b459f9 to
f0523f9CompareSparkQA
commented
Nov 18, 2016
Test build #68864 has finished for PR 15435 at commit
|
f0523f9 to
79c5ddaCompareSparkQA
commented
Nov 18, 2016
Test build #68865 has finished for PR 15435 at commit
|
46d49c9 to
d338a94CompareSparkQA
commented
Aug 21, 2017
Test build #80926 has finished for PR 15435 at commit
|
WeichenXu123
commented
Aug 21, 2017
Jenkins, test this please. |
SparkQA
commented
Aug 21, 2017
Test build #80928 has finished for PR 15435 at commit
|
d338a94 to
b6cde56CompareSparkQA
commented
Aug 21, 2017
Test build #80932 has finished for PR 15435 at commit
|
SparkQA
commented
Aug 22, 2017
Test build #80947 has finished for PR 15435 at commit
|
WeichenXu123
commented
Aug 22, 2017
Jenkins, test this please. |
SparkQA
commented
Aug 22, 2017
Test build #80954 has finished for PR 15435 at commit
|
| } | ||
| /** | ||
| * Returns the sequence of labels in ascending order |
There was a problem hiding this comment.
Clarify: "Returns the sequence of labels in ascending order. This order matches the order used in metrics which are specified as arrays over labels, e.g., truePositiveRateByLabel."
jkbradley
left a comment
There was a problem hiding this comment.
Has there been discussion of removing the Experimental tags from the summary types? I'd prefer to leave them since there is still talk of further refactoring (e.g., generalizing out a ClassificationSummary across different models).
Other than that + my 1 small comment, this looks ready. @sethah and @yanboliang any more comments?
Thanks everyone!
MLnick
commented
Aug 23, 2017
I agree keeping the |
SparkQA
commented
Aug 23, 2017
Test build #81022 has finished for PR 15435 at commit
|
OK, then let's reinstate the Experimental tags. @WeichenXu123 could you please mark the 4 public summary traits Experimental? |
SparkQA
commented
Aug 25, 2017
Test build #81111 has finished for PR 15435 at commit
|
WeichenXu123
commented
Aug 25, 2017
Jenkins test this please |
SparkQA
commented
Aug 25, 2017
Test build #81119 has finished for PR 15435 at commit
|
WeichenXu123
commented
Aug 25, 2017
Jenkins test this please |
SparkQA
commented
Aug 25, 2017
Test build #81124 has finished for PR 15435 at commit
|
jkbradley
commented
Aug 28, 2017
LGTM |
What changes were proposed in this pull request?
Add 4 traits, using the following hierarchy:
LogisticRegressionSummary
LogisticRegressionTrainingSummary: LogisticRegressionSummary
BinaryLogisticRegressionSummary: LogisticRegressionSummary
BinaryLogisticRegressionTrainingSummary: LogisticRegressionTrainingSummary, BinaryLogisticRegressionSummary
and the public method such as
def summaryonly return trait type listed above.and then implement 4 concrete classes:
LogisticRegressionSummaryImpl (multiclass case)
LogisticRegressionTrainingSummaryImpl (multiclass case)
BinaryLogisticRegressionSummaryImpl (binary case).
BinaryLogisticRegressionTrainingSummaryImpl (binary case).
How was this patch tested?
Existing tests & added tests.