Для одного из моих курсовых проектов я начал реализацию «Наивного байесовского классификатора» на C. Мой проект заключается в реализации приложения классификатора документов (особенно спама) с использованием огромных обучающих данных.
Теперь у меня проблема с реализацией алгоритма из-за ограничений в типе данных Си.
(алгоритм, который я использую, приведен здесь, http://en.wikipedia.org/wiki/Bayesian_spam_filtering)
ПОСТАНОВКА ЗАДАЧИ:
Алгоритм включает взятие каждого слова в документе и вычисление вероятности того, что это слово является спамом. Если p1, p2 p3 .... pn - вероятности слова -1, 2, 3 ... n. Вероятность того, что документ является спамом или нет, рассчитывается с использованием
Здесь значение вероятности может быть очень легко около 0,01. Таким образом, даже если я использую тип данных "double", мой расчет пойдет на бросок. Чтобы подтвердить это, я написал пример кода, приведенного ниже.
#define PROBABILITY_OF_UNLIKELY_SPAM_WORD (0.01)
#define PROBABILITY_OF_MOSTLY_SPAM_WORD (0.99)
int main()
{
int index;
long double numerator = 1.0;
long double denom1 = 1.0, denom2 = 1.0;
long double doc_spam_prob;
/* Simulating FEW unlikely spam words */
for(index = 0; index < 162; index++)
{
numerator = numerator*(long double)PROBABILITY_OF_UNLIKELY_SPAM_WORD;
denom2 = denom2*(long double)PROBABILITY_OF_UNLIKELY_SPAM_WORD;
denom1 = denom1*(long double)(1 - PROBABILITY_OF_UNLIKELY_SPAM_WORD);
}
/* Simulating lot of mostly definite spam words */
for (index = 0; index < 1000; index++)
{
numerator = numerator*(long double)PROBABILITY_OF_MOSTLY_SPAM_WORD;
denom2 = denom2*(long double)PROBABILITY_OF_MOSTLY_SPAM_WORD;
denom1 = denom1*(long double)(1- PROBABILITY_OF_MOSTLY_SPAM_WORD);
}
doc_spam_prob= (numerator/(denom1+denom2));
return 0;
}
Я пробовал Float, double и даже long double типы данных, но все еще та же проблема.
Следовательно, скажем, в анализируемом документе из 100 тыс. Слов, если только 162 слова имеют вероятность спама в 1%, а оставшиеся 99838 являются явно спам-словами, то мое приложение все равно будет называть его «Не спам-документ» из-за ошибки точности (как нумератор легко уходит в НОЛЬ) !!!.
Я впервые сталкиваюсь с такой проблемой. Так как именно решить эту проблему?