为什么我的optimize.leastsq无效?

时间:2013-02-06 12:36:07

标签: python optimization scipy

我正在尝试将功能与我的数据相匹配。我有两个不同的轴,x轴:高度,y轴:重量。通过视觉检查,我可以看到,它或多或少地给出了在重量= 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)

无论我设置为p0的值,输出始终为p1 = p0

我做错了什么?

你认为如果饱和会使用不同的功能会更好吗?

提前致谢!

3 个答案:

答案 0 :(得分:3)

如果他们是人口的体重和身高,你的体重和身高可能会发生逆转。除此之外,您的代码运行得非常好:

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()

enter image description here

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

代码有时会发出警告:

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

您可能希望将fitfuncerrfunc重新定义为

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

然后执行:

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

绘制这个和之前的结果略有不同但可比较的结果:

enter image description here

答案 1 :(得分:2)

不能直接回答您的问题,但根据您的数据,我没有问题:

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()

fit results

您可以做的一件事,就像我在上面的代码中所做的那样,设置为full_output=1并打印您收到的消息。请注意,我的success值实际上是2,而不是4.所以有一些奇怪的区别。由于我们应该使用相同的数据,因此scipy设置中的某些内容可能不正确。那,或者你没有表现出整个问题,其他地方也出现了问题。

看一下这个数字,我确实看到价值几乎散落在任何地方,所以无论如何都很难适应(事实上,我不会!)。

答案 2 :(得分:2)

感谢您的帮助。我想我知道问题是什么。不知何故,sqrt变得负面,并且正在给出错误。当我取出变量以使它不能为负数时,它开始起作用,即:

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

它不完全一样,但对我有用。 我之前应该考虑过这个问题。再次感谢