2010-06-08 3 views
4

다음 코드에서 흥미로운 버그를 수정했습니다. 그러나 최선의 방법을 택한 것이 확실하지 않습니다.숫자가 너무 작아 져서 0이 될 수있는 숫자를 처리하는 방법

결과가 정확히 할 필요가 없기 때문에
p = 1 
probabilities = [ ... ] # a (possibly) long list of numbers between 0 and 1 
for wp in probabilities: 

    if (wp > 0): 
    p *= wp 

# Take the natural log, this crashes when 'probabilites' is long enough that p ends up 
# being zero 
try: 
    result = math.log(p) 

, 나는 단순히 작은 아닌 값을 유지, p는 이제까지 0

p = 1 
probabilities = [ ... ] # a long list of numbers between 0 and 1 
for wp in probabilities: 

    if (wp > 0): 
    old_p = p 
    p *= wp 
    if p == 0: 
     # we've gotten so small, its just 0, so go back to the smallest 
     # non-zero we had 
     p = old_p 
     break 

# Take the natural log, this crashes when 'probabilites' is long enough that p ends up 
# being zero 
try: 
    result = math.log(p) 

이되는 경우가 작동을 사용하여이 문제를 해결하지만 보인다 나에게 약간의 kludgy. 나는이 종류의 수치 프로그래밍을하지 않으며, 이것이 사람들이 사용하는 수정인지, 아니면 내가 더 잘할 수있는 것이 있는지 확실하지 않습니다.

답변

9

math.log(a * b)math.log(a) + math.log(b)과 같으므로 probabilities 배열의 모든 구성원의 로그 합계를 사용하지 않으시겠습니까?

이렇게하면 p이 너무 작아 져서 문제가되는 것을 피할 수 있습니다.

편집 :

import numpy 
prob = numpy.array([0.1, 0.213, 0.001, 0.98 ... ]) 
result = sum(numpy.log(prob)) 
+0

천재 : 이것은 NumPy와 버전, 대용량 데이터 세트에 대한 훨씬 빨리 깨끗하고 있습니다! 나는 프로그래머 모자를 제거하고 수학자 모자를 써야한다는 것을 알고 있었다. :-) –

관련 문제