Python lmfit - 为什么线性回归中截距的估计依赖于初始值?
我正在尝试弄清楚为什么使用lmfit
这个包进行截距估计时,结果会因为起始值不同而有所不同。我把这些估计结果和使用statsmodels
进行的标准最小二乘法(OLS)估计结果进行了比较。有没有人能帮我一下?
代码:
from lmfit import minimize, Parameters
import numpy as np
import statsmodels.api as sm
x = np.linspace(0, 15, 10)
x_ols = sm.add_constant(x)
y = range(0,10)
model = sm.OLS(y,x_ols)
results = model.fit()
print "OLS: ", format(results.params[0], '.10f'), format(results.params[1], '.10f')
# define objective function: returns the array to be minimized
def fcn2min(params, x, data):
a = params['a'].value
b = params['b'].value
model = a + b * x
return model - data
for i in range(-2,3):
# create a set of Parameters
params = Parameters()
params.add('a', value= i)
params.add('b', value= 20)
# do fit, here with leastsq model
result = minimize(fcn2min, params, args=(x, y))
# print "lmfit: ",result.values # older usage
print "lmfit: ",result.params.values # newer syntax
1 个回答
1
如果你看看结果,就会发现常数的值在大约scipy.optimize.leastsq的默认容忍度下接近于零。
OLS: -0.0000000000 0.6000000000
lmfit: {'a': 1.1967327242889913e-08, 'b': 0.59999999932429748}
lmfit: {'a': 3.2643846243929039e-08, 'b': 0.59999999717671448}
lmfit: {'a': 3.2644232427278463e-08, 'b': 0.59999999717679642}
lmfit: {'a': 1.636450187584131e-08, 'b': 0.59999999900662315}
lmfit: {'a': 3.3578611617157454e-08, 'b': 0.59999999693286854}
如果我把需要的容忍度调得更严格,那么常数的估计值会更接近零,而且两个估计的系数也会更接近OLS的解。
在你的代码中添加了xtol
之后
result = minimize(fcn2min, params, args=(x, y), xtol=1e-12)
我得到了:
OLS: -0.0000000000 0.6000000000
lmfit: {'a': -3.5437341988915725e-32, 'b': 0.59999999999999998}
lmfit: {'a': -1.8490806236697864e-32, 'b': 0.59999999999999998}
lmfit: {'a': -9.8614500814838325e-32, 'b': 0.59999999999999998}
lmfit: {'a': 8.328833474508222e-09, 'b': 0.59999999921839664}
lmfit: {'a': -5.8547746020524404e-32, 'b': 0.59999999999999998}
OLS使用线性代数来得到一个明确的解(基于广义逆,pinv)。这样做的数值精度很高。
而非线性优化则使用迭代的方法来寻找解,当结果在要求的容忍度内时就停止。
在这个例子中,仍然有一个情况只有在8e-9时是正确的,但这也可能是因为对梯度的数值近似,以及其他影响收敛检查的因素。