如何使用SciPy的曲线拟合对某些点进行优先排序

问题描述 投票:0回答:1

我想对以下曲线建模:

enter image description here

[要执行它,我使用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)))

[当我第一次这样做时,我得到了:

enter image description here

将残差最小化,每个点的重要性相同。我想要的是得到一条曲线,该曲线对曲线的最后一个值(例如,从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)

在这种情况下,我得到的是我一直在寻找的东西:

enter image description here

看起来不错,但我正在寻找另一种方式,以便可以“控制”每个数据点,例如以线性方式或指数方式加权每个残差,或者甚至手动选择它(而不是像以前的情况那样通过相反的方法将它们全部选择)。

提前感谢

python scipy curve-fitting
1个回答
1
投票

首先,请注意,不需要三个系数。由于

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数组中每个点的值来控制每个点的优先级。比较两个结果给我:

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.