我试图以指数方式拟合某些数据,但似乎无法强迫scipy.optimize.curve_fit
给我一个令人满意的结果。
我已经将我的代码归结为下面的示例,包括符合经验的手动拟合数据。
import matplotlib.pylab as plt
import numpy
import scipy.stats
x = [25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64]
y = [9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14,
14, 14, 15, 15, 16, 16, 17, 17, 18, 19, 20, 21, 22, 24, 25, 27, 30, 31,
32, 37, 37]
def fitting_function(x, a, b, c):
return a * numpy.exp(b * x) + c
plt.plot(x, y, 'o', label='Original data')
OptimalValues, Covariance = scipy.optimize.curve_fit(fitting_function, x, y)
plt.plot(x, fitting_function(x, *OptimalValues), '-',
label='Fitted Curve (%0.2e*e^%sx+%0.2e)' % (OptimalValues[0],
OptimalValues[1],
OptimalValues[2]))
ManualFit = [0.1 * numpy.exp(0.09 * i) + 8 for i in x]
plt.plot(x, ManualFit, '-', label='Manual Fit (%s*e^%sx+%s)' % (0.1, 0.09, 8))
plt.legend(loc='best')
plt.show()
根据Stack Overflow的其他答案,一个明显的解决方案是为curve_fit
提供合理的初始猜测。
如果我通过将以下行放在相关位置我的代码(第16和17行),解释器会抱怨ValueError
因为它以某种方式尝试将guess
广播到len(x)
或len(y0
(即操作数无法与形状(0)(40)一起广播。
guess = (0.1, 0.1, 10)
OptimalValues, Covariance = scipy.optimize.curve_fit(fitting_function, x, y,
p0=guess)
在这种情况下,如何让scipy.optimize.curve_fit
给我一个有意义的输出?
答案 0 :(得分:1)
将您的x
和y
列表转换为numpy
阵列,它会正常工作。我发现为了获得满意的效果,你需要包括你的初步猜测。所以,这段代码:
import matplotlib.pylab as plt
import numpy
import scipy.stats
x = numpy.array([25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64])
y = numpy.array([9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 14,
14, 14, 15, 15, 16, 16, 17, 17, 18, 19, 20, 21, 22, 24, 25, 27, 30, 31,
32, 37, 37])
def fitting_function(x, a, b, c):
return a * numpy.exp(b * x) + c
plt.plot(x, y, 'o', label='Original data')
guess =(0.1,0.1,10)
OptimalValues, Covariance = scipy.optimize.curve_fit(fitting_function, x, y,
p0=guess)
plt.plot(x, fitting_function(x, *OptimalValues), '-',
label='Fitted Curve (%0.2e*e^%sx+%0.2e)' % (OptimalValues[0],
OptimalValues[1],
OptimalValues[2]))
ManualFit = [0.1 * numpy.exp(0.09 * i) + 8 for i in x]
plt.plot(x, ManualFit, '-', label='Manual Fit (%s*e^%sx+%s)' % (0.1, 0.09, 8))
plt.legend(loc='best')
plt.show()
制作此情节: