web-dev-qa-db-fra.com

Débordement dans exp dans scipy/numpy en Python?

Qu'est-ce que l'erreur suivante:

Warning: overflow encountered in exp

dans scipy/numpy en utilisant Python signifie généralement? Je calcule un ratio sous forme de log, c'est-à-dire log (a) + log (b), puis je prends l'exposant du résultat, en utilisant exp, et en utilisant une somme avec logsumexp, comme suit:

c = log(a) + log(b)
c = c - logsumexp(c)

certaines valeurs du tableau b sont volontairement définies sur 0. Leur journal sera -Inf.

Quelle pourrait être la cause de cet avertissement? Merci.

17
user248237dfsf

Dans votre cas, cela signifie que b est très petit quelque part dans votre tableau, et vous obtenez un nombre (a/b ou exp(log(a) - log(b))) trop grand pour le type de fichier (float32, float64, etc.) re utiliser pour stocker la sortie est. 

Numpy peut être configuré pour 

  1. Ignorer ces sortes d'erreurs, 
  2. Affiche l'erreur mais ne déclenche pas d'avertissement pour arrêter l'exécution (valeur par défaut)
  3. Enregistre l'erreur, 
  4. Émettre un avertissement
  5. Relever une erreur
  6. Appeler une fonction définie par l'utilisateur

Voir numpy.seterr pour contrôler comment il gère les sous/débordements, etc. dans des tableaux à virgule flottante.

25
Joe Kington

Lorsque vous devez faire face à des exponentielles, vous passez rapidement au flux supérieur/inférieur car la fonction se développe si rapidement. Les statistiques constituent un cas typique, où la somme des exponentielles d'amplitudes diverses est assez courante. Comme les nombres sont très gros/petits, on prend généralement le journal pour rester dans une plage "raisonnable", appelée domaine de journalisation:

exp(-a) + exp(-b) -> log(exp(-a) + exp(-b))

Des problèmes persistent quand même parce que exp (-a) sera toujours sous-alimenté. Par exemple, exp (-1000) est déjà inférieur au plus petit nombre que vous pouvez représenter sous forme de double. Donc par exemple:

log(exp(-1000) + exp(-1000))

donne -inf (log (0 + 0)), même si vous pouvez vous attendre à quelque chose comme -1000 à la main (-1000 + log (2)). La fonction logsumexp fait mieux, en extrayant le maximum du nombre défini et en le retirant du journal:

log(exp(a) + exp(b)) = m + log(exp(a-m) + exp(b-m))

Cela n'évite pas totalement les débordements (si a et b sont très différents par exemple), mais cela évite la plupart des problèmes de précision dans le résultat final

8
David Cournapeau

Je pense que vous pouvez utiliser cette méthode pour résoudre ce problème:

Normalisé

Je surmonte le problème avec cette méthode. Avant d’utiliser cette méthode, la précision que je classe est la suivante: 86%. Après avoir utilisé cette méthode, la précision de mon classement est la suivante: 96% !!! C’est génial!
premier:
Mise à l'échelle Min-Max

 Min-Max scaling

seconde:
Normalisation du Z-score

 Z-score standardization

Ce sont des méthodes courantes pour implémenter normalization.
J'utilise la première méthode. Et je le modifie. Le nombre maximum est divisé par 10. Donc, le nombre maximum de résultats est 10. Alors exp (-10) ne sera pas overflow!
J'espère que ma réponse vous aidera! (^_^)

3
intoo

exp(log(a) - log(b)) n'est-il pas identique à exp(log(a/b)), ce qui correspond à a/b?

>>> from math import exp, log
>>> exp(log(100) - log(10))
10.000000000000002
>>> exp(log(1000) - log(10))
99.999999999999957

2010-12-07: S'il en est ainsi "certaines valeurs du tableau b sont intentionnellement définies sur 0", vous divisez essentiellement par 0. Cela semble être un problème.

2
hughdbrown

Dans mon cas, cela était dû à de grandes valeurs dans les données. Je devais normaliser (diviser par 255, car mes données étaient liées à des images) pour réduire les valeurs.

0
sheikirfanbasha