Distribution that has a range from 0 to 1 and with peak between them?

Is there a distribution or can I work from another distribution to create a distribution like that in the image below (apologies for the bad drawings)?

where I give a number (0.2, 0.5 and 0.9 in the examples) for where the peak should be and a standard deviation (sigma) that makes the function wider or less wide.

P.S.: When the given number is 0.5 the distribution is a normal distribution.

• en.wikipedia.org/wiki/Beta_distribution – djs Nov 28 '17 at 14:48
• note that the 0.5 case would not be the normal distribution since the range of the normal distribution is $\pm \infty$ – user137329 Nov 28 '17 at 14:50
• If you take your pictures literally then there are no distributions that look like that since the area in all cases are strictly less than 1. If you are going to restrict the support to [0,1] then you can't restrict the range of the pdf to [0,1] as well (other than in the trivial uniform case). – John Coleman Nov 28 '17 at 22:43

One possible choice is the beta distribution, but re-parametrized in terms of mean $\mu$ and precision $\phi$, that is, "for fixed $\mu$, the larger the value of $\phi$, the smaller the variance of $y$" (see Ferrari, and Cribari-Neto, 2004). The probability density function is constructed by replacing the standard parameters of beta distribution with $\alpha = \phi\mu$ and $\beta = \phi(1-\mu)$

$$f(y) = \frac{1}{\mathrm{B}(\phi\mu,\; \phi(1-\mu))}\; y^{\phi\mu-1} (1-y)^{\phi(1-\mu)-1}$$

where $E(Y) = \mu$ and $\mathrm{Var}(Y) = \frac{\mu(1-\mu)}{1+\phi}$.

Alternatively, you can calculate appropriate $\alpha$ and $\beta$ parameters that would lead to beta distribution with pre-defined mean and variance. However, notice that there are restrictions on possible values of variance that are valid for beta distribution. For me personally, the parametrization using precision is more intuitive (think of $x\,/\,\phi$ proportions in binomially distributed $X$, with sample size $\phi$ and the probability of success $\mu$).

Kumaraswamy distribution is another bounded continuous distribution, but it would be harder to re-parametrize like above.

As others have noticed, it is not normal since normal distribution has the $(-\infty, \infty)$ support, so at best you could use the truncated normal as an approximation.

Ferrari, S., & Cribari-Neto, F. (2004). Beta regression for modelling rates and proportions. Journal of Applied Statistics, 31(7), 799-815.

