线性回归中如何强制零截取?

2024-09-27 07:24:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我是个新手,所以很抱歉,如果这个问题已经被回答了,我已经看了一眼,找不到具体的我在找什么。

我有一些或多或少的线性数据

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在这里是否是正确的使用方法,但它可能有点过头了?)。

但是,由于数据点所在的方式,它没有在0处提供y轴截获。我知道在这种情况下,它必须为零,if x = 0 than y = 0

有什么办法可以强迫我这样做吗?


Tags: the数据forinitcreatefunction线性scipy
2条回答

我不擅长这些模块,但我有一些统计经验,所以这里是我看到的。你需要改变你的健身功能

fitfunc = lambda params, x: params[0] * x + params[1]  

致:

fitfunc = lambda params, x: params[0] * x 

同时删除行:

init_b = min(y) 

并将下一行更改为:

init_p = numpy.array((init_a))

这应该去掉产生y截距的第二个参数,并使拟合线通过原点。在剩下的代码中,可能还需要做一些小的修改。

但是是的,如果你像这样把第二个参数去掉,我不确定这个模块是否能工作。这取决于模块的内部工作,看它是否能接受这种修改。例如,我不知道参数列表params在哪里被初始化,所以我不知道这样做是否会改变它的长度。

作为旁白,既然你提到了,我认为这是一个有点过分的方法来优化一个斜坡。你可以读一点线性回归,然后自己写一些小代码来完成它。很简单,很直接,真的。实际上,我只是做了一些计算,我想优化后的斜率就是<xy>/<x^2>,即x*y积的平均值除以x^2的平均值

正如@AbhranilDas提到的,只要使用线性方法。不需要像scipy.optimize.lstsq这样的非线性解算器。

通常,您需要使用numpy.polyfit来将行与数据匹配,但在这种情况下,您需要直接使用numpy.linalg.lstsq,因为您希望将截距设置为零。

举个简单的例子:

import numpy as np
import matplotlib.pyplot as plt

x = np.array([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 = np.array([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])

# Our model is y = a * x, so things are quite simple, in this case...
# x needs to be a column vector instead of a 1D vector for this, however.
x = x[:,np.newaxis]
a, _, _, _ = np.linalg.lstsq(x, y)

plt.plot(x, y, 'bo')
plt.plot(x, a*x, 'r-')
plt.show()

enter image description here

相关问题 更多 >

    热门问题