使用曲线拟合拟合双曲函数和调和函数 [英] fitting hyperbolic and harmonic functions with curvefit

查看:46
本文介绍了使用曲线拟合拟合双曲函数和调和函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用曲线拟合函数时遇到问题.在这里,我有一个包含两个函数的代码.第一个是双曲函数.第二个是相同的,但有一个参数 = 1.我的问题是,用 curvefit 拟合第一个函数的结果可以正常工作,但第二个函数却没有.我有一个商业程序,可以分别为两者生成正确的解决方案.所以有可能找到第二个函数的解决方案(我上面提到的第一个函数的特殊情况)有没有人可以让我知道我做错了什么?谢谢!

I have a problem working with curvefit function. Here I have a code with two functions to work with. The first is an hyperbolic function. The second is the same but with one parameter = 1. My problem is that the result to fit the first function with curvefit works fine but with the second doesn´t. I have a commercial program that generates correct solutions for both respectively. So it is possible to find a solution for the second function (a particular case of the first one as I mentioned above) Is there someone that could give me an idea about what I am doing wrong ? Thanks !

这是要运行的代码:

def hypRegress(ptp,pir):

    xData = np.arange(len(ptp))
    yData = pir

    xData = np.array(xData, dtype=float)
    yData = np.array(yData, dtype= float)

    def funcHyp(x, qi, exp, di):
        return qi*(1+exp*di*x)**(-1/exp)

    def errfuncHyp(p):
        return funcHyp(xData, p[0], p[1], p[2]) - yData

    #print(xData.min(), xData.max())
    #print(yData.min(), yData.max())

    trialX = np.linspace(xData[0], xData[-1], 1000)



    # Fit an hyperbolic
    popt, pcov = optimize.curve_fit(funcHyp, xData, yData)
    print 'popt'
    #print(popt)
    yHYP = funcHyp(trialX, *popt)

    #optimization

    # initial values
    p1, success = optimize.leastsq(errfuncHyp, popt,maxfev=10000)
    print p1

    aaaa = funcHyp(trialX, *p1)

    plt.figure()
    plt.plot(xData, yData, 'r+', label='Data', marker='o')
    plt.plot(trialX, yHYP, 'r-',ls='--', label="Hyp Fit")
    plt.plot(trialX, aaaa, 'y', label = 'Optimized')
    plt.legend()
    plt.show(block=False)
    return p1


def harRegress(ptp,pir):

    xData = np.arange(len(ptp))
    yData = pir

    xData = np.array(xData, dtype=float)
    yData = np.array(yData, dtype=float)

    def funcHar(x, qi, di):
        return qi*(1+di*x)**(-1)

    def errfuncHar(p):
        return funcHar(xData, p[0], p[1]) - yData

    #print(xData.min(), xData.max())
    #print(yData.min(), yData.max())

    trialX = np.linspace(xData[0], xData[-1], 1000)



    # Fit an harmonic
    popt, pcov = optimize.curve_fit(funcHar, xData, yData)
    print 'popt'
    print(popt)
    yHAR = funcHar(trialX, *popt)

    #optimization

    # initial values
    p1, success = optimize.leastsq(errfuncHar, popt,maxfev=1000)
    print p1

    aaaa = funcHar(trialX, *p1)

    plt.figure()
    plt.plot(xData, yData, 'r+', label='Data', marker='o')
    plt.plot(trialX, yHAR, 'r-',ls='--', label="Har Fit")
    plt.plot(trialX, aaaa, 'y', label = 'Optimized')
    plt.legend()
    plt.show(block=False)
    return p1


ptp = ([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14])
pir = ([150,85,90,50,45,60,60,40,40,30,28,30,38,30,26])

hypRegress(ptp,pir)
harRegress(ptp,pir)

input('pause')

推荐答案

这是一个经典问题.curve_fit 算法从对要优化的参数的初始猜测开始,如果未提供,则只是所有参数.

It's a classic problem. The curve_fit algorithm starts from an initial guess for the arguments to be optimized, which, if not supplied, is simply all ones.

也就是说,当你打电话

popt, pcov = optimize.curve_fit(funcHar, xData, yData)

拟合例程的第一次尝试将是假设

the first attempt for the fitting routine will be to assume

funcHar(xData, qi=1, di=1)

如果您没有指定任何其他选项,则拟合将很差,这可以从参数估计值的较大差异中得到证明(检查 pcov 的对角线并将其与实际值进行比较)popt 中返回的值).

If you haven't specified any of the other options, the fit will be poor, as evidenced by the large variances of the parameter estimates (check the diagonal of pcov and compare it to the actual values returned in popt).

在许多情况下,这种情况可以通过提供智能猜测来解决.从您的 HAR 模型中,我收集到 x==0 周围的值与 qi 的大小相同.因此,您可以提供 p0 = (pir[0], 1) 的初始猜测,这将导致一个令人满意的解决方案.你也可以用

In many cases, the situation is solved by supplying an intelligent guess. From your HAR-model, I gather that the values around x==0 are the same in size as qi. So you could supply an initial guess of p0 = (pir[0], 1), which will already lead to a satisfying solution. You could also call it with

popt, pcov = optimize.curve_fit(funcHar, ptp, pir, p0=(0, 1))

导致相同的结果.所以问题只是算法找到了一个局部最小值.

which leads to the same result. So the problem is just that the algorithm finds a local minimum.

另一种方法是提供不同的因子,即确定初始步长界限的参数":

An alternative would've been to supply a different factor, the "parameter determining the initial step bound":

popt, pcov = optimize.curve_fit(funcHar, ptp, pir, p0=(1, 1), factor=1)

在这种情况下,即使使用 p0=(1,1) 的(默认)初始猜测,它也会给出相同的结果拟合.

In this case, even with the (default) initial guess of p0=(1,1), it gives the same resulting fit.

请记住:试穿是一门艺术,而不是一门科学.很多时候,通过分析您想要拟合的模型,您已经可以提供一个很好的初始猜测.

Remember: fitting is an art, not a science. Often times, by analyzing the model you want to fit, you could already supply a good initial guess.

我不能说商业程序中使用的算法.如果它是开源的(不太可能),你可以看看他们做了什么.

I can't speak for the algorithm used in the commercial program. If it is open-source (unlikely), you could have a look to see what they do.

这篇关于使用曲线拟合拟合双曲函数和调和函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