[英]Why does “scipy.optimize.minimize” gives me such a bad fit?
I have a function y(x,z)
with two variables x
, z
and 6 coefficients a
, b
, c
, d
, e
, f
. 我有一个函数
y(x,z)
具有两个变量x
, z
和6个系数a
, b
, c
, d
, e
, f
。 I have the data for x
, z
and let's say for testing purpose the data of the coefficients. 我有
x
, z
的数据,并假设出于测试目的,系数的数据。 With those datas I calculate my y
. 利用这些数据,我计算出
y
。
Then I want to fit the function with the datas of x
, z
and the calculated y
to get the coefficients and compare them with the testing purpose one. 然后,我想用
x
, z
和计算出的y
的数据拟合函数,以获取系数并将其与测试目的之一进行比较。
import numpy as np
from scipy.optimize import minimize
x = np.array([0,0.25,0.5,0.75,1]) # data of variable x
z = np.array([0,0.25,0.5,0.75,1]) # data of variable z
def func(pars,x,z): #my function
a,b,c,d,e,f = pars
return a*x**2+b*x+c+d*z+e*z*x+f*z*x**2
a = np.array([1,1,1,1,1]) #define coefficients to get the y data and compare them later with fit
b = np.array([0.5,0.5,0.5,0.5,0.5])
c = np.array([0.25,0.25,0.25,0.25,0.25])
d = np.array([1,1,1,1,1])
e = np.array([0.5,0.5,0.5,0.5,0.5])
f = np.array([0.25,0.25,0.25,0.25,0.25])
y = []
y.append(func((a,b,c,d,e,f),x,z)) #calculate the y data
print(y)
def resid(pars,x,z,y): #residual function
return ((func(pars,x,z) - y) ** 2).sum()
pars0 = np.array([0,0,0,0,0,0])
res = minimize(resid, pars0,args=(x,z,y), method='cobyla',options={'maxiter': 5000000})
print("a = %f , b = %f, c = %f, d = %f, e = %f, f = %f" % (res.x[0], res.x[1], res.x[2], res.x[3], res.x[4], res.x[5]))
I am getting the following coefficients from fitting: 我从拟合中得到以下系数:
a = 1.181149 , b = 1.228558, c = 0.253053, d = 0.219143, e = 0.444941, f = 0.172369
Compared with my coefficients for calculating the y
data the fitting is not realy what I would call adquate. 与我的用于计算
y
数据的系数相比,拟合度并不是我所说的适当。 Can someone explain me why my fit is so bad? 有人可以解释一下我的身材为什么这么差吗?
PS: If someone is wondering, I use cobyla
because I have to define some constraints later on. PS:如果有人想知道,我会使用
cobyla
因为稍后必须定义一些约束。 This is just a testing code to find out where my problem is located (hopefully). 这只是一个测试代码,可以找出我的问题所在(希望如此)。
Looking at res.fun
, which is in your case around 1e-5
the fit is actually quite good. 查看
res.fun
,在您的情况下大约为1e-5
,拟合度实际上非常好。
Most likely you found a local mininum of your objective function. 您很可能找到了目标函数的局部最小值。 To better understand this behaviour, try the code below.
为了更好地理解这种行为,请尝试下面的代码。 This will generate different results for different startpoints.
对于不同的起点,这将产生不同的结果。 As you will see, you are minimizing, just not to the global minimum.
正如您将看到的,您正在最小化,只是没有达到全局最小值。 To optimize globally, you have to use other approaches/methods.
要进行全局优化,您必须使用其他方法/方法。 You could also increase the criteria for when to stop the optimization.
您还可以增加何时停止优化的条件。 Or use a hybrid approach and start at different initial points, solve the local minimization and take the best value.
或使用混合方法并从不同的起始点开始,解决局部最小化问题并获得最佳价值。
for i in range(10):
pars0 = np.random.rand(6) * 1
res = minimize(resid, pars0, args=(x,z,y), method='cobyla',options={'maxiter': 5000000})
print("a = %f , b = %f, c = %f, d = %f, e = %f, f = %f" % (res.x[0], res.x[1], res.x[2], res.x[3], res.x[4], res.x[5]))
print(res.fun)
Try an inital point close to the solution you are seeking. 尝试在接近您要寻找的解决方案的起始点。 This will most probably yield the global result.
这很可能会产生全局结果。 If you don't know the vague location of your solution, you may have to use a hybrid/global approach to the minimization.
如果您不知道解决方案的模糊位置,则可能必须使用混合/全局方法进行最小化。
For example, the initial point: 例如,初始点:
pars0 = np.array([1,0.5,0.25,1,0.5,0.25]) + np.random.rand(6)*0.01
yields a quite fitting solution. 产生一个非常合适的解决方案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.