我想对以下曲线建模:
[要执行它,我使用SciPy的curve_fit,拟合指数函数。
def exponenial_func(x, a, b, c):
return a * b**(c*x)
popt, pcov = curve_fit(exponenial_func, x, y, p0=(1,2,2),
bounds=((0, 0, 0), (np.inf, np.inf, np.inf)))
[当我第一次这样做时,我得到了:
将残差最小化,每个点的重要性相同。我想要的是得到一条曲线,该曲线对曲线的最后一个值(例如,从x轴30开始)的重视程度要高于第一个值,因此它在曲线的末端比在起点处更合适它的。
我知道从这里有很多方法可以解决这个问题(首先,定义我想赋予每个残差的重要性)。我在这里的问题是要对如何解决这个问题有所了解。
我的一个想法是更改sigma值,以每个数据点的反值加权。
popt, pcov = curve_fit(exponenial_func, x, y, p0=(1,2,2),
bounds=((0, 0, 0), (np.inf, np.inf, np.inf)),
sigma=1/y)
在这种情况下,我得到的是我一直在寻找的东西:
看起来不错,但我正在寻找另一种方式,以便可以“控制”每个数据点,例如以线性方式或指数方式加权每个残差,或者甚至手动选择它(而不是像以前的情况那样通过相反的方法将它们全部选择)。
提前感谢
首先,请注意,不需要三个系数。由于
a * b**(c*x) = a * exp(log(b)*c*x).
我们可以定义k = log(b)*c
。
这里是关于如何使用scipy.optimize.least_squares和优先级向量来[[手动解决问题的建议:
import numpy as np
from scipy.optimize import least_squares
def exponenial_func2(x, a, k):
return a * np.exp(k*x)
# returns the vector of residuals
def fitwrapper2(coeffs, *args):
xdata, ydata, prio = args
return prio*(exponenial_func2(xdata, *coeffs)-ydata)
# Data
n = 31
xdata = np.arange(n)
ydata = np.array([155.0,229,322,453,655,888,1128,1694,
2036,2502,3089,3858,4636,5883,7375,
9172,10149,12462,12462,17660,21157,
24747,27980,31506,35713,41035,47021,
53578,59138,63927,69176])
# The priority vector
prio = np.ones(n)
prio[-1] = 5
res = least_squares(fitwrapper2, x0=[1.0,2.0], bounds=(0,np.inf), args=(xdata,ydata,prio))
prio[-1] = 5
,我们给最后一个点一个高的优先级。res.x
包含您的最佳系数。这里a, k = res.x
。prio = np.ones(n)
,这是正常的最小二乘拟合(如curve_fit一样),其中所有点都具有相同的priority
prio
数组中每个点的值来控制每个点的优先级。比较两个结果给我: