简体   繁体   English

为什么我的optimize.leastsq无法正常工作?

[英]why is my optimize.leastsq not working?

I am trying to fit function to my data. 我正在尝试使功能适合我的数据。 I have two different axis, x-axis: height, y-axis: weight. 我有两个不同的轴,x轴:高度,y轴:重量。 By visual inspection, I can see, that it gives more or less the shape of square root function saturating around weight = 10. Here is what I am doing: 通过视觉检查,我可以看到,它或多或少地给出了在重量= 10周围饱和的平方根函数的形状。这就是我正在做的事情:

from scipy import optimize

fitfunc = lambda p, x: np.sqrt(p[0]* x + p[1]) +p[2] # Target function
errfunc = lambda p, x, y: fitfunc(p, x) - y

sort_idx = np.argsort(height)
height = height[sort_idx]
weight = weight[sort_idx]

p0 = [0.1, 0.2, 0.3] # initial values
p1, success = optimize.leastsq(errfunc, p0, args=(height, weight), maxfev=10000)

No matter what values I set as p0, the output is always p1 = p0 无论我设置为p0的值,输出始终为p1 = p0

What am I doing wrong? 我究竟做错了什么?

Do you think it would be better to use different function if it is saturating? 您认为饱和时使用其他功能会更好吗?

Thanks in advance! 提前致谢!

You may have weight and height reversed, if they are the weight and height of a human population. 如果它们是人口的体重和身高,您的体重和身高可能会发生逆转。 Other than that your code runs beautifully well: 除此之外,您的代码可以很好地运行:

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

fitfunc = lambda p, x: np.sqrt(p[0]* x + p[1]) +p[2] # Target function
errfunc = lambda p, x, y: fitfunc(p, x) - y

height = np.random.normal(loc=1.70, scale=.15, size=(100))
bmi = np.random.normal(loc=20, scale=2, size=(100))
weight = bmi * height**2

sort_idx = np.argsort(weight)
height = height[sort_idx]
weight = weight[sort_idx]

p0 = [0.1, 0.2, 0.3] # initial values
p1, success = optimize.leastsq(errfunc, p0, args=(weight, height), maxfev=10000)

plt.plot(weight, height, 'o')
plt.plot(weight, fitfunc(p1, weight), '-')
plt.xlabel('weight')
plt.ylabel('height')
plt.show()

在此输入图像描述

>>> p1
array([ 0.01625167, -0.32844465,  0.9256349 ])

The code does sometime give warnings like: 该代码有时会发出如下警告:

RuntimeWarning: invalid value encountered in sqrt
  fitfunc = lambda p, x: np.sqrt(p[0]* x + p[1]) +p[2] # Target function

You may want to redefine your fitfunc and errfunc as 您可能希望将fitfuncerrfunc重新定义为

fitfunc2 = lambda p, y: ((y - p[2])**2 - p[1]) / p[0] # Target function
errfunc2 = lambda p, x, y: fitfunc2(p, y) - x

and then do : 然后做:

p2, success2 = optimize.leastsq(errfunc2, p0, args=(weight, height), maxfev=10000)

Plotting this and the previous gives slightly different but comparable results: 绘制这个和前一个给出了略有不同但可比较的结果:

在此输入图像描述

Not directly an answer to your problem, but with your data given, I have no problem fitting this: 不是直接回答你的问题,但是根据你提供的数据,我没有问题:

import sys
from scipy import optimize
import numpy as np
from matplotlib import pyplot as plt


height=np.array([34.75625407,126.90646855,369.02594015,321.33822843,100.89398254,119.73654933,421.4400502,98.09051003,72.61433571,626.54970675,45.97802204,741.65476066,39.13568217,67.21666378,58.44445182,31.9950751,32.74788721,168.3256637,149.57003524,1058.41323859])
weight=np.array([4.375,3.95833333,9.16666667,8.125,3.75,8.4375,7.91666667,7.5,5.,10.,6.25,7.625,5.,6.25,10.,3.75,4.375,6.66666667,6.25,8.28125])

fitfunc = lambda p, x: np.sqrt(p[0]* x + p[1]) +p[2] # Target function
errfunc = lambda p, x, y: fitfunc(p, x) - y

pp = [0.2, 0.3, 0.4]
sort_idx = np.argsort(height)
height = height[sort_idx]
weight = weight[sort_idx]

p0 = [0.2, 0.2, 0.3] # initial values
result = optimize.leastsq(errfunc, p0, args=(height, weight), maxfev=10000, full_output=1)
p1 = result[0]
print result[3]

plt.plot(height, weight, 'o')
plt.plot(height, fitfunc(p1, height), '-')
plt.show()

合适的结果

One thing you could do, as I've done in my code above, is set full_output=1 and print the message you get. 正如我在上面的代码中所做的那样,您可以做的一件事是将full_output=1设置并打印得到的消息。 Note that my success value is actually 2, not 4. So there is some odd difference. 请注意,我的success值实际上是2,而不是4.所以有一些奇怪的区别。 Since we should be using the same data, something in your scipy setup may be incorrect. 由于我们应该使用相同的数据,因此scipy设置中的某些内容可能不正确。 That, or you're not showing the whole problem and something's up elsewhere. 那,或者您没有显示整个问题,而其他地方有问题。

Looking at the figure, I do see that the values are scattered pretty much around anywhere, so it'll be hard to fit anyway (in fact, I wouldn't!). 查看该图,我确实看到这些值几乎分散在任何地方,因此无论如何都很难拟合(实际上,我不会!)。

Thanks for your help. 谢谢你的帮助。 I think I know what was the problem. 我想我知道问题是什么。 Somehow the sqrt was becoming negative, and was giving the errors. 不知何故,sqrt变得负面,并且正在给出错误。 When I took out the variables so that it cannot be negative it started to work, ie: 当我拿出变量以使其不能为负数时,它开始起作用,即:

p[0]* np.sqrt(x + np.abs(p[1]))

It's not exactly the same, but it works for me. 它不完全一样,但对我有用。 I should have thought about that before. 我之前应该考虑过这个问题。 Thanks again 再次感谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Scipy:optimize.fmin 和 optimize.leastsq 之间的区别 - Scipy: difference between optimize.fmin and optimize.leastsq Scipy:使用optimize.leastsq时拟合参数的界限 - Scipy: bounds for fitting parameter(s) when using optimize.leastsq 使用optimize.leastsq()(Python)的一组方程中的最小二乘法 - Least squares in a set of equations with optimize.leastsq() (Python) "python optimize.leastsq:将圆拟合到 3d 点集" - python optimize.leastsq: fitting a circle to 3d set of points Scipy ValueError:对象不足,无法使用optimize.leastsq进行所需的数组 - Scipy ValueError: object too deep for desired array with optimize.leastsq Python / Scipy - 将optimize.curve_fit的sigma实现到optimize.leastsq中 - Python / Scipy - implementing optimize.curve_fit 's sigma into optimize.leastsq 使用python的optimize.leastsq()和optimize.curve_fit将数据拟合到Faddeeva函数 - Fitting data to Faddeeva function using python's optimize.leastsq() and optimize.curve_fit 使用python中的optimize.leastsq方法获取拟合参数的标准错误 - Getting standard errors on fitted parameters using the optimize.leastsq method in python 当 sp.optimize.least_squares 不收敛时,为什么 sp.optimize.leastsq 会收敛? - Why would sp.optimize.leastsq converge when sp.optimize.least_squares doesn't? Python scipy.optimize.leastsq - Python scipy.optimize.leastsq
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM