S形曲线检测
Posted
技术标签:
【中文标题】S形曲线检测【英文标题】:Sigmoid curve detection 【发布时间】:2021-12-26 13:23:45 【问题描述】:我有表示曲线的表格数据集,每条曲线由 42 个值(数据点)表示,目标是过滤掉不遵循 Sigmoid 函数的曲线。
应用技术
-
S 形曲线拟合
计算曲线的优度
曲线拟合 source
from scipy.optimize import curve_fit
def sigmoid(x, L=max(y), x0=21, k=0.6, b=5):
y = L / (1 + np.exp(-k*(x-x0)))+b
return (y)
p0 = [max(y), np.median(x),1,min(y)]
popt, pcov = curve_fit(sigmoid, x, y, p0, method='dogbox', maxfev=10000)
绘图
yd = sigmoid(x, *popt)
plt.plot(x, y, 'o', label='data')
plt.plot(x,yd, label='fit')
plt.legend(loc='best')
plt.show()
r2_score(y, yd)
= 0.99
但即使曲线不是 sigmoid,cuve 也非常适合,我得到曲线的适应度 r2_score(y, yd)
= 0.98
示例数据
**Sigmoid**
[154.02811505496447,
146.39766673379745,
130.55841841263054,
105.90461009146338,
66.8461297702961,
22.543803049129565,
-13.688227352037302,
-31.754967769204086,
-36.574590925571556,
-34.31173263297842,
-27.98295459843348,
-17.624496325705877,
-2.2469180569519267,
20.740420258644008,
54.053534582814336,
104.15375611806758,
180.67655429725164,
299.0412892474392,
473.8589268806131,
712.1355324045853,
1010.3945120433141,
1353.3417600831544,
1722.423136626168,
2095.8689925500385,
2453.614570050715,
2779.492987742925,
3064.6579177888016,
3304.9067183437182,
3500.629595471177,
3654.4640620149517,
3773.8156617564973,
3866.2930060208614,
3937.098925829344,
3990.995709651212,
4032.976381384583,
4066.19200350293,
4094.2713932805746,
4117.570526667072,
4137.0863623072,
4154.089487119825,
4169.671081872018,
4185.233572233441]
Non sigmoid
[489.2834973631293,
361.00794898560935,
263.98040060808944,
176.09045223057,
110.87762385304995,
63.42773947552996,
42.065867898009856,
29.47418768048965,
23.254148294970037,
17.262475347849886,
13.390803854810201,
5.18880594026632,
-4.0552569677629435,
-9.77379815878885,
-15.39564800511198,
-17.0930552390937,
-22.386235681666676,
-24.01368224348971,
-27.6271366708811,
-28.704645895235444,
-26.672167652096505,
-20.310502874851863,
-17.661003297287152,
-15.088099452837014,
-15.872947794945503,
-8.34466572098927,
-1.6253080011324528,
6.594890931118698,
10.953473235028014,
14.039900455748466,
17.299573334162687,
16.739464327477435,
16.650048075311133,
13.090813997028818,
12.731754904427362,
12.118767243738603,
12.095028866568555,
11.33835463248488,
5.952943083721948,
-0.7048030993591965,
-9.088792078874576,
-15.823553268803153]
相关工作
Link1
Link2
Link3
Link4
【问题讨论】:
你试过普通最小二乘法吗? 问题是,您绘制的第二条曲线非常适合在 y 轴上反映的 sigma 曲线的尾端。数学表现完全符合预期。您可能需要在 k 上添加一个额外的约束(非负数,超出我的想象),或者考虑其他启发式方法,例如查看范围的两个边界处的梯度。 【参考方案1】:问题是您使用了无限参数。例如,如果您允许 L 为负数,您可以用您的函数拟合一个单调递减的数据集。
如果我添加简单的非负性界限,我会得到:
def sigmoid(x, L=max(y), x0=21, k=0.6, b=5):
y = L / (1 + np.exp(-k*(x-x0)))+b
return (y)
p0 = [max(y), np.median(x), 1, 0]
popt, pcov = curve_fit(sigmoid, x, y, p0, method='dogbox', maxfev=10000, bounds=(0, np.inf))
乙状结肠:
非 sigmoid:
您可以使用边界来更好地将拟合限制在允许的形状范围内。
【讨论】:
以上是关于S形曲线检测的主要内容,如果未能解决你的问题,请参考以下文章