sigmoid function in python

Tissuebox picture Tissuebox · Jun 9, 2017 · Viewed 7.8k times · Source

I am trying to understand why my sigmoid function when the input is 37, it output 1. the sigmoid function:

import math

def sigmoid(x):
    return 1 / (1 + math.e ** -x)

I am not good in math but I think there should never be a moment where the f(x) is equal to 1 right? maybe it is because the e constant isnt precise enough however my real problem is I want to map a number between 0 and 1 to what is x when f(x) is 0 and what x is when f(x) is 1. my map function:

def p5map(n, start1, stop1, start2, stop2):
    return ((float(n)-start1)/(stop1-start1))*(stop2-start2)+start2

so for exemple I want to do

p5map(y, 0, 1, -37, 37)

where the y would be f(x) in the sigmoid curve and -37 and 37 would be where f(x) is 0 and 1 respectively. using -37 and 37 would not work for me so what I am asking is why is it 37 and how can I fix that so it is between -1 and 1 for exemple

Answer

Rory Daulton picture Rory Daulton · Jun 10, 2017

You are working with regular floating point numbers, which can hold only 15 or 16 significant digits. When you evaluate math.e**-37 the result is

8.533047625744083e-17

When you add that to one, you may want to get

1.00000000000000008533047625744083

but the computer in effect removes all but the first 16 digits and gives

1.000000000000000

which is simply 1. In fact, adding 1e-16 to 1 just gives 1. You do get something other than one when you add 1e-15 but that is larger than what you are trying.

There are several ways to get what you want. One way is to use Python's decimal module, which adds many more significant digits to your numbers and calculations, and you can add as many as you want. Using decimal,

from decimal import Decimal
print(1 / (1 + Decimal(-37).exp()))

you get

Decimal('0.9999999999999999146695237430')

and the resulting sigmoid function 1/(1+D(37).exp()) for -37 gives

Decimal('8.533047625744065066149031992E-17')

which is not zero.

Another solution is to use another sigmoid function, different from the one you use, that approaches 1 more slowly than yours does. One that approaches 1 slowly is

0.5 * (1 + x / (1 + abs(x)))

Doing that to 37 yields

0.986842105263158

which is far from 1, and the result for -37 is

0.01315789473684209

Choose your desired solution.