Come campionate in modo uniforme gli intervalli da una linea delimitata?

Aug 24 2020

Supponi di avere una linea delimitata e continua. Ad esempio, la linea potrebbe includere tutti i numeri reali compresi tra 0 e 3. Come campionare gli intervalli dalla linea in modo tale che ...

  • Qualsiasi punto sulla linea ha la stessa possibilità di essere incluso nello span.
  • La distribuzione delle lunghezze di campata è uniforme.

La mia soluzione tentata:

import random

max_length = 15.0
bounds = (0.0, 3.0)

length = random.uniform(0, max_length)
start = random.uniform(bounds[0] - length, bounds[1])
end = min(start + length, bounds[1])
start = max(start, bounds[0])

Questa soluzione è in grado di soddisfare il primo criterio e non il secondo.

EDIT: seguendo l'esempio di BruceET, ho tracciato la distribuzione delle lunghezze di campata:

import random
from matplotlib import pyplot
import seaborn

max_length = 6
bounds = (0, 3)
num_samples = 10**6

samples = []
for _ in range(num_samples):
    length = random.uniform(0, max_length)
    start = random.uniform(bounds[0] - length, bounds[1])
    end = min(start + length, bounds[1])
    start = max(start, bounds[0])
    samples.append(end - start)

seaborn.distplot(
    samples,
    hist=True,
    kde=True,
    bins=30,
    color='darkblue',
    hist_kws={'edgecolor': 'black'},
    kde_kws={'linewidth': 1})
pyplot.show()

Risposte

3 BruceET Aug 24 2020 at 01:41

Commento: hai problemi con la tua seconda simulazione perché la "durata" di diverse variabili casuali uniformi non è uniforme.

In R, la funzione rangefornisce gli endpoint, prendendo la differenza si ottiene ciò che si chiama "span".

Ecco una simulazione in R delle lunghezze di span da 100.000 campioni di dimensione $n=5$ a partire dal $\mathsf{Unif}(0, 3).$

set.seed(2020)
span.5 = replicate(10^6, diff(range(runif(5,0,3))))
summary(span.5)
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
0.07294 1.63716 2.05782 1.99968 2.41826 2.99932 
hist(span.5, prob=T, col="skyblue2")
curve((1/3)*dbeta(x/3, 4, 2), add=T, col="red", lwd=2)