• I like your answer, I've constructed some graphs from it. The only problem I have is that I can't seem to control the width (sigma in a normal distribution of the curve). I would like to have a formula which calculates the phi value when a certain sigma value is given. The problem that I have is that the curve turns upside down or takes a weird shape, that's the behaviour I want to avoid. – Stan Callewaert Nov 28 '17 at 16:23
• In short: I would like to give a mu and a sigma to the function and then get a distribution which is wide when the sigma is big and is thin (but doesn't turn upside down or shows weird behaviour) when the sigma is small. – Stan Callewaert Nov 28 '17 at 16:25
• The precision and standard deviation are related: $\phi = \mu(1-\mu)/\sigma^2 - 1$. Also, the Beta Distribution is unimodal (won't show weird behavior) when $\alpha$ and $\beta$ are greater than 1. This means that when $\mu = 1/2$, you should choose $\phi > 2$ or equivalently $\sigma < 0.707$. – knrumsey Nov 28 '17 at 16:46
• Another thing to mention is that you could of course use mixtures of beta distributions, if a single beta distribution is not flexible enough. – Björn Nov 28 '17 at 16:59
• @knrumsey I've used the same formula for phi, the only problem I seem to have is that when the sigma is a big number, phi becomes a negative number which means alpha also becomes a negative number. Alpha can't be negative according to Wikipedia. Is there a solution for this? – Stan Callewaert Nov 28 '17 at 17:15

Try the beta distribution, its range is from 0 to 1. Have you tried this yet? The mean value is $\frac{\alpha}{(\alpha + \beta)}$

• Looks very interesting, but how can I convert my number (the peak value) and my sigma to the alpha and beta values? – Stan Callewaert Nov 28 '17 at 15:00
• Just look it up on wikipedia ... it's a two-parameter distribution. Between the two, they can tune to your peak value (with an extra degree of freedom). – user137329 Nov 28 '17 at 15:06

I transform to create this kind of variable. Start with a random variable, x, which has support on the whole real line (like normal), and then transform it to make a new random variable $y=\frac{exp(x)}{1+exp(x)}$. Presto, you have a random variable distributed on the unit interval. Since this particular transformation is increasing, you can move the mean/median/mode of y around by moving the mean/median/mode of x around. Want to make $y$ more dispersed (in terms of inter-quartile range, say)? Just make $x$ more dispersed.

There is nothing special about the function $\frac{exp(x)}{1+exp(x)}$. Any cumulative distribution function works to produce a new random variable defined on the unit interval.

So, any random variable transformed by plugging it into any cdf ($y=F(x)$) does what you want---makes an r.v. distributed on the unit interval whose properties you can conveniently adjust by adjusting the parameters of the untransformed random variable in an intuitive way. As long as $F()$ is strictly monotonic, the transformed variable will, in several ways, look like the untransformed one. For example, you want $y$ to be a unimodal random variable on the unit interval. As long as $F()$ is strictly increasing and $x$ is unimodal, you get that. Increasing the median/mean/mode of $x$ increases the median/mean/mode of $y$. Increasing the interquartile range of $x$ (by moving the 25th percentile down and the 75th percentile up) increases the interquartile range of $y$. Strict monotonicity is a nice thing.

The formula for calculating the mean and sd of $y$ is perhaps not easy to find, but that's what Monte Carlo simulations are for. To get relatively pretty distributions like the ones you draw, you want $x$ and $F()$ to be continuous random variables (cdf of continuous random variables) with support on the real line.

If somebody is interested in the solution I used in Python for generating a random value close to the given number as a parameter. My solution exist of four stages. Each stage the chance that the generated number is closer to the given number is bigger.

I know the solution is not as beautiful as using one distribution but this was the way I was able to solve my problem:

number_factory.py:

import random
import numpy as np

class NumberFactory:
def __init__(self):
self.functions = [self.__linear, self.__exponential_point_four, self.__exponential_point_three, self.__exponential_point_twenty_five]
self.stage = 0

def next_stage(self):
self.stage += 1

def get_mutated_number(self, number):
# True if the generated number will be higher than the given number
# False if the generated number will be lower than the given number

# Generate a number between 0 and 1 that will be used
# to multiply the new number by which the number parameter will be substracted or added
# The bigger the stage number (0-3) the more change that the mutated number is close to the number parameter
multiply_number_seed = random.uniform(0, 1)
multiply_number = self.functions[self.stage](multiply_number_seed)

return number+((1-number)*multiply_number)
else:
return number-(number*multiply_number)

def __linear(self, x):
return -x+1

def __exponential_point_four(self, x):
return 0.4*x**2 - 1.4*x + 1

def __exponential_point_three(self, x):
return 0.8*x**2 - 1.8*x + 1

def __exponential_point_twenty_five(self, x):
return x**2 - 2*x + 1

def get_stage(self):
return self.stage


main.py:

import matplotlib.pyplot as plt
import numpy as np

factory = NumberFactory()
numbers = []

factory.next_stage()
factory.next_stage()
factory.next_stage()

for _ in range(100000):
numbers.append(factory.get_mutated_number(0.3))

bins = 100

plt.hist(numbers, bins, normed=True)
plt.plot(1, np.ones_like(bins))
plt.show()


result when executing this code is shown in the picture below:

You might want to take a look at 'Johnson curves'. See N.L. Johnson: Systems of Frequency Curves generated by methods of translation. 1949 Biometrika Volume 36 pp 149-176. R has support for fitting them to arbitrary curves. In particular his SB (bounded) curves might be useful.

It's 40 years since I used them, but they were very useful to me at the time, and I think they will work for you.