Я использую x = numpy.random.rand(1)
для генерации случайного числа между 0 и 1. Как сделать так, чтобы x > .5
был в 2 раза более вероятным, чем x < .5
?
Сделайте число, более вероятное, результатом случайного
Ответ 1
Это подходящее имя!
Просто немного манипулируйте входами. Сначала установите x
в диапазоне от 0
до 1.5
.
x = numpy.random.uniform(1.5)
x
имеет вероятность 2/3
быть выше 0.5
и 1/3
вероятность меньше. Тогда, если x
больше, чем 1.0
, вычтите из него .5
if x >= 1.0:
x = x - 0.5
Ответ 2
Это слишком много для вас, но полезно знать фактический метод генерации случайного числа с любой функцией плотности вероятности (pdf).
Вы можете сделать это путем подкласса scipy.stat.rv_continuous, если вы сделаете это правильно. У вас должен быть нормализованный pdf (так что его интеграл равен 1). Если вы этого не сделаете, numpy автоматически отрегулирует диапазон для вас. В этом случае ваш pdf имеет значение 2/3 для x < 0,5 и 4/3 для x > 0,5 с поддержкой [0, 1) (поддержка - это интервал, на котором он отличен от нуля):
import scipy.stats as spst
import numpy as np
import matplotlib.pyplot as plt
import ipdb
def pdf_shape(x, k):
if x < 0.5:
return 2/3.
elif 0.5 <= x and x < 1:
return 4/3.
else:
return 0.
class custom_pdf(spst.rv_continuous):
def _pdf(self, x, k):
return pdf_shape(x, k)
instance = custom_pdf(a=0, b=1)
samps = instance.rvs(k=1, size=10000)
plt.hist(samps, bins=20)
plt.show()
Ответ 3
tmp = random()
if tmp < 0.5: tmp = random()
- довольно простой способ сделать это
ehh Я предполагаю, что это в 3 раза скорее... вот что я получаю для сна через этот класс, я думаю
from random import random,uniform
def rand1():
tmp = random()
if tmp < 0.5:tmp = random()
return tmp
def rand2():
tmp = uniform(0,1.5)
return tmp if tmp <= 1.0 else tmp-0.5
sample1 = []
sample2 = []
for i in range(10000):
sample1.append(rand1()>=0.5)
sample2.append(rand2()>=0.5)
print sample1.count(True) #~ 75%
print sample2.count(True) #~ 66% <- desired i believe :)
Ответ 4
Во-первых, numpy.random.rand(1)
не возвращает значение в диапазоне [0,1)
(полуоткрытый, включает ноль, но не один), он возвращает массив размером один, содержащий значения в этом диапазоне, с верхним конец диапазона, не имеющий никакого отношения к аргументу, переданному.
Функция, которой вы, вероятно, после этого, является равномерным распределением, numpy.random.uniform()
, поскольку это позволит использовать произвольный верхний диапазон.
И, чтобы сделать верхнюю половину вдвое вероятнее всего относительно простой.
Возьмем, например, генератор случайных чисел r(n)
, который возвращает равномерно распределенное целое число в диапазоне [0,n)
. Все, что вам нужно сделать, это отрегулировать значения для изменения распределения:
x = r(3) # 0, 1 or 2, @ 1/3 probability each
if x == 2:
x = 1 # Now either 0 (@ 1/3) or 1 (@ 2/3)
Теперь шансы получить нуль равны 1/3, а шансы получить один - 2/3, в основном то, что вы пытаетесь достичь с помощью значений с плавающей запятой.
Итак, я бы просто получил случайное число в диапазоне [0,1.5)
, а затем вычитал 0.5, если он больше или равен одному.
x = numpy.random.uniform(high=1.5)
if x >= 1: x -= 0.5
Поскольку исходное распределение должно быть равно даже в диапазоне [0,1.5)
, вычитание должно сделать [0.5,1.0)
вдвое вероятнее (и [1.0,1.5)
невозможно), сохраняя распределение даже внутри каждого раздела ([0,0.5)
и [0.5,1)
):
[0.0,0.5) [0.5,1.0) [1.0,1.5) before
<---------><---------><--------->
[0.0,0.5) [0.5,1.0) [0.5,1.0) after
Ответ 5
Вы можете использовать подход "смешанной модели", в котором вы разбиваете процесс на два этапа: во-первых, решите, следует ли использовать вариант A или B, где B в два раза чаще, чем A; то, если вы выбрали A, верните случайное число между 0.0 и 0.5, иначе, если вы выбрали B, верните один из 0.5 и 1.0.
В примере randint случайным образом возвращает 0, 1 или 2, поэтому случай else
в два раза больше, чем случай if
.
m = numpy.random.randint(3)
if m==0:
x = numpy.random.uniform(0.0, 0.5)
else:
x = numpy.random.uniform(0.5, 1.0)
Это немного дороже (две случайные ничьи вместо одного), но он может обобщать на более сложные дистрибутивы довольно простым способом.
Ответ 6
Если вы хотите более жидкую случайность, вы можете просто скомпоновать вывод случайной функции
(и вычтите его из 1, чтобы сделать x > 0.5
более вероятным вместо x < 0.5
).
x = 1 - sqr(numpy.random.rand(1))