OiO.lk Community platform!

Oio.lk is an excellent forum for developers, providing a wide range of resources, discussions, and support for those in the developer community. Join oio.lk today to connect with like-minded professionals, share insights, and stay updated on the latest trends and technologies in the development field.
  You need to log in or register to access the solved answers to this problem.
  • You have reached the maximum number of guest views allowed
  • Please register below to remove this limitation

How can I create a custom sigmoid function?

  • Thread starter Thread starter cercio
  • Start date Start date
C

cercio

Guest
Dear Stackoverflow community, I am trying to build a custom sigmoid shaped function because I want to scale my data during preprocessing. Basically the goal is to obtain a sigmoid shaped function which outputs from 0 to 1 and only takes positive input values ( it approaches 0 as input approaches 0, and 1 if input approaches +infinity). The key point is that i want to be able to choose the inflection points of the 'S' shape at will. I have a little sketch here (forgive my paint skills)enter image description here.

The points i want to choose are marked as A and B and ideally they are somewhere midway through the curve that connects the linear part of the function to the asymptotes.

Here is how i did it so far, I tried to fit a classic logistic function to two points, here is the function :

Code:
def sigmoid(x,x0, k):
y = 1 / (1 + np.exp(-k * (x - x0)))
return y

and here the fit:

Code:
ydata = [0.1, 0.9]
xdata = [0.22, 1.34]
p0 = [np.median(xdata), 1]  # this is a mandatory initial guess
from scipy.optimize import curve_fit

popt, pcov = curve_fit(sigmoid, xdata, ydata, p0=p0, method='dogbox')

Here xdata corresponds to the A and B points on the x axis(which I want to be able to vary), and ydata are arbitrary points i want to map A and B to, in order to have them roughly at the inflection points of the S curve ( I dont know if there's a better way to do it perhaps)

Then, the plot

Code:
x = np.linspace(0, 5, 1000)
y = sigmoid(x,*popt)

plt.figure()
plt.plot(xdata, ydata, 'o', label='10th/90th percentiles')
plt.plot(x, y, label='sigmoid curve')
plt.ylim(0, 1.3)
plt.legend(loc='best')
plt.show()

yields the figure : (ignore the percentiles label in the legend, those are my A/b points) enter image description here

Which is not a great shape. Especially towards 0, the transition is not nearly as smooth and gradual. I would like to basically shift the function to the right, to have a smoother curve, while still intercepting my A,B points at the inflection points. Do you have any suggestions on how I would achieve that ? Adding a shift to the definition of the sigmoid function wouldnt work as the offset will just be overwritten by the curve fit Is there a smarter way to solve this problem instead of my approach which I cant see?
<p>Dear Stackoverflow community,
I am trying to build a custom sigmoid shaped function because I want to scale my data during preprocessing. Basically the goal is to obtain a sigmoid shaped function which outputs from 0 to 1 and only takes positive input values ( it approaches 0 as input approaches 0, and 1 if input approaches +infinity). The key point is that i want to be able to choose the inflection points of the 'S' shape at will. I have a little sketch here (forgive my paint skills)<a href="https://i.sstatic.net/xFlUqxEi.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/xFlUqxEi.png" alt="enter image description here" /></a>.</p>
<p>The points i want to choose are marked as A and B and ideally they are somewhere midway through the curve that connects the linear part of the function to the asymptotes.</p>
<p>Here is how i did it so far, I tried to fit a classic logistic function to two points, here is the function :</p>
<pre><code>def sigmoid(x,x0, k):
y = 1 / (1 + np.exp(-k * (x - x0)))
return y
</code></pre>
<p>and here the fit:</p>
<pre><code>ydata = [0.1, 0.9]
xdata = [0.22, 1.34]
p0 = [np.median(xdata), 1] # this is a mandatory initial guess
from scipy.optimize import curve_fit

popt, pcov = curve_fit(sigmoid, xdata, ydata, p0=p0, method='dogbox')
</code></pre>
<p>Here xdata corresponds to the A and B points on the x axis(which I want to be able to vary), and ydata are arbitrary points i want to map A and B to, in order to have them roughly at the inflection points of the S curve ( I dont know if there's a better way to do it perhaps)</p>
<p>Then, the plot</p>
<pre><code>x = np.linspace(0, 5, 1000)
y = sigmoid(x,*popt)

plt.figure()
plt.plot(xdata, ydata, 'o', label='10th/90th percentiles')
plt.plot(x, y, label='sigmoid curve')
plt.ylim(0, 1.3)
plt.legend(loc='best')
plt.show()
</code></pre>
<p>yields the figure : (ignore the percentiles label in the legend, those are my A/b points)
<a href="https://i.sstatic.net/65iZ56iB.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/65iZ56iB.png" alt="enter image description here" /></a></p>
<p>Which is not a great shape. Especially towards 0, the transition is not nearly as smooth and gradual. I would like to basically shift the function to the right, to have a smoother curve, while still intercepting my A,B points at the inflection points. Do you have any suggestions on how I would achieve that ? Adding a shift to the definition of the sigmoid function wouldnt work as the offset will just be overwritten by the curve fit Is there a smarter way to solve this problem instead of my approach which I cant see?</p>
 

Latest posts

I
Replies
0
Views
1
impact christian
I
Top