web-dev-qa-db-ja.com

Python複数の独立変数を持つcurve_fit

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に適合させたいと考えています。

39
rferdinand

curve_fitに独立変数の多次元配列を渡すことができますが、funcは同じものを受け入れなければなりません。たとえば、この配列Xを呼び出して、わかりやすくするためにxyに展開します。

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]]))
47
xnx

はい、あります:単にcurve_fitxDataの多次元配列。

0
Marcus Müller
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)
0
Abhishek Kumar

パラメータの未知数への適合

この例では、いくつかの測定データ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)

結果:

enter image description here

0
Markus Dutschke