Подтвердить что ты не робот

Сделайте число, более вероятное, результатом случайного

Я использую x = numpy.random.rand(1) для генерации случайного числа между 0 и 1. Как сделать так, чтобы x > .5 был в 2 раза более вероятным, чем x < .5?

4b9b3361

Ответ 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()

Example histogram

Ответ 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))