Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 29.4k
SPARK-1939 Refactor takeSample method in RDD to use ScaSRS#916
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
1441977ffea61a7cab53ae3fd6a69bdd36e065ebcdae3ad04f80f2700a9b3e3ecab508eff89e255518ed64e445bdc699f31481b01fb1452f48d954d82dde313de882b444e7505b061aeFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.spark.util.random | ||
| private[spark] object SamplingUtils { | ||
| /** | ||
| * Returns a sampling rate that guarantees a sample of size >= sampleSizeLowerBound 99.99% of | ||
| * the time. | ||
| * | ||
| * How the sampling rate is determined: | ||
| * Let p = num / total, where num is the sample size and total is the total number of | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The first sentence should be a brief description. | ||
| * datapoints in the RDD. We're trying to compute q > p such that | ||
| * - when sampling with replacement, we're drawing each datapoint with prob_i ~ Pois(q), | ||
| * where we want to guarantee Pr[s < num] < 0.0001 for s = sum(prob_i for i from 0 to total), | ||
| * i.e. the failure rate of not having a sufficiently large sample < 0.0001. | ||
| * Setting q = p + 5 * sqrt(p/total) is sufficient to guarantee 0.9999 success rate for | ||
| * num > 12, but we need a slightly larger q (9 empirically determined). | ||
| * - when sampling without replacement, we're drawing each datapoint with prob_i | ||
| * ~ Binomial(total, fraction) and our choice of q guarantees 1-delta, or 0.9999 success | ||
| * rate, where success rate is defined the same as in sampling with replacement. | ||
| * | ||
| * @param sampleSizeLowerBound sample size | ||
| * @param total size of RDD | ||
| * @param withReplacement whether sampling with replacement | ||
| * @return a sampling rate that guarantees sufficient sample size with 99.99% success rate | ||
| */ | ||
| def computeFractionForSampleSize(sampleSizeLowerBound: Int, total: Long, | ||
| withReplacement: Boolean): Double = { | ||
| val fraction = sampleSizeLowerBound.toDouble / total | ||
| if (withReplacement) { | ||
| val numStDev = if (sampleSizeLowerBound < 12) 9 else 5 | ||
| fraction + numStDev * math.sqrt(fraction / total) | ||
| } else { | ||
| val delta = 1e-4 | ||
| val gamma = - math.log(delta) / total | ||
| math.min(1, fraction + gamma + math.sqrt(gamma * gamma + 2 * gamma * fraction)) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,46 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one or more | ||
| * contributor license agreements. See the NOTICE file distributed with | ||
| * this work for additional information regarding copyright ownership. | ||
| * The ASF licenses this file to You under the Apache License, Version 2.0 | ||
| * (the "License"); you may not use this file except in compliance with | ||
| * the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package org.apache.spark.util.random | ||
| import org.apache.commons.math3.distribution.{BinomialDistribution, PoissonDistribution} | ||
| import org.scalatest.FunSuite | ||
| class SamplingUtilsSuite extends FunSuite { | ||
| test("computeFraction") { | ||
| // test that the computed fraction guarantees enough data points | ||
| // in the sample with a failure rate <= 0.0001 | ||
| val n = 100000 | ||
| for (s <- 1 to 15) { | ||
| val frac = SamplingUtils.computeFractionForSampleSize(s, n, true) | ||
| val poisson = new PoissonDistribution(frac * n) | ||
| assert(poisson.inverseCumulativeProbability(0.0001) >= s, "Computed fraction is too low") | ||
| } | ||
| for (s <- List(20, 100, 1000)) { | ||
| val frac = SamplingUtils.computeFractionForSampleSize(s, n, true) | ||
| val poisson = new PoissonDistribution(frac * n) | ||
| assert(poisson.inverseCumulativeProbability(0.0001) >= s, "Computed fraction is too low") | ||
| } | ||
| for (s <- List(1, 10, 100, 1000)) { | ||
| val frac = SamplingUtils.computeFractionForSampleSize(s, n, false) | ||
| val binomial = new BinomialDistribution(n, frac) | ||
| assert(binomial.inverseCumulativeProbability(0.0001)*n >= s, "Computed fraction is too low") | ||
| } | ||
| } | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be
<scope>test</scope>if it's a test-only dependency?