J'écris un algorithme dans lequel, étant donné un modèle, je calcule les probabilités pour une liste d'ensembles de données, puis je dois normaliser (selon la probabilité) chacune des probabilités. Donc, quelque chose comme [0,00043, 0,00004, 0,00321] pourrait être converti en peut être comme [0,2, 0,03, 0,77].
Mon problème est que les probabilités du journal avec lesquelles je travaille sont assez petites (par exemple, dans l'espace journal, les valeurs sont comme -269647.432, -231444.981, etc.). Dans mon code C ++, lorsque j'essaye d'en ajouter deux (en prenant leur exposant) j'obtiens une réponse "Inf". J'ai essayé de les ajouter dans l'espace de journal (sommation / soustraction de journal) , mais je suis encore tombé sur le même problème.
Quelqu'un peut-il partager son opinion d'expert à ce sujet?
log1p
Réponses:
Soustrayez le logarithme maximum de tous les journaux. Jetez tous les résultats si négatifs qu'ils déborderont l'exponentielle. (Leurs probabilités sont, à toutes fins pratiques, nulles.)
En effet, si vous voulez une précision relative de (comme ϵ = 10 - d pour d chiffres de précision) et que vous avez n vraisemblances, jetez tout résultat inférieur au logarithme de ϵ / n . Ensuite, procédez comme d'habitude pour exponentiariser les valeurs résultantes et divisez chacune par la somme de toutes les exponentielles.ϵ ϵ=10−d d n ϵ/n
Les probabilités normalisées sont égales à , Cela fonctionne parce que le remplacement de tous les autrement sous- par zéro fait une erreur totale d'au plus alors que, parce que et tous les sont non négatifs, le dénominateur , d'où l' erreur relative totale due à la règle de remplacement zéro est strictement inférieure à , comme vous le souhaitez. i = 1 , 2 , … , n . α i ( n - 1 ) ϵ / n < ϵ α n = b λ n - λ n = b 0 = 1 α i A = ∑ j α j ≥ 1 ( ( n - 1αje/ ∑nj = 1αj i = 1 , 2 , … , n . αje ( n - 1 ) ϵ / n < ϵ αn= bλn- λn= b0= 1 αje A = ∑jαj≥ 1 ( ( n - 1 ) ϵ / n ) / A < ϵ
Pour éviter une trop grande erreur d'arrondi, calculez la somme en commençant par les plus petites valeurs de . Cela se fera automatiquement lorsque les sont d'abord triés dans l'ordre croissant. Ceci n'est pris en compte que pour les très grands .λ i nαje λje n
BTW, cette prescription suppose que la base des journaux est supérieure à . Pour les bases inférieures à , annulez d'abord tous les journaux et procédez comme si la base était égale à .b 1 1 / b1 b 1 1/b
Exemple
Soit trois valeurs avec des logarithmes (journaux naturels, par exemple) égaux à et Le dernier est le plus grand; la soustraire de chaque valeur donne et- 231444,981 , - 231444,699. - 38202,733 , - 0,282 , 0.−269647.432, −231444.981, −231444.699. −38202.733, −0.282, 0.
Supposons que vous souhaitiez une précision comparable aux doubles IEEE (environ 16 chiffres décimaux), de sorte que et . (Vous ne pouvez pas réellement atteindre cette précision, car n'est donné que pour trois chiffres significatifs, mais ce n'est pas grave: nous ne que des valeurs qui sont garanties de ne pas affecter le mieux la précision que vous voulez et la précision que vous avez réellement avoir.) Calculer = = La première des trois différences, est inférieure à cela, alors jetez-la, ne laissant que et Les donne n = 3 - 0,282 log ( ϵ / n ) log ( 10 - 16 ) - log ( 3 ) - 37,93997. - 38202,733 , - 0,282 0. exp ( - 0,282 ) = 0,754 exp ( 0 ) = 1 0 0,754 / ( 1 + 0,754 ) =ϵ=10−16 n=3 −0.282 log(ϵ/n) log(10−16)−log(3) −37.93997. −38202.733, −0.282 0. exp(−0.282)=0.754 et (bien sûr). Les valeurs normalisées sont - dans l'ordre - pour celle que vous avez jetée, et .exp(0)=1 0 1 / ( 1 + 0,754 ) = 0,5700.754/(1+0.754)=0.430 1/(1+0.754)=0.570
la source