2010-09-13 1 views
21

У меня есть байесовский классификатор, запрограммированный в Python, проблема в том, что когда я умножаю вероятности функций, я получаю ОЧЕНЬ маленькие значения float, такие как 2.5e-320 или что-то в этом роде, и вдруг это превращается в 0.0. 0.0, очевидно, бесполезно для меня, так как я должен найти «лучший» класс, на основе которого класс возвращает значение MAX (большее значение).В Python небольшие поплавки, стремящиеся к нулю

Что было бы лучшим способом справиться с этим? Я подумал о том, чтобы найти экспоненциальную часть числа (-320) и, если она идет слишком низко, умножая значение на 1e20 или некоторое значение, подобное этому. Но может быть, есть лучший способ?

+23

Это не математика. В математике положительные числа могут быть сколь угодно малыми. Это плавающая точка. – recursive

+6

@S. Lott Это определенно не математический вопрос на любом участке. Это имеет все, что связано с числами с плавающей запятой, и тем, как они работают на Python, а также на других языках программирования. –

+12

Я считаю, что 2.5e-320 - это точная вероятность того, что кит внезапно превратится в чашу петуний. – Seth

ответ

22

То, что вы описываете, является стандартной проблемой с наивным классификатором Байеса. Вы можете найти нижний поток с этим, чтобы найти ответ. или см. here.

Короткий ответ - это стандартно выразить все это с точки зрения логарифмов. Поэтому вместо того, чтобы умножать вероятности, вы суммируете их логарифмы.

Возможно, вы захотите посмотреть и на другие алгоритмы классификации.

+0

Эй! Большое спасибо за ответ, я буду смотреть на это, поскольку он точно решает мою проблему. Я думал, что это должно быть обычным явлением, так как я умножаю вероятности, например, 3.14e-05 несколько раз, поэтому они достигают уровней e-300 (например) довольно быстро, даже больше, когда у меня есть много функций в моем классификаторе. – Pravel

+0

Да, как рекурсивно упоминалось, это решается с помощью логарифмов и добавления вероятностей. В ссылке, предоставленной Мухаммадом, все объясняется. Спасибо всем за ваши ответы! – Pravel

3

Посмотрите на Decimal от stdlib.

from decimal import Decimal, getcontext 

getcontext().prec = 320 

Decimal(1)/Decimal(7) 

Я не размещаю результаты здесь, так как он довольно длинный.

7

Floating point номера не имеют бесконечной точности, поэтому вы видели, что числа обращаются к 0. Не могли бы вы умножить все вероятности на большой скаляр, чтобы ваши номера оставались в более высоком диапазоне? Если вас беспокоит только макс, а не величина, вам даже не нужно беспокоиться о том, чтобы пробиться в конце. В качестве альтернативы вы можете использовать бесконечную десятичную дециметрию, как предлагает иканобори.

17

Возможно ли выполнить вашу работу в логарифмическом пространстве? (Например, вместо хранения 1e-320 просто сохраните -320 и используйте дополнение вместо умножения)

+0

Эй! Ваше решение кажется отличным. Это очень просто и очень легко попробовать. Благодаря! Я попробую. – Pravel

Смежные вопросы