具有多个自变量的 Python 曲线拟合

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28372597/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:10:18  来源:igfitidea点击:

Python curve_fit with multiple independent variables

pythonscipycurve-fitting

提问by rferdinand

Python's curve_fitcalculates the best-fit parameters for a function with a single independent variable, but is there a way, using curve_fitor something else, to fit for a function with multiple independent variables? For example:

Pythoncurve_fit计算具有单个自变量的函数的最佳拟合参数,但是有没有办法使用curve_fit或其他方法来拟合具有多个自变量的函数?例如:

def func(x, y, a, b, c):
    return log(a) + b*log(x) + c*log(y)

where x and y are the independent variable and we would like to fit for a, b, and c.

其中 x 和 y 是自变量,我们想拟合 a、b 和 c。

采纳答案by xnx

You can pass curve_fita multi-dimensional array for the independent variables, but then your funcmust accept the same thing. For example, calling this array Xand unpacking it to x, yfor clarity:

您可以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)

Gives the fit:

给出合适的:

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

回答by Marcus Müller

Yes, there is: simply give curve_fita multi-dimensional array for xData.

是的,有:简单地给出curve_fit一个多维数组xData

回答by Markus Dutschke

Fitting to an unknown numer of parameters

拟合未知数量的参数

In this example, we try to reproduce some measured data measData. In this example measDatais generated by the function measuredData(x, a=.2, b=-2, c=-.8, d=.1). I practice, we might have measured measDatain a way - so we have no idea, how it is described mathematically. Hence the fit.

在这个例子中,我们尝试重现一些测量数据measData。在这个例子中measData是由函数生成的measuredData(x, a=.2, b=-2, c=-.8, d=.1)。我练习,我们可能measData以某种方式进行了测量- 所以我们不知道它是如何用数学描述的。因此合身。

We fit by a polynomial, which is described by the function polynomFit(inp, *args). As we want to try out different orders of polynomials, it is important to be flexible in the number of input parameters. The independent variables (x and y in your case) are encoded in the 'columns'/second dimension of inp.

我们通过多项式拟合,该多项式由函数 描述polynomFit(inp, *args)。由于我们想尝试不同阶的多项式,因此输入参数的数量必须灵活。自变量(在您的情况下为 x 和 y)在inp.

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)

Result:

结果:

enter image description here

在此处输入图片说明

回答by Abhishek Kumar

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)

回答by Kumar Mayank

Yes. We can pass multiple variables for curve_fit. I have written a piece of code:

是的。我们可以为curve_fit传递多个变量。我写了一段代码:

import numpy as np
x = np.random.randn(2,100)
w = np.array([1.5,0.5]).reshape(1,2)
esp = np.random.randn(1,100)
y = np.dot(w,x)+esp
y = y.reshape(100,)

In the above code I have generated xa 2D data set in shape of (2,100) i.e, there are two variables with 100 data points. I have fit the dependent variable ywith independent variables xwith some noise.

在上面的代码我已生成的X中的形状的2D数据集(2100),即,有两个变量与100个数据点。我已经将因变量y与带有一些噪声的自变量x拟合。

def model_func(x,w1,w2,b):
  w = np.array([w1,w2]).reshape(1,2)
  b = np.array([b]).reshape(1,1)
  y_p = np.dot(w,x)+b
  return y_p.reshape(100,)

We have defined a model function that establishes relation between y& x.
Note:The shape of output of the model function or predicted yshould be (length of x,)

我们已经定义了一个模型函数来建立y& x之间的关系。
注意:模型函数或预测y的输出形状应该是(x 的长度,)

popt, pcov = curve_fit(model_func,x,y)

The poptis an 1D numpy array containing predicted parameters. In our case there are 3 parameters.

所述POPT是含有预测的参数的一维阵列numpy的。在我们的例子中,有 3 个参数。