Supposons que j'ai une fonction telle que:
f <- function(x){
exp(x) / (1 + exp(x))
}
il est censé fonctionner pour toute valeur réelle de x, mais en fait, il renvoie NaN lorsque x est 710 ou plus. Je me demande quelle est la bonne façon de gérer ce problème. Je me rends compte qu'il est facile de le faire simplement renvoyer 1, mais ce n'est peut-être pas un bon comportement du point de vue d'un statisticien. Quelqu'un a-t-il des commentaires ou des suggestions?
Réponses:
Dans ce cas, le
NaN
(pas un nombre) est renvoyé car le calcul des débordements exponentiels en arithmétique double précision.Une expression algébriquement équivalente, développée dans une série MacLaurin autour de , est0
Comme il s'agit d'une série alternée, l'erreur commise lors de la suppression d'un terme n'est pas supérieure à la taille du terme suivant. Ainsi, lorsque , l'erreur n'est pas supérieure à rapport à la valeur réelle. C'est beaucoup plus précis que n'importe quel calcul statistique doit être, donc vous êtes bien en remplaçant la valeur de retour par dans cette situation.x>710 exp(−710)≈10−308≈2−1024 1
Fait intéressant,
R
ne produira pas deNaN
moment où l'exponentielle se déverse . Ainsi, vous pouvez simplement choisir la version la plus fiable du calcul, en fonction du signe dex
, comme dansCe problème apparaît dans presque toutes les plates-formes informatiques (je n'ai pas encore vu d'exception) et elles varient dans la façon dont elles gèrent les débordements et les débordements. Les exponentielles sont connues pour créer ce genre de problèmes, mais elles ne sont pas seules. Par conséquent, il ne suffit pas d'avoir une solution
R
: un bon statisticien comprend les principes de l'arithmétique informatique et sait comment les utiliser pour détecter et contourner les particularités de son environnement informatique.la source
D'autres ont déjà discuté des problèmes de calcul, je vais donc leur laisser cela. Puisque je suppose que vous travaillez avec R, je pensais que je soulignerais que le paquet de démarrage est livré avec sa propre fonction logit inverse à utiliser, qui est assez stable sur le plan des calculs:
require(boot) inv.logit(710)
semble évaluer à 1 comme souhaité.
la source
plogis(710)
le même résultat. (En effet,inv.logit
c'est juste un alias pourplogis
.)