Ответ 1
Вы можете легко достичь этого с помощью numpy. Он имеет функцию choice, которая принимает параметр вероятности.
np.random.choice(
['pooh', 'rabbit', 'piglet', 'Christopher'],
5,
p=[0.5, 0.1, 0.1, 0.3]
)
Я пытаюсь закодировать программу, которая использует функцию активации softmax посередине.
Сейчас у меня есть список вероятностей, подобных этому:
P[0.10,0.25,0.60,0.05]
Сумма всех переменных в P всегда равна 1.
Мне нужен способ выбрать индекс списка с учетом вероятности, привязанной к нему. Или, другими словами, функция, которая вернула
0 - 10% of the time
1 - 25% of the time
2 - 60% of the time
3 - 5% of the time
Я не знаю, с чего начать. Любая помощь будет оценена по достоинству.:)
Вы можете легко достичь этого с помощью numpy. Он имеет функцию choice, которая принимает параметр вероятности.
np.random.choice(
['pooh', 'rabbit', 'piglet', 'Christopher'],
5,
p=[0.5, 0.1, 0.1, 0.3]
)
Хм интересно, как насчет...
Создайте число от 0 до 1.
Пройдите список, вычитая вероятность каждого элемента из вашего номера.
Выберите элемент, который после вычитания уменьшил ваш номер до 0 или ниже.
Это просто, O (n) и должно работать:)
В принципе, создайте массив совокупное распределение вероятности (CDF). В принципе, значение CDF для данного индекса равно сумме всех значений в P, равных или меньших этого индекса. Затем вы создаете случайное число от 0 до 1 и выполняете двоичный поиск (или линейный поиск, если хотите). Вот какой-то простой код для него.
from bisect import bisect
from random import random
P = [0.10,0.25,0.60,0.05]
cdf = [P[0]]
for i in xrange(1, len(P)):
cdf.append(cdf[-1] + P[i])
random_ind = bisect(cdf,random())
конечно, вы можете создать кучу случайных индексов с чем-то вроде
rs = [bisect(cdf, random()) for i in xrange(20)]
получая
[2, 2, 3, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2]
(результаты будут и будут меняться). Разумеется, бинарный поиск довольно ненужен для стольких возможных индексов, но определенно рекомендуется для распределений с более возможными индексами.
То, что вы ищете, представляет собой взвешенное случайное поколение, и хотя оно не встроено, существует много стандартных рецептов для этого.
Эта проблема эквивалентна выборке из категориального распространения. Это распределение обычно сочетается с многочленным распределением, которое моделирует результат нескольких выборок из категориального распределения.
В numpy легко получить выборку из мультиномиального распределения, используя numpy.random.multinomial, но конкретной категориальной версии этого не существует. Однако это может быть выполнено путем выборки из многочленного распределения с одним испытанием и последующим возвратом ненулевого элемента в выходной файл.
import numpy as np
pvals = [0.10,0.25,0.60,0.05]
ind = np.where(np.random.multinomial(1,pvals))[0][0]
import random
probs = [0.1, 0.25, 0.6, 0.05]
r = random.random()
index = 0
while(r >= 0 and index < len(probs)):
r -= probs[index]
index += 1
print index - 1