互いにシグモイド関係にある2つの変数(xとy)があり、xの値が与えられた場合に、yの値を予測できるような予測式を見つける必要があります。私の予測式は、2つの変数間のややシグモイド関係を示す必要があります。したがって、線を生成する線形回帰方程式を決定することはできません。2つの変数のグラフの左右両方で発生する、勾配の緩やかな曲線変化を確認する必要があります。
曲線回帰とPythonをグーグルで調べた後、numpy.polyfitを使い始めましたが、以下のコードを実行すると、ひどい結果が得られました。 誰かが私が望むタイプのシグモイド回帰方程式を得るために以下のコードを書き直す方法を教えてもらえますか?
以下のコードを実行すると、下向きの放物線が表示されることがわかります。これは、変数間の関係がどのようになるかとは異なります。代わりに、2つの変数の間にシグモイド関係がもっとあるはずですが、以下のコードで使用しているデータと密接に適合しています。以下のコードのデータは、大規模なサンプルの調査研究からの平均であるため、5つのデータポイントが示唆するよりも多くの統計的検出力を備えています。大規模なサンプルの調査研究からの実際のデータはありませんが、以下の平均とそれらの標準偏差(表示していません)はあります。以下にリストされている平均データを使用して単純な関数をプロットすることをお勧めしますが、複雑さが大幅な改善をもたらす場合、コードはより複雑になる可能性があります。
できればscipy、numpy、pythonを使用して、シグモイド関数に最適なものを表示するようにコードを変更するにはどうすればよいですか? これが私のコードの現在のバージョンであり、修正する必要があります。
import numpy as np
import matplotlib.pyplot as plt
# Create numpy data arrays
x = np.array([821,576,473,377,326])
y = np.array([255,235,208,166,157])
# Use polyfit and poly1d to create the regression equation
z = np.polyfit(x, y, 3)
p = np.poly1d(z)
xp = np.linspace(100, 1600, 1500)
pxp=p(xp)
# Plot the results
plt.plot(x, y, '.', xp, pxp, '-')
plt.ylim(140,310)
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.show()
以下の編集:(質問を再構成しました)
あなたの反応とそのスピードはとても印象的です。ありがとう、うんぶ。ただし、より有効な結果を生成するには、データ値を再構成する必要があります。これは、x値を最大x値のパーセンテージとして再キャストし、y値を元のデータのx値のパーセンテージとして再キャストすることを意味します。私はあなたのコードでこれをやろうとしました、そして次のことを思いつきました:
import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize
# Create numpy data arrays
'''
# Comment out original data
#x = np.array([821,576,473,377,326])
#y = np.array([255,235,208,166,157])
'''
# Re-calculate x values as a percentage of the first (maximum)
# original x value above
x = np.array([1.000,0.702,0.576,0.459,0.397])
# Recalculate y values as a percentage of their respective x values
# from original data above
y = np.array([0.311,0.408,0.440,0.440,0.482])
def sigmoid(p,x):
x0,y0,c,k=p
y = c / (1 + np.exp(-k*(x-x0))) + y0
return y
def residuals(p,x,y):
return y - sigmoid(p,x)
p_guess=(600,200,100,0.01)
(p,
cov,
infodict,
mesg,
ier)=scipy.optimize.leastsq(residuals,p_guess,args=(x,y),full_output=1,warning=True)
'''
# comment out original xp to allow for better scaling of
# new values
#xp = np.linspace(100, 1600, 1500)
'''
xp = np.linspace(0, 1.1, 1100)
pxp=sigmoid(p,xp)
x0,y0,c,k=p
print('''\
x0 = {x0}
y0 = {y0}
c = {c}
k = {k}
'''.format(x0=x0,y0=y0,c=c,k=k))
# Plot the results
plt.plot(x, y, '.', xp, pxp, '-')
plt.ylim(0,1)
plt.xlabel('x')
plt.ylabel('y')
plt.grid(True)
plt.show()
この改訂されたコードを修正する方法を教えていただけますか?
注:データを再キャストすることにより、基本的に2d(x、y)シグモイドをz軸を中心に180度回転させました。また、1.000は実際にはx値の最大値ではありません。代わりに、1.000は、最大テスト条件でのさまざまなテスト参加者からの値の範囲の平均です。
以下の2番目の編集:
ありがとう、ubuntu。私はあなたのコードを注意深く読み、scipyのドキュメントでその側面を調べました。あなたの名前はscipyドキュメントのライターとして表示されるようですので、次の質問に答えていただければ幸いです。
1.)leastsq()はresiduals()を呼び出しますか?これにより、入力yベクトルとsigmoid()関数によって返されるyベクトルの差が返されますか?もしそうなら、それは入力yベクトルとsigmoid()関数によって返されるyベクトルの長さの違いをどのように説明しますか?
2.)残余関数を介してその数学方程式にアクセスし、次に数学関数を呼び出す限り、任意の数学方程式に対してleastsq()を呼び出すことができるように見えます。これは本当ですか?
3.)また、p_guessにはpと同じ数の要素があることに気付きました。これは、p_guessの4つの要素が、x0、y0、c、およびkによって返される値とそれぞれ順番に対応していることを意味しますか?
4.)residuals()およびsigmoid()関数への引数として送信されるpは、leastsq()によって出力されるのと同じpであり、leastsq()関数はそのpを内部で使用してから返しますか?
5.)pの要素の数がp_guessの要素の数と等しい限り、モデルとして使用される方程式の複雑さに応じて、pとp_guessは任意の数の要素を持つことができますか?