Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的非线性最小二乘拟合(二维)_Python_Numpy_Optimization_Scipy_Linear Algebra - Fatal编程技术网

Python中的非线性最小二乘拟合(二维)

Python中的非线性最小二乘拟合(二维),python,numpy,optimization,scipy,linear-algebra,Python,Numpy,Optimization,Scipy,Linear Algebra,我想知道在python中,将数据点拟合到非线性函数的正确方法应该是什么 我正在尝试拟合一系列数据点 t = [0., 0.5, 1., 1.5, ...., 4.] y = [6.3, 4.5,.................] 使用以下模型函数 f(t, x) = x1*e^(x2*t) 我主要想知道哪个库例程适合这个问题,以及应该如何设置它。我尝试使用以下方法,但未成功: t_data = np.array([0.5, 1.0, 1.5, 2.0,........]) y_data =

我想知道在python中,将数据点拟合到非线性函数的正确方法应该是什么

我正在尝试拟合一系列数据点

t = [0., 0.5, 1., 1.5, ...., 4.]
y = [6.3, 4.5,.................]
使用以下模型函数

f(t, x) = x1*e^(x2*t)
我主要想知道哪个库例程适合这个问题,以及应该如何设置它。我尝试使用以下方法,但未成功:

t_data = np.array([0.5, 1.0, 1.5, 2.0,........])
y_data = np.array([6.8, 3., 1.5, 0.75........])

def func_nl_lsq(x, t, y):
    return [x[0]*np.exp(x[1]*t)] -  y

popt, pcov = scipy.optimize.curve_fit(func_nl_lsq, t_data, y_data)
我知道这是不成功的,因为我能够解决“等效”线性最小二乘问题(简单地通过获取模型函数的对数来获得),而它的答案甚至不接近我通过上述方法得到的答案


谢谢

scipy.otimize。曲线拟合
可用于拟合数据。我觉得你就是用得不好。我假设您有一个给定的
t
y
,并尝试拟合形式为
x1*exp(x2*t)=y的函数

你需要

ydata = f(xdata, *params) + eps
这意味着您的函数定义不正确。您的函数应该看起来像

def func_nl_lsq(t, x1, x2):
    return x1*np.exp(x2*t)
取决于你真正想要的。这里x1和x2是拟合参数。这也是可能的

def func_nl_lsq(t, x):
    return x[0]*np.exp(x[1]*t)

但您可能需要提供一个初始猜测p0。

scipy.otimize.curve\u fit
可用于拟合数据。我觉得你就是用得不好。我假设您有一个给定的
t
y
,并尝试拟合形式为
x1*exp(x2*t)=y的函数

你需要

ydata = f(xdata, *params) + eps
这意味着您的函数定义不正确。您的函数应该看起来像

def func_nl_lsq(t, x1, x2):
    return x1*np.exp(x2*t)
取决于你真正想要的。这里x1和x2是拟合参数。这也是可能的

def func_nl_lsq(t, x):
    return x[0]*np.exp(x[1]*t)

但是您可能需要提供一个初始猜测p0。

如果您使用的是
曲线拟合
,则可以将其简化很多,而无需计算函数内部的错误:

from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt

t_data = np.array([0.5, 1.0, 1.5, 2.0, 2.5, 3.])
y_data = np.array([6.8, 3., 1.5, 0.75, 0.25, 0.1])
def func_nl_lsq(t, *args):
    a, b = args
    return a*np.exp(b*t)
popt, pcov = curve_fit(func_nl_lsq, t_data, y_data, p0=[1, 1])
plt.plot(t_data, y_data, 'o')
plt.plot(t_data, func_nl_lsq(t_data, *popt), '-')
plt.show()
编辑 注意:我使用的是接受
*args
的常规签名。为了使其工作,您必须将
p0
传递到
曲线拟合

t_data = np.array([0.5, 1.0, 1.5, 2.0])
y_data = np.array([6.8, 3., 1.5, 0.75])

def func_nl_lsq(x, t=t_data, y=y_data):
    return x[0]*np.exp(x[1]*t) -  y
    # removed one level of []'s

scipy.optimize.least_squares(func_nl_lsq, [0, 0])
传统方法如下所示:

def func_nl_lsq(t, a, b):
        return a*np.exp(b*t)
    popt, pcov = curve_fit(func_nl_lsq, t_data, y_data)
    a, b = popt
    plt.plot(t_data, func_nl_lsq(t_data, a, b), '-')

如果您使用的是
曲线拟合
,则无需计算函数内部的错误,您可以将其简化很多:

