具有多个自变量的 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
Python curve_fit with multiple independent variables
提问by rferdinand
Python's curve_fit
calculates the best-fit parameters for a function with a single independent variable, but is there a way, using curve_fit
or 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_fit
a multi-dimensional array for the independent variables, but then your func
must accept the same thing. For example, calling this array X
and unpacking it to x
, y
for clarity:
您可以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)
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_fit
a 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 measData
is generated by the function measuredData(x, a=.2, b=-2, c=-.8, d=.1)
. I practice, we might have measured measData
in 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:
结果:
回答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 个参数。