曲线

时间:2018-04-21 19:21:39

标签: python

我正在尝试使用Python来将曲线拟合到一系列数据点,总结如下:

enter image description here

从下面看,似乎大于2的多项式是最合适的,其次是线性的,最后是指数的,这总体上是最差的结果。

虽然我很欣赏这可能不会呈指数级增长,但我只是想知道你是否会期望指数函数的表现如此糟糕(基本上x,b的系数已经设置为0并且已经选择了一个任意点要交叉的曲线)或者如果我在某些方面做错了我的代码以适应。

我使用的代码如下:

# Fitting
def exponenial_func(x,a,b,c):
    return a*np.exp(-b*x)+c

def linear(x,m,c):
    return m*x+c

def quadratic(x,a,b,c):
    return a*x**2 + b*x+c

def cubic(x,a,b,c,d):
    return a*x**3 + b*x**2 + c*x + d

x = np.array(x)
yZero = np.array(cancerSizeMean['levelZero'].values)[start:]

print len(x)
print len(yZero)

popt, pcov = curve_fit(exponenial_func,x, yZero, p0=(1,1,1))
expZeroFit = exponenial_func(x, *popt)
plt.plot(x, expZeroFit, label='Control, Exponential Fit')

popt, pcov = curve_fit(linear, x, yZero, p0=(1,1))
linearZeroFit = linear(x, *popt)
plt.plot(x, linearZeroFit, label = 'Control, Linear')

popt, pcov = curve_fit(quadratic, x, yZero, p0=(1,1,1))
quadraticZeroFit = quadratic(x, *popt)
plt.plot(x, quadraticZeroFit, label = 'Control, Quadratic')

popt, pcov = curve_fit(cubic, x, yZero, p0=(1,1,1,1))
cubicZeroFit = cubic(x, *popt)
plt.plot(x, cubicZeroFit, label = 'Control, Cubic')

*编辑:curve_fit是从scipy.optimize包中导入的

from scipy.optimize import curve_fit

2 个答案:

答案 0 :(得分:2)

如果你用像指数这样的函数给出一个糟糕的初始猜测,那么

curve_fit往往表现不佳,最终会产生非常大的数字。您可以尝试更改maxfev输入,以便运行更多迭代。否则,我建议尝试使用类似的东西:

p0=(1000,-.005,0)

- .01,因为它从300增加到500,你的eqn中有-b,100 0因为它在300时为~3000(从0增加1.5倍)。看看结果如何

至于为什么初始指数根本不起作用,你的初始猜测是b = 1,x在(300,1000)或范围的范围内。这意味着python正在计算exp(-300),它会抛出异常或设置为0.此时,无论b是增加还是减少,对于任何一般值附近的值,指数仍将设置为0初步估计。

基本上,python使用精度有限的数值方法,并且指数估计超出了它可以处理的值范围

答案 1 :(得分:0)

我不确定你是如何拟合曲线的 - 你使用多项式最小二乘法吗?在这种情况下,你会期望适应性随着每一个额外的灵活性而提高,你可以根据边际改善/外部理论的减少来选择权力。

改善适合度应该类似于this

我实际上写了一些代码来在python中为一个类做一个多项式最小二乘,which you can find here on Github。由于我只是用它来解决练习,所以它有点hacky并且松散地评论。希望它有用。

相关问题