Choose list variable given probability of each variable

后端 未结 5 1431
野趣味
野趣味 2020-12-08 00:34

I\'ve been trying to code a program that uses the softmax activation function in the middle.

Right now, I have a list of probabilities like this:

P[0         


        
相关标签:
5条回答
  • 2020-12-08 01:07

    You can easily achieve this with numpy. It has a choice function which accepts the parameter of probabilities.

    np.random.choice(
      ['pooh', 'rabbit', 'piglet', 'Christopher'], 
      5,
      p=[0.5, 0.1, 0.1, 0.3]
    )
    
    0 讨论(0)
  • 2020-12-08 01:12

    This problem is equivalent to sampling from a categorical distribution. This distribution is commonly conflated with the multinomial distribution which models the result of multiple samples from a categorical distribution.

    In numpy, it is easy to sample from the multinomial distribution using numpy.random.multinomial, but a specific categorical version of this does not exist. However, it can be accomplished by sampling from the multinomial distribution with a single trial and then returning the non-zero element in the output.

    import numpy as np
    pvals = [0.10,0.25,0.60,0.05]
    ind = np.where(np.random.multinomial(1,pvals))[0][0]
    
    0 讨论(0)
  • 2020-12-08 01:21
    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
    
    0 讨论(0)
  • 2020-12-08 01:27

    Hmm interesting, how about...

    1. Generate a number between 0 and 1.

    2. Walk the list substracting the probability of each item from your number.

    3. Pick the item that, after substraction, took your number down to 0 or below.

    That's simple, O(n) and should work :)

    0 讨论(0)
  • 2020-12-08 01:32

    Basically, make a cumulative probability distribution (CDF) array. Basically, the value of the CDF for a given index is equal to the sum of all values in P equal to or less than that index. Then you generate a random number between 0 and 1 and do a binary search (or linear search if you want). Here's some simple code for it.

    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())
    

    of course you can generate a bunch of random indices with something like

    rs = [bisect(cdf, random()) for i in xrange(20)]
    

    yielding

    [2, 2, 3, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2]
    

    (results will, and should vary). Of course, binary search is rather unnecessary for so few of possible indices, but definitely recommended for distributions with more possible indices.

    0 讨论(0)
提交回复
热议问题