'What are the arguments for scipy.stats.uniform?
I'm trying to create a uniform distribution between two numbers (lower bound and upper bound) in order to feed it to sklearn's ParameterSampler. I am using scipy.stats.uniform in the following format:
from scipy.stats import uniform
params = ParameterSampler({'bandwidth':uniform(5,50)}, 20)
But when I get the random selections of the 'bandwidth' parameter, they are not all between 5 and 50. Some of them are bigger than 50 by a bit. So my question is what do the arguments in scipy.stats.uniform represent? Are they not a lower bound and upper bound? The documentation shows no arguments so I can't figure it out from that.
Solution 1:[1]
The first argument is the lower bound, and the second argument is the range of the distribution. So the example distribution in your question is uniform between 5 and 55.
Quoting from the documentation linked in your question:
A uniform continuous random variable.
This distribution is constant between
loc
andloc + scale
.
loc
is the first argument and scale
is the second argument.
Solution 2:[2]
In the given case the call should look like that:
uniform.rvs(loc=5, scale=45)
Even though it's possible to call the distribution directly with parameters, scipy.stats
has the following logic:
<dist_name>.rvs(loc=<param1>, scale=<param2>, size=(Nx, Ny))
Solution 3:[3]
The loc
is the lower bound and scale
is upper bound subtracted from the lower bound.
Function
Here is a function to do that for you:
from scipy.stats import uniform
def get_uniform(min, max):
"""Transform min (lower bound) and max (upper bound)
to scipy.stats.uniform parameters"""
return uniform(loc=min, scale=max-min)
Proof
I tested it with this:
size = 100000
experiments = [
(5_000, 10_000),
(-10_000, -5_000),
(-1_000, 0),
(0, 1_000),
]
for lb, ub in experiments:
print(f"Experiment (Lower: {lb}, Upper: {ub})")
rand_values = get_uniform(min=lb, max=ub).rvs(size)
print(f"Observed range: {int(round(rand_values.min(), 0))} to {int(round(rand_values.max(), 0))}")
print()
Which gives:
Experiment (Lower: 5000, Upper: 10000)
Observed range: 5000 to 10000
Experiment (Lower: -10000, Upper: -5000)
Observed range: -10000 to -5000
Experiment (Lower: -1000, Upper: 0)
Observed range: -1000 to 0
Experiment (Lower: 0, Upper: 1000)
Observed range: 0 to 1000
Which is exactly as you would expect.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | Anton K |
Solution 3 | miksus |