scipy curve_fit的多变量回归:总是偏离系统量

时间:2016-08-17 21:52:27

标签: python scipy curve-fitting

我一直在python中进行多变量线性回归(形式的方程式:y = b0 + b1 * x1 + b2 * x2 + ... + bnxn)。我可以成功解决以下功能:

def MultipleRegressionFunc(X,B):
    y=B[0]
    for i in range(0,len(X)): y += X[i]*B[i+1]
    return y

我现在暂时跳过该功能的详细信息。可以说使用curve_fit中的scipy包装器使用此函数已经成功地允许我解决具有许多变量的系统。

现在我一直想考虑变量之间可能的相互作用,所以我修改了这个函数如下:

def MultipleRegressionFuncBIS(X,B):
    #Define terms of the equation
    #The first term is 1*b0 (intercept)
    terms=[1]
    #Adding terms for the "non-interaction" part of the equation
    for x in X: terms.append(x)
    #Adding terms for the 'interaction' part of the equations
    for x in list(combinations(X, 2)): terms.append(x[0]*x[1])
    #I'm proceeding in this way because I found that some operations on iterables are not well handled when curve_fit passes numpy arrays to the function
    #Setting a float object to hold the result of the calculation
    y = 0.0
    #Iterating through each term in the equation, and adding the value to y
    for i in range(0, len(terms)):  y += B[i]*terms[i]
    return y

我为上面做了一个包装函数,能够通过curve_fit将多个线性系数传递给它。

def wrapper_func(X,*B):
    return MultipleRegressionFuncBIS(X,B)

这里有一些模拟输入,通过应用以下公式生成:1+2*x1+3*x2+4*x3+5*x1*x2+6*x1*x3+7*x2*x3

x1=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53]
x2=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54]
x3=[3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55]
y=[91, 192, 329, 502, 711, 956, 1237, 1554, 1907, 2296, 2721, 3182, 3679, 4212, 4781, 5386, 6027, 6704, 7417, 8166, 8951, 9772, 10629, 11522, 12451, 13416, 14417, 15454, 16527, 17636, 18781, 19962, 21179, 22432, 23721, 25046, 26407, 27804, 29237, 30706, 32211, 33752, 35329, 36942, 38591, 40276, 41997, 43754, 45547, 47376, 49241, 51142, 53079]

然后通过调用以下内容获得线性系数:

linear_coeffs=list(curve_fit(wrapper_func,[x1,x2,x3],y,p0=[1.1,2.2,3.1,4.1,5.1,6.1,7.1],bounds=(0.0,10.0))[0])
print linear_coeffs

请注意,此处将p0估算值手动设置为非常接近实际值的值,以排除curve_fit难以收敛的可能性。

然而,这个特定情况的输出偏离了我对实际值的预期(预期:[1.0,2.0,3.0,4.0,5.0,6.0,7.0]):

[1.1020684140370627, 2.1149407566785214, 2.9872182044259676, 3.9734017072175436, 5.0575156518729969, 5.9605293645760549, 6.9819549835509491]

现在,这是我的问题。虽然系数与输入模型不完全匹配,但这是次要问题。我确实希望在现实生活中有一些错误的例子,尽管在这个没有噪音的模拟例子中令人费解。我的主要问题是错误系统性。在上面的示例中,对于curve_fit的所有值,使用由0.10206841估计的系数,残差系统地等于x1,x2,x3。其他模拟数据集产生不同但仍然系统的残差。

您能否想到对此系统错误的任何解释?

我在这里发帖是因为我怀疑这是一个编码问题,而不是统计问题。如果事实证明我犯了统计信息错误,我非常愿意将此问题移至Cross Validated。

非常感谢!

0 个答案:

没有答案