Python curve_fit有多个自变量

时间:2015-02-06 18:41:20

标签: python scipy curve-fitting

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。

6 个答案:

答案 0 :(得分:43)

您可以为自变量传递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]]))

答案 1 :(得分:0)

是的,有:只需为curve_fit提供xData多维数组。

答案 2 :(得分:0)

适合未知数目的参数

在此示例中,我们尝试重现一些测量数据measData。 在此示例中,measData由函数measuredData(x, a=.2, b=-2, c=-.8, d=.1)生成。我的实践是,我们可能以某种方式对measData进行了测量-因此我们不知道如何对其进行数学描述。因此适合。

我们用多项式拟合,该多项式由函数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)

结果:

enter image description here

答案 3 :(得分:0)

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)

答案 4 :(得分:0)

是的。我们可以为 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,)

在上面的代码中,我生成了 x 形状为(2,100)的2D数据集,即,有两个带有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,)

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

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

popt 是包含预测参数的一维numpy数组。在我们的例子中,有3个参数。

答案 5 :(得分:0)

优化具有多个输入维度和可变数量参数的功能

此示例显示了如何通过增加数量的系数来拟合具有二维输入(R ^ 2-> R)的多项式。该设计非常灵活,因此可以为任意数量的非关键字参数定义一次curve_fit中的可调用f。

enter image description here

最小可复制示例

{'message': 'success', 
  'people': [
        {'name': 'Sergey Ryzhikov', 'craft': 'ISS'},
        {'name': 'Kate Rubins', 'craft': 'ISS'},
        {'name': 'Sergey Kud-Sverchkov', 'craft': 'ISS'}

   ], 
   'number': 3}

P.S。这个答案的概念与我在这里的其他答案相同,但是代码示例更加清晰。在给出的时间,我将删除其他答案。