2

関数をデータに適合させようとしています。x 軸: 高さ、y 軸: 重量の 2 つの異なる軸があります。目視検査により、重み = 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 です。

私は何を間違っていますか?

飽和している場合は、別の関数を使用した方がよいと思いますか?

前もって感謝します!

4

3 に答える 3

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

ここに画像の説明を入力

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

fitfuncanderrfuncを次のように再定義することもできます。

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)

これと前のものをプロットすると、わずかに異なるが同等の結果が得られます。

ここに画像の説明を入力

于 2013-02-06T15:03:43.863 に答える
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()

適合結果

上記のコードで行ったように、できることの 1 つは、full_output=1取得したメッセージを設定して出力することです。私の値は実際には 4 ではなく 2 であることに注意してくださいsuccess。したがって、いくつかの奇妙な違いがあります。同じデータを使用する必要があるため、scipy セットアップの何かが間違っている可能性があります。それか、問題全体が表示されておらず、他の場所で何かが起きています。

図を見ると、値がかなりあちこちに散らばっていることがわかります。そのため、いずれにせよ適合させるのは難しいでしょう (実際、私は適合しません!)。

于 2013-02-06T16:13:43.610 に答える
2

ご協力いただきありがとうございます。私は何が問題だったのか知っていると思います。どういうわけか、平方根が負になり、エラーが発生していました。負にならないように変数を取り出したところ、機能し始めました。

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

まったく同じではありませんが、私にとってはうまくいきます。その前に考えておくべきだった。再度、感謝します

于 2013-02-13T10:37:12.283 に答える