我想将函数f(x) = b + a / x
放到我的数据集中。为此我发现优化的scipy leastsquares
是合适的。
我的代码如下:
x = np.asarray(range(20,401,20))
y
是我计算的距离,但是是一个长度为20的数组,这里只是随机数,例如
y = np.random.rand(20)
对参数a和b的初步猜测:
params = np.array([1,1])
最小化的功能
def funcinv(x):
return params[0]/x+params[1]
res = least_squares(funinv, params, args=(x, y))
给出错误:
return np.atleast_1d(fun(x, *args, **kwargs))
TypeError:funinv()占用1个位置参数但是3个被赋予
我如何适合我的数据?
答案 0 :(得分:2)
要做一点清晰。有两个相关的问题:
使模型适合观察到的数据是找到模型的这些参数,这些参数最小化模型数据和观测数据之间的某种错误。
least_squares
方法只是最小化关于x
的后续函数(x
可以是向量)。
F(x)= 0.5 *总和(rho(f_i(x)** 2),i = 0,...,m - 1)
(rho
是一种损失函数,默认为rho(x) = x
,所以暂时不要介意)
least_squares(func, x0)
预计对func(x)
的调用将返回一个向量[a1, a2, a3, ...]
,其中将计算平方和:S = 0.5 * (a1^2 + a2^2 + a3^2 + ...)
。
least_squares
将调整x0
以最小化S
。
因此,为了使用它来使模型适合数据,必须在模型和实际数据之间构建误差函数 - 残差然后最小化残差功能。在您的情况下,您可以按如下方式编写它:
import numpy as np
from scipy.optimize import least_squares
x = np.asarray(range(20,401,20))
y = np.random.rand(20)
params = np.array([1,1])
def funcinv(x, a, b):
return b + a/x
def residuals(params, x, data):
# evaluates function given vector of params [a, b]
# and return residuals: (observed_data - model_data)
a, b = params
func_eval = funcinv(x, a, b)
return (data - func_eval)
res = least_squares(residuals, params, args=(x, y))
这给出了一个结果:
print(res)
...
message: '`gtol` termination condition is satisfied.'
nfev: 4
njev: 4 optimality: 5.6774618339971994e-10
status: 1
success: True
x: array([ 6.89518618, 0.37118815])
但是,由于残差函数始终基本相同(res = observed_data - model_data
),因此scipy.optimize
中有一个名为curve_fit
:curve_fit(func, xdata, ydata, x0)
的快捷方式。 curve_fit
自动构建残差函数,您只需编写:
import numpy as np
from scipy.optimize import curve_fit
x = np.asarray(range(20,401,20))
y = np.random.rand(20)
params = np.array([1,1])
def funcinv(x, a, b):
return b + a/x
res = curve_fit(funcinv, x, y, params)
print(res) # ... array([ 6.89518618, 0.37118815]), ...