from scipy.optimize import curve_fit
import numpy as np
import matplotlib.pyplot as plt

t_data = np.array([0.5, 1.0, 1.5, 2.0, 2.5, 3.])
y_data = np.array([6.8, 3., 1.5, 0.75, 0.25, 0.1])
def func_nl_lsq(t, *args):
    a, b = args
    return a*np.exp(b*t)
popt, pcov = curve_fit(func_nl_lsq, t_data, y_data, p0=[1, 1])
plt.plot(t_data, y_data, 'o')
plt.plot(t_data, func_nl_lsq(t_data, *popt), '-')
plt.show()
编辑 注意:我使用的是接受
*args
的常规签名。为了使其工作,您必须将
p0
传递到
曲线拟合

t_data = np.array([0.5, 1.0, 1.5, 2.0])
y_data = np.array([6.8, 3., 1.5, 0.75])

def func_nl_lsq(x, t=t_data, y=y_data):
    return x[0]*np.exp(x[1]*t) -  y
    # removed one level of []'s

scipy.optimize.least_squares(func_nl_lsq, [0, 0])
传统方法如下所示:

def func_nl_lsq(t, a, b):
        return a*np.exp(b*t)
    popt, pcov = curve_fit(func_nl_lsq, t_data, y_data)
    a, b = popt
    plt.plot(t_data, func_nl_lsq(t_data, a, b), '-')

首先,您使用了错误的功能。您的函数
func_nl_lsq
计算残差,它不是模型函数。要使用
scipy.otimize.curve_fit
,您必须定义模型函数,正如@DerWeh和@saullo_castro的回答所建议的那样。您仍然可以使用自定义残差函数作为
scipy.optimize.least\u squares
而不是
scipy.optimize.curve\u fit

t_data = np.array([0.5, 1.0, 1.5, 2.0])
y_data = np.array([6.8, 3., 1.5, 0.75])

def func_nl_lsq(x, t=t_data, y=y_data):
    return x[0]*np.exp(x[1]*t) -  y
    # removed one level of []'s

scipy.optimize.least_squares(func_nl_lsq, [0, 0])

另外,请注意,@MadPhysicast的评论是正确的:您正在考虑的两个问题(初始问题和模型函数在对数下的问题)彼此不等价。请注意,如果将对数应用于模型函数,也将对数应用于残差,残差平方和现在表示不同的含义。这会导致不同的优化问题和不同的结果。

首先,您使用了错误的函数。您的函数
func_nl_lsq
计算残差,它不是模型函数。要使用
scipy.otimize.curve_fit
,您必须定义模型函数,正如@DerWeh和@saullo_castro的回答所建议的那样。您仍然可以使用自定义残差函数作为
scipy.optimize.least\u squares
而不是
scipy.optimize.curve\u fit

t_data = np.array([0.5, 1.0, 1.5, 2.0])
y_data = np.array([6.8, 3., 1.5, 0.75])

def func_nl_lsq(x, t=t_data, y=y_data):
    return x[0]*np.exp(x[1]*t) -  y
    # removed one level of []'s

scipy.optimize.least_squares(func_nl_lsq, [0, 0])

另外,请注意,@MadPhysicast的评论是正确的:您正在考虑的两个问题(初始问题和模型函数在对数下的问题)彼此不等价。请注意,如果将对数应用于模型函数,也将对数应用于残差,残差平方和现在表示不同的含义。这会导致不同的优化问题和不同的结果。

通常,模型日志的拟合不会与模型的拟合相匹配,因为日志版本的拟合实际上会为y值较小的点分配更多的相对权重。通常,模型日志的拟合不会与模型的拟合相匹配,因为日志版本的拟合实际上会为具有较小y值的点分配更多的相对权重。这似乎是一个伟大而简洁的解决方案!如果使用相同的精确代码,我会得到以下结果:
ValueError:无法确定拟合参数的数量。
曲线拟合
调用中。知道为什么吗?@user3501476当然。。我使用的是传递
*args
的一般方法,而不是
a,b
。为了使用这种方法,
曲线拟合
需要接收具有所需未知数数量的
p0
。我已经编辑了答案(我在这里用更新的代码创建了曲线),这似乎是一个伟大而简洁的解决方案!如果使用相同的精确代码,我会得到以下结果:
ValueError:无法确定拟合参数的数量。
曲线拟合
调用中。知道为什么吗?@user3501476当然。。我使用的是传递
*args
的一般方法,而不是
a,b
。为了使用这种方法,
曲线拟合
需要接收具有所需未知数数量的
p0
。我已经编辑了答案(我在这里用更新的代码创建了曲线)