Цикл по конечным весам вероятности с SciPy / NumPy - PullRequest
1 голос
/ 02 октября 2019

Пусть у нас есть единственная вероятность события prob, которая является скаляром между 0-1. Если я хочу перебрать каждую возможную вероятность с шагом 0,1, тогда я могу использовать:

prob = np.arange(0.01, 1, 0.1)

Теперь предположим, что у меня есть 5 событий (независимых, вероятности составляют 1), каждое с вероятностью p_i. Я хотел бы иметь многомерные массивы вероятностей, такие как:

1.0 - 0.0 - 0.0 - 0.0 - 0.0
0.9 - 0.1 - 0.0 - 0.0 - 0.0
0.9 - 0.0 - 0.1 - 0.0 - 0.0
0.9 - 0.0 - 0.0 - 0.1 - 0.0
0.9 - 0.0 - 0.0 - 0.0 - 0.1
0.8 - 0.1 - 0.1 - 0.0 - 0.0
0.8 - 0.1 - 0.0 - 0.1 - 0.0
.      .     .     .     .
.      .     .     .     .
.      .     .     .     . 
0.2 - 0.2 - 0.2 - 0.2 - 0.2

Есть ли более умный способ, чем рассматривать все комбинации 0 - 0,1 - ... - 1 и удалять строки, не суммирующиедо 1? Если да, какой самый простой способ?

Ответы [ 2 ]

1 голос
/ 02 октября 2019

Вы можете использовать itertools.product и filter, чтобы создать все комбинации на сумму 10 и передать их в массив:

import itertools
f = filter(lambda x: sum(x) == 10, itertools.product(*[range(11)]*5))
x = np.array(list(f)).astype(np.float)/10
x
>> array([[0. , 0. , 0. , 0. , 1. ],
       [0. , 0. , 0. , 0.1, 0.9],
       [0. , 0. , 0. , 0.2, 0.8],
       ...,
       [0.9, 0. , 0.1, 0. , 0. ],
       [0.9, 0.1, 0. , 0. , 0. ],
       [1. , 0. , 0. , 0. , 0. ]])

РЕДАКТИРОВАТЬ

Длязапись, вот более эффективный способ без использования фильтрации. По сути, вы создаете k бинов (в вашем примере 10) и «присваиваете» их «n» семплам (в вашем примере 3) во всех возможных комбинациях, используя combinations_with_replacement

Затем выпосчитайте, сколько бинов получает каждый образец: это ваша вероятность. Этот метод более сложен для понимания, но избегает filter, и, следовательно, он намного эффективнее. Вы можете попробовать это с делениями 0,01 (k = 100)

n = 3 # number of samples
k = 100 # number of subdivisions

f = itertools.combinations_with_replacement(range(3),k) #your iterator
r = np.array(list(f)) #your array of combinations
x = np.vstack((r==i).sum(1) for i in range(n)).T/k #your probability matrix
0 голосов
/ 02 октября 2019

Вероятно, есть более элегантное решение, использующее itertools, но это, вероятно, хорошо и не использует никаких зависимостей?:

for i in prob:
  for j in prob:
     for k in prob:
        for l in prob:
           m = 1 - i - j - l
           if m>=0:
              print(i,j,k,l,m)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...