Pythonの curve_fit
は、単一の独立変数を持つ関数の最適なパラメーターを計算しますが、curve_fit
または他の何か、複数の独立変数を持つ関数に適合しますか?例えば:
def func(x, y, a, b, c):
return log(a) + b*log(x) + c*log(y)
ここで、xとyは独立変数であり、a、b、およびcに適合させたいと考えています。
curve_fit
に独立変数の多次元配列を渡すことができますが、func
は同じものを受け入れなければなりません。たとえば、この配列X
を呼び出して、わかりやすくするためにx
、y
に展開します。
import numpy as np
from scipy.optimize import curve_fit
def func(X, a, b, c):
x,y = X
return np.log(a) + b*np.log(x) + c*np.log(y)
# some artificially noisy data to fit
x = np.linspace(0.1,1.1,101)
y = np.linspace(1.,2., 101)
a, b, c = 10., 4., 6.
z = func((x,y), a, b, c) * 1 + np.random.random(101) / 100
# initial guesses for a,b,c:
p0 = 8., 2., 7.
print curve_fit(func, (x,y), z, p0)
フィット感を与えます:
(array([ 9.99933937, 3.99710083, 6.00875164]), array([[ 1.75295644e-03, 9.34724308e-05, -2.90150983e-04],
[ 9.34724308e-05, 5.09079478e-06, -1.53939905e-05],
[ -2.90150983e-04, -1.53939905e-05, 4.84935731e-05]]))
はい、あります:単にcurve_fit
xData
の多次元配列。
def func(X, a, b, c):
x,y = X
return np.log(a) + b*np.log(x) + c*np.log(y)
# some artificially noisy data to fit
x = np.linspace(0.1,1.1,101)
y = np.linspace(1.,2., 101)
a, b, c = 10., 4., 6.
z = func((x,y), a, b, c) * 1 + np.random.random(101) / 100
# initial guesses for a,b,c:
p0 = 8., 2., 7.
print curve_fit(func, (x,y), z, p0)
パラメータの未知数への適合
この例では、いくつかの測定データmeasData
を再現しようとします。この例では、measData
は関数measuredData(x, a=.2, b=-2, c=-.8, d=.1)
によって生成されます。練習して、ある方法でmeasData
を測定したかもしれません-そのため、数学的にどのように記述されているのかわかりません。したがって、フィット。
関数polynomFit(inp, *args)
で記述される多項式で近似します。さまざまな次数の多項式を試してみたいので、入力パラメーターの数に柔軟に対応することが重要です。独立変数(あなたの場合はxとy)は、inp
の 'columns'/second次元でエンコードされます。
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
def measuredData(inp, a=.2, b=-2, c=-.8, d=.1):
x=inp[:,0]
y=inp[:,1]
return a+b*x+c*x**2+d*x**3 +y
def polynomFit(inp, *args):
x=inp[:,0]
y=inp[:,1]
res=0
for order in range(len(args)):
print(14,order,args[order],x)
res+=args[order] * x**order
return res +y
inpData=np.linspace(0,10,20).reshape(-1,2)
inpDataStr=['({:.1f},{:.1f})'.format(a,b) for a,b in inpData]
measData=measuredData(inpData)
fig, ax = plt.subplots()
ax.plot(np.arange(inpData.shape[0]), measData, label='measuered', marker='o', linestyle='none' )
for order in range(5):
print(27,inpData)
print(28,measData)
popt, pcov = curve_fit(polynomFit, xdata=inpData, ydata=measData, p0=[0]*(order+1) )
fitData=polynomFit(inpData,*popt)
ax.plot(np.arange(inpData.shape[0]), fitData, label='polyn. fit, order '+str(order), linestyle='--' )
ax.legend( loc='upper left', bbox_to_anchor=(1.05, 1))
print(order, popt)
ax.set_xticklabels(inpDataStr, rotation=90)
結果: