我们如何在 Python 中拟合 sigmoid 函数?
Posted
技术标签:
【中文标题】我们如何在 Python 中拟合 sigmoid 函数?【英文标题】:How do we fit a sigmoid function in Python? 【发布时间】:2019-08-01 19:17:00 【问题描述】:出于可重复性的原因,我正在分享我正在使用的简单数据集here。
为了清楚我在做什么 - 从第 2 列开始,我正在读取当前行并将其与前一行的值进行比较。如果它更大,我会继续比较。如果当前值小于前一行的值,我想将当前值(较小)除以前一个值(较大)。因此,下面是我的源代码。
import numpy as np
import scipy.stats
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import beta
protocols =
types = "data_v": "data_v.csv"
for protname, fname in types.items():
col_time,col_window = np.loadtxt(fname,delimiter=',').T
trailing_window = col_window[:-1] # "past" values at a given index
leading_window = col_window[1:] # "current values at a given index
decreasing_inds = np.where(leading_window < trailing_window)[0]
quotient = leading_window[decreasing_inds]/trailing_window[decreasing_inds]
quotient_times = col_time[decreasing_inds]
protocols[protname] =
"col_time": col_time,
"col_window": col_window,
"quotient_times": quotient_times,
"quotient": quotient,
plt.figure(); plt.clf()
plt.plot(quotient_times, quotient, ".", label=protname, color="blue")
plt.ylim(0, 1.0001)
plt.title(protname)
plt.xlabel("quotient_times")
plt.ylabel("quotient")
plt.legend()
plt.show()
sns.distplot(quotient, hist=False, label=protname)
这给出了以下图。
从图中我们可以看出
当quotient_times
小于 3 时,Data-V 的商为 0.8,如果 quotient_times
为
大于 3。
我还使用以下代码将其安装到 beta 发行版中
xt = plt.xticks()[0]
xmin, xmax = min(xt), max(xt)
lnspc = np.linspace(xmin, xmax, len(quotient))
alpha,beta,loc,scale = stats.beta.fit(quotient)
pdf_beta = stats.beta.pdf(lnspc, alpha, beta,loc, scale)
plt.plot(lnspc, pdf_beta, label="Data-V", color="darkblue", alpha=0.9)
plt.xlabel('$quotient$')
#plt.ylabel(r'$p(x|\alpha,\beta)$')
plt.title('Beta Distribution')
plt.legend(loc="best", frameon=False)
我们如何将quotient
(如上定义)放入一个 sigmoid 函数中,以得到如下图?
【问题讨论】:
我向您推荐 lmfit 软件包。在那里你有一个简单的方法来实现你自己的拟合功能。 (希望我正确理解了您的问题)lmfit
用于 sigmoid 函数?我以前没有使用过它,但你可以尝试使用我共享的数据集吗,Richard?谢谢。
将数据集拟合到 sigmoid 与使用 sigmoid 分类器不同吗?您只需要提取参数。 Scikit learn 具有非常易于使用的 sigmoid 分类器。
我在 R 中做了一些非常相似的事情,如果我分享一下会有帮助吗?
@MedImage,谢谢,但我想要它在 Python 中。如果您可以分享您在 Python 中使用我分享的相同数据回答您的答案,那就太好了,我会将其标记为已接受的答案。
【参考方案1】:
您想匹配sigmoid
,或者实际上是logistic function。这可以通过多种方式进行更改,例如斜率、中点、幅度和偏移量。
这是定义 sigmoid
函数并利用 scipy.optimize.curve_fit
函数通过调整参数来最小化错误的代码。
from scipy.optimize import curve_fit
def sigmoid (x, A, h, slope, C):
return 1 / (1 + np.exp ((x - h) / slope)) * A + C
# Fits the function sigmoid with the x and y data
# Note, we are using the cumulative sum of your beta distribution!
p, _ = curve_fit(sigmoid, lnspc, pdf_beta.cumsum())
# Plots the data
plt.plot(lnspc, pdf_beta.cumsum(), label='original')
plt.plot(lnspc, sigmoid(lnspc, *p), label='sigmoid fit')
plt.legend()
# Show parameters for the fit
print(p)
这为您提供了以下情节:
以及下面的参数空间(对于上面用到的函数):
[-1.82910694e+01 4.88870236e-01 6.15103201e-03 1.82895890e+01]
如果要拟合变量 quotient_time
和 quotient
,只需更改变量即可。
...
p, _ = curve_fit(sigmoid, quotient_times, quotient)
...
并绘制它:
【讨论】:
我仍然不确定这是否是你真正“想要”的(科学上),但这就是你所要求的 ;-) 是的,这正是我所要求的,但你能用我共享的数据集试试吗? @Brown,这是你的数据集!这是 beta 分布的累积和。 真的吗?那么你在哪里传递数据的 beta 拟合呢?我可以喝咖啡吗:-D @Brown,它是pdf_beta.cumsum()
命令,pdf_beta
是您在示例代码中提供的。我现在还提供了quotient
和quotient_times
的匹配(作为你的第一个情节)。希望能帮助到你。而当数据如此异质分布时,拟合很可能不太好。以上是关于我们如何在 Python 中拟合 sigmoid 函数?的主要内容,如果未能解决你的问题,请参考以下文章