I have a dataset which has a very skewed distribution across a parameter
S, which is in the range
[0,1). There are many, many values close to 0, and very few above 0.05. My goal is to draw a random sample from this distribution which has a roughly uniform distribution across
I start by binning the points into 1000 linearly-spaced bins, and then calculate a weight parameter
w_i = 1/N_i, where
N_i is the number of points in bin
i. The figure below shows the number of points per bin. Some bins have more than 100M points, others have as few as 500.
Then I perform a weighted random sample on this parameter. To perform the weighted random sampling, I sort by a parameter
weight_order = -log(rand())/w_i and take the first
N rows. (I originally saw this suggested on this Stack Overflow answer, and I have not thought through the math carefully.) Note that this is sampling without replacement.
This approach results in a uniform distribution as long as
N is sufficiently small. See for example the histogram for
The histogram is somewhat sparse because I have included all 1000 bins so the average number per bin
N_i=1, but aggregating into fewer larger bins visually confirms that the sample is reasonably uniform.
However, for larger
N, the resulting sample starts to become skewed. See the same but for
N = 10000.
I want 10 samples per bin, but already the resulting sample is quite skewed towards the thicker parts of the source distribution.
Thus, my question: is there a better way to sample my original dataset such that I get an approximately uniform distribution even as
N becomes larger? Ultimately I would like to sample 100000 points, which would ideally result in about 100 samples per bin, which is still quite a bit less than the smallest number of points in a bin in the original dataset (~500).