我有一些或多或少的线性数据的形式:
x = [0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 2.0, 4.0, 6.0, 8.0, 10.0, 20.0, 40.0, 60.0, 80.0]
y = [0.50505332505407008, 1.1207373784533172, 2.1981844719020001, 3.1746209003398689, 4.2905482471260044, 6.2816226678076958, 11.073788414382639, 23.248479770546009, 32.120462301367183, 44.036117671229206, 54.009003143831116, 102.7077685684846, 185.72880217806673, 256.12183145545811, 301.97120103079675]
我使用scipy.optimize.leastsq
来拟合一个线性回归:
def lin_fit(x, y):
'''Fits a linear fit of the form mx+b to the data'''
fitfunc = lambda params, x: params[0] * x + params[1] #create fitting function of form mx+b
errfunc = lambda p, x, y: fitfunc(p, x) - y #create error function for least squares fit
init_a = 0.5 #find initial value for a (gradient)
init_b = min(y) #find initial value for b (y axis intersection)
init_p = numpy.array((init_a, init_b)) #bundle initial values in initial parameters
#calculate best fitting parameters (i.e. m and b) using the error function
p1, success = scipy.optimize.leastsq(errfunc, init_p.copy(), args = (x, y))
f = fitfunc(p1, x) #create a fit with those parameters
return p1, f
而且它工作得很漂亮(虽然我不确定scipy.optimize
在这里使用是否正确,但它可能有点过了头?)。
然而,由于数据点的位置,它没有给予我一个y轴截距在0。我知道,虽然它必须是零,在这种情况下,if x = 0 than y = 0
。
我能不能强迫你?
3条答案
按热度按时间vsaztqbk1#
正如@AbhranilDas提到的,只需要使用线性方法,不需要像
scipy.optimize.lstsq
这样的非线性求解器。通常,您会使用
numpy.polyfit
来拟合数据线,但在本例中,您需要直接使用numpy.linalg.lstsq
,因为您希望将截距设置为零。举个简单的例子:
nle07wnf2#
我并不擅长这些模块,但我在统计学方面有一些经验,所以我看到的是这样的。
至:
同时删除行:
并将下一行更改为:
这将去掉产生y轴截距的第二个参数,并将拟合线通过原点。在代码的其余部分,可能需要做一些小的修改。
但是,我不确定如果像这样去掉第二个参数,这个模块是否能正常工作。这取决于模块的内部工作方式,它是否能接受这种修改。例如,我不知道参数列表
params
在哪里被初始化,所以我不知道这样做是否会改变它的长度。顺便说一句,既然你提到了,我实际上认为这是一个有点过火的方法来优化一个斜率。你可以读一点 * 线性回归 ,然后在一些信封后面的演算之后自己写一些小代码来做。这真的很简单和直接。事实上,我刚刚做了一些计算,我猜优化的斜率将只是
<xy>/<x^2>
。即xy乘积的均值除以x^2的均值。ql3eal8s3#
从
Python 3.11
开始,我们可以直接使用标准库执行截距强制为0的linear_regression
:将参数
proportional
设置为True
,以指定假定x
和y
成正比(并且数据将拟合到通过原点的直线)。