为什么scipy.optimize.curve_fit不能正确匹配数据?

时间:2022-10-26 21:24:11

I've been trying to fit a function to some data for a while using scipy.optimize.curve_fit but I have real difficulty. I really can't see any reason why this wouldn't work.

我一直在尝试使用scipy.optimize.curve_fit将函数拟合到某些数据,但我确实遇到了困难。我真的看不出有什么理由不起作用。

# encoding: utf-8
from __future__ import (print_function,
                        division,
                        unicode_literals,
                        absolute_import,
                        with_statement)
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as mpl

x, y, e_y = np.loadtxt('data.txt', unpack=True)

def f(x, a, k):
    return (1/(np.sqrt(1 + a*((k-x)**2))))

popt, pcov = curve_fit(f, x, y, maxfev = 100000000)

mpl.plot(x, f(x, *popt), 'r-', label='Fit')
mpl.plot(x, y, 'rx', label='Original')
mpl.legend(loc='best')
mpl.savefig('curve.pdf')
print(popt)

# correct values which should be calculated
# a=0.003097
# k=35.4

Here is the plot-image which is produced by upper code: 为什么scipy.optimize.curve_fit不能正确匹配数据?

这是由上层代码生成的情节图像:

data.txt:
#x      y       e_y
4.4     0.79    0.13
19.7    4.9     0.8
23.5    7.3     1.2
29.7    17      2.79
30.7    21.5    3.52
34      81      13.28
34.6    145     23.77
35.4    610     100
36.3    115     18.85
38.1    38      6.23
43.7    14      2.3
56.2    6.2     1.02
64.7    4.6     0.75
79.9    3.2     0.52
210     0.98    0.16

2 个解决方案

#1


13  

Firstly try not to increase maxfev so large, this is usually a sign something else is going wrong! Playing around I can get a fit by the following addition:

首先尽量不要将maxfev增加到如此之大,这通常是其他出错的标志!玩耍我可以通过以下添加来获得合适:

def f(x, b, a, k):
    return (b/(np.sqrt(1 + a*((k-x)**2))))

popt, pcov = curve_fit(f, x, y, p0=[20, 600.0, 35.0])

Firstly give the fitting function you have given has a maximum of 1, since the peak in your data is 600, it will never fit. So I added an overall factor b. Secondly , try to help poor old curve_fit out. If by eye you can see it peaks at x~35 then tell it through the p0. This requires some intuition as to how the function works but is very important if your going to use a curve fitting function.

首先给出你给出的拟合函数最多为1,因为数据中的峰值是600,它永远不适合。所以我添加了一个整体因子b。其次,尝试帮助穷人的旧曲线。如果用眼睛你可以看到它在x~35处达到峰值,然后通过p0告诉它。这需要一些关于函数如何工作的直觉,但如果你要使用曲线拟合函数则非常重要。

为什么scipy.optimize.curve_fit不能正确匹配数据?

#2


1  

I looked at the raw data on an X-Y scatterplot, an equation to fit this data appears to require a very sharp, narrow peak. The equation you have been given will not yield a peak response. In my opinion, a fit of this data to the given equation won't work for this reason.

我查看了X-Y散点图上的原始数据,拟合此数据的等式似乎需要非常尖锐,窄的峰值。您给出的等式不会产生峰值响应。在我看来,由于这个原因,这些数据与给定方程的拟合将不起作用。

#1


13  

Firstly try not to increase maxfev so large, this is usually a sign something else is going wrong! Playing around I can get a fit by the following addition:

首先尽量不要将maxfev增加到如此之大,这通常是其他出错的标志!玩耍我可以通过以下添加来获得合适:

def f(x, b, a, k):
    return (b/(np.sqrt(1 + a*((k-x)**2))))

popt, pcov = curve_fit(f, x, y, p0=[20, 600.0, 35.0])

Firstly give the fitting function you have given has a maximum of 1, since the peak in your data is 600, it will never fit. So I added an overall factor b. Secondly , try to help poor old curve_fit out. If by eye you can see it peaks at x~35 then tell it through the p0. This requires some intuition as to how the function works but is very important if your going to use a curve fitting function.

首先给出你给出的拟合函数最多为1,因为数据中的峰值是600,它永远不适合。所以我添加了一个整体因子b。其次,尝试帮助穷人的旧曲线。如果用眼睛你可以看到它在x~35处达到峰值,然后通过p0告诉它。这需要一些关于函数如何工作的直觉,但如果你要使用曲线拟合函数则非常重要。

为什么scipy.optimize.curve_fit不能正确匹配数据?

#2


1  

I looked at the raw data on an X-Y scatterplot, an equation to fit this data appears to require a very sharp, narrow peak. The equation you have been given will not yield a peak response. In my opinion, a fit of this data to the given equation won't work for this reason.

我查看了X-Y散点图上的原始数据,拟合此数据的等式似乎需要非常尖锐,窄的峰值。您给出的等式不会产生峰值响应。在我看来,由于这个原因,这些数据与给定方程的拟合将不起作用。