Uh oh!
There was an error while loading. Please reload this page.
[SPARK-21818][ML][MLLIB] Fix bug of MultivariateOnlineSummarizer.variance generate negative result - #19029
[SPARK-21818][ML][MLLIB] Fix bug of MultivariateOnlineSummarizer.variance generate negative result#19029WeichenXu123 wants to merge 6 commits into
Conversation
| realVariance(i) = (currM2n(i) + deltaMean(i) * deltaMean(i) * weightSum(i) * | ||
| (totalWeightSum - weightSum(i)) / totalWeightSum) / denominator | ||
| // Because of numerical error, it is possible to get negative real variance | ||
| if (realVariance(i) < 0.0) { |
There was a problem hiding this comment.
Just use math.max(0.0 ...) in the line above? no need to assign it twice.
There was a problem hiding this comment.
The computation of variance may be touch this numerical error, it seems WeightedLeastSquares also use the same method to compute variance , does it will have similar issue? @WeichenXu123
There was a problem hiding this comment.
Hmm.. WeightedLeastSquares use another way to compute variance Var(X) = E(X^2) - E(X)^2. But it seems also possible to have this problem.
SparkQA
commented
Aug 23, 2017
Test build #81032 has finished for PR 19029 at commit
|
SparkQA
commented
Aug 25, 2017
Test build #81118 has finished for PR 19029 at commit
|
yanboliang
left a comment
There was a problem hiding this comment.
One minor comments, otherwise, LGTM.
| * Weighted population standard deviation of labels. | ||
| */ | ||
| def bStd: Double = math.sqrt(bbSum / wSum - bBar * bBar) | ||
| def bStd: Double = math.sqrt(math.max(bbSum / wSum - bBar * bBar, 0.0)) |
There was a problem hiding this comment.
Please add comment here and bellow to clarify that we are preventing from negative value caused by numerical error.
SparkQA
commented
Aug 25, 2017
Test build #81127 has finished for PR 19029 at commit
|
SparkQA
commented
Aug 25, 2017
Test build #81129 has finished for PR 19029 at commit
|
| * We prevent variance from negative value caused by numerical error. | ||
| */ | ||
| def bStd: Double = math.sqrt(bbSum / wSum - bBar * bBar) | ||
| def bStd: Double = math.sqrt(math.max(bbSum / wSum - bBar * bBar, 0.0)) |
There was a problem hiding this comment.
There are a couple more places where variance is computed in this file -- I think they need this too?
SparkQA
commented
Aug 27, 2017
Test build #81167 has finished for PR 19029 at commit
|
| /** | ||
| * Weighted population standard deviation of labels. | ||
| * We prevent variance from negative value caused by numerical error. |
There was a problem hiding this comment.
I'm not so against this, but this is really an implementation detail and not relevant to the caller. It's a value that is by definition nonnegative.
SparkQA
commented
Aug 28, 2017
Test build #81171 has finished for PR 19029 at commit
|
Merged to master/2.2 |
…ance generate negative result Because of numerical error, MultivariateOnlineSummarizer.variance is possible to generate negative variance. **This is a serious bug because many algos in MLLib** **use stddev computed from** `sqrt(variance)` **it will generate NaN and crash the whole algorithm.** we can reproduce this bug use the following code: ``` val summarizer1 = (new MultivariateOnlineSummarizer) .add(Vectors.dense(3.0), 0.7) val summarizer2 = (new MultivariateOnlineSummarizer) .add(Vectors.dense(3.0), 0.4) val summarizer3 = (new MultivariateOnlineSummarizer) .add(Vectors.dense(3.0), 0.5) val summarizer4 = (new MultivariateOnlineSummarizer) .add(Vectors.dense(3.0), 0.4) val summarizer = summarizer1 .merge(summarizer2) .merge(summarizer3) .merge(summarizer4) println(summarizer.variance(0)) ``` This PR fix the bugs in `mllib.stat.MultivariateOnlineSummarizer.variance` and `ml.stat.SummarizerBuffer.variance`, and several places in `WeightedLeastSquares` test cases added. Author: WeichenXu <WeichenXu123@outlook.com> Closes#19029 from WeichenXu123/fix_summarizer_var_bug. (cherry picked from commit 0456b40) Signed-off-by: Sean Owen <sowen@cloudera.com>
…ance generate negative result Because of numerical error, MultivariateOnlineSummarizer.variance is possible to generate negative variance. **This is a serious bug because many algos in MLLib** **use stddev computed from** `sqrt(variance)` **it will generate NaN and crash the whole algorithm.** we can reproduce this bug use the following code: ``` val summarizer1 = (new MultivariateOnlineSummarizer) .add(Vectors.dense(3.0), 0.7) val summarizer2 = (new MultivariateOnlineSummarizer) .add(Vectors.dense(3.0), 0.4) val summarizer3 = (new MultivariateOnlineSummarizer) .add(Vectors.dense(3.0), 0.5) val summarizer4 = (new MultivariateOnlineSummarizer) .add(Vectors.dense(3.0), 0.4) val summarizer = summarizer1 .merge(summarizer2) .merge(summarizer3) .merge(summarizer4) println(summarizer.variance(0)) ``` This PR fix the bugs in `mllib.stat.MultivariateOnlineSummarizer.variance` and `ml.stat.SummarizerBuffer.variance`, and several places in `WeightedLeastSquares` test cases added. Author: WeichenXu <WeichenXu123@outlook.com> Closesapache#19029 from WeichenXu123/fix_summarizer_var_bug. (cherry picked from commit 0456b40) Signed-off-by: Sean Owen <sowen@cloudera.com>
What changes were proposed in this pull request?
Because of numerical error, MultivariateOnlineSummarizer.variance is possible to generate negative variance.
This is a serious bug because many algos in MLLib
use stddev computed from
sqrt(variance)it will generate NaN and crash the whole algorithm.
we can reproduce this bug use the following code:
This PR fix the bugs in
mllib.stat.MultivariateOnlineSummarizer.varianceandml.stat.SummarizerBuffer.variance, and several places inWeightedLeastSquaresHow was this patch tested?
test cases added.