이러한 답변 중 특히 명확하거나 간단한 것은 없습니다.
작동이 보장되는 명확하고 간단한 방법입니다.
축적p
_ 정규화 확률은 기호를 확률 또는 빈도로 매핑 하는 사전 을 사용합니다 . 선택을 수행 할 수있는 사용 가능한 튜플 목록을 출력합니다.
def accumulate_normalize_values(p):
pi = p.items() if isinstance(p,dict) else p
accum_pi = []
accum = 0
for i in pi:
accum_pi.append((i[0],i[1]+accum))
accum += i[1]
if accum == 0:
raise Exception( "You are about to explode the universe. Continue ? Y/N " )
normed_a = []
for a in accum_pi:
normed_a.append((a[0],a[1]*1.0/accum))
return normed_a
수율 :
>>> accumulate_normalize_values( { 'a': 100, 'b' : 300, 'c' : 400, 'd' : 200 } )
[('a', 0.1), ('c', 0.5), ('b', 0.8), ('d', 1.0)]
작동하는 이유
퇴적 단계는 (첫 번째 심볼의 경우는 0) 자체 이전 심볼 확률 또는 주파수 간격으로 각각의 기호를 온. 이 간격은 간격 0.0-> 1.0 (이전 준비)의 난수가 현재 심볼의 간격 끝점보다 작거나 같아 질 때까지 간단히 목록을 단계별로 선택하여 선택하여 제공된 분포를 샘플링하는 데 사용할 수 있습니다.
정상화는 어떤 값으로 확인 모든 합계를 만들기 위해 필요에서 우리를 해제합니다. 정규화 후 확률의 "벡터"는 1.0이됩니다.
코드의 나머지 선택 및 분포로부터 임의의 길이의 샘플을 생성하기위한 이하이다 :
def select(symbol_intervals,random):
print symbol_intervals,random
i = 0
while random > symbol_intervals[i][1]:
i += 1
if i >= len(symbol_intervals):
raise Exception( "What did you DO to that poor list?" )
return symbol_intervals[i][0]
def gen_random(alphabet,length,probabilities=None):
from random import random
from itertools import repeat
if probabilities is None:
probabilities = dict(zip(alphabet,repeat(1.0)))
elif len(probabilities) > 0 and isinstance(probabilities[0],(int,long,float)):
probabilities = dict(zip(alphabet,probabilities)) #ordered
usable_probabilities = accumulate_normalize_values(probabilities)
gen = []
while len(gen) < length:
gen.append(select(usable_probabilities,random()))
return gen
사용법 :
>>> gen_random (['a','b','c','d'],10,[100,300,400,200])
['d', 'b', 'b', 'a', 'c', 'c', 'b', 'c', 'c', 'c'] #<--- some of the time
random.choice()
? 적절한 발생 횟수로 마스터 목록을 작성하고 하나를 선택하십시오. 물론 이것은 중복 질문입니다.