Problema com a operação de ponto flutuante de precisão em C
Para um dos meus projetos de curso, comecei a implementar o "classificador Naive Bayesiano" em C. Meu projeto é implementar um aplicativo classificador de documentos (especialmente Spam) usando enormes dados de treinamento.
Agora, tenho problemas ao implementar o algoritmo devido às limitações no tipo de dados do C.
(Algoritmo que estou usando é dado aqui,http://en.wikipedia.org/wiki/Bayesian_spam_filtering )
DECLARAÇÃO DE PROBLEMA: O algoritmo envolve pegar cada palavra em um documento e calcular a probabilidade de ser uma palavra spam. Se p1, p2 p3 .... pn são probabilidades da palavra 1, 2, 3 ... n. A probabilidade de o documento ser spam ou não é calculada usando
Aqui, o valor da probabilidade pode ser muito facilmente em torno de 0,01. Portanto, mesmo se eu usar o tipo de dados "double", meu cálculo será descartado. Para confirmar isso, escrevi um código de exemplo fornecido abaixo.
#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;
}
Tentei Float, tipos de dados duplos e até longos duplos, mas ainda o mesmo problema.
Portanto, digamos que em um documento de 100 mil palavras que estou analisando, se apenas 162 palavras tiverem 1% de probabilidade de spam e as 99838 restantes forem palavras notoriamente spam, meu aplicativo continuará dizendo que não é um documento de spam devido a um erro de precisão (como o numerador é fácil) para ZERO) !!!.
É a primeira vez que encontro esse problema. Então, como exatamente esse problema deve ser resolvido?