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形曲线检测的主要内容,如果未能解决你的问题,请参考以下文章

使用 Python 将 sigmoid 函数(“S”形曲线)拟合到数据中

S型函数:Sigmoid 函数

HIT1946 希尔伯特分形曲线(dfs)

matlab 七段式轨迹 S型速度规划

求助:图像显著检测算法的PR曲线是怎么画出来的

将php数组值排序或显示为钟形曲线