2010-12-14 35 views
14

Tôi đã cố mã hóa chương trình sử dụng hàm kích hoạt softmax ở giữa.Chọn biến danh sách cho xác suất của mỗi biến

Ngay bây giờ, tôi có một danh sách xác suất như thế này:

P[0.10,0.25,0.60,0.05] 

Tổng của tất cả các biến trong P luôn là 1.

Tôi muốn có một cách để chọn chỉ số của danh sách cho xác suất gắn liền với nó. Hoặc nói cách khác, một hàm trả về

0 - 10% of the time 
1 - 25% of the time 
2 - 60% of the time 
3 - 5% of the time 

Tôi hoàn toàn không biết bắt đầu từ đâu. Bất kỳ trợ giúp sẽ được đánh giá cao. :)

Trả lời

10

Hmm thú vị, làm thế nào về ...

  1. Tạo một số giữa 0 và 1.

  2. Đi bộ danh sách trừ đi xác suất của từng hạng mục từ số của bạn.

  3. Chọn mục sau khi chất nền, lấy số của bạn xuống 0 hoặc thấp hơn.

Đó là đơn giản, O (n) và nên làm việc :)

2
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

Haha và ở đây tôi nghĩ ~ 2 giây trước khi bạn đăng rằng tôi đã được ban – slezica

+0

@Santiago: và tôi tự hỏi tại sao bạn đã gõ nó bằng tiếng Anh :) – sje397

10

Về cơ bản, tạo một mảng cumulative probability distribution (CDF). Về cơ bản, giá trị của CDF cho một chỉ mục đã cho bằng tổng của tất cả các giá trị trong P bằng hoặc nhỏ hơn chỉ số đó. Sau đó, bạn tạo một số ngẫu nhiên từ 0 đến 1 và thực hiện tìm kiếm nhị phân (hoặc tìm kiếm tuyến tính nếu bạn muốn). Đây là một số mã đơn giản cho nó.

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

tất nhiên bạn có thể tạo ra một loạt các chỉ số ngẫu nhiên với một cái gì đó giống như

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

năng suất

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

(kết quả sẽ, và nên thay đổi). Tất nhiên, tìm kiếm nhị phân là không cần thiết cho rất ít chỉ mục có thể, nhưng chắc chắn được đề xuất cho các bản phân phối có nhiều chỉ mục có thể hơn.

+0

Đó là đẹp .... – sje397

3

Sự cố này tương đương với lấy mẫu từ categorical distribution. Sự phân bố này thường được liên kết với sự phân bố đa thức mô hình kết quả của nhiều mẫu từ một phân bố phân loại.

Ở dạng vón cục, rất dễ lấy mẫu từ bản phân phối đa thức sử dụng numpy.random.multinomial, nhưng một phiên bản phân loại cụ thể của điều này không tồn tại. Tuy nhiên, nó có thể được thực hiện bằng cách lấy mẫu từ phân phối đa thức với một thử nghiệm đơn lẻ và sau đó trả về phần tử khác 0 trong đầu ra.

import numpy as np 
pvals = [0.10,0.25,0.60,0.05] 
ind = np.where(np.random.multinomial(1,pvals))[0][0] 
15

Bạn có thể dễ dàng đạt được điều này với sự khó khăn. Nó có hàm choice chấp nhận tham số của xác suất.

np.random.choice(
    ['pooh', 'rabbit', 'piglet', 'Christopher'], 
    5, 
    p=[0.5, 0.1, 0.1, 0.3] 
) 
Các vấn đề liên quan