【问题标题】:Huber Regressor returns inconsistent sign of coefficientHuber 回归器返回的系数符号不一致
【发布时间】:2023-03-25 03:31:01
【问题描述】:

我一直在尝试对时间序列执行 Huber Regressor (sklearn.linear_model)。 我遇到了一个奇怪的现象:有时它返回一个非常小的负系数,有时返回正值,尽管数字不断向上变化。

例如:

HuberRegressor(epsilon=1.35,max_iter=10000).fit(X=np.arange(12).reshape(-1,1),y=pd.Series([0,0,0,0,0,0,0,0,0,0,0,1])).coef_

数组([3.1380359e-08])

HuberRegressor(epsilon=1.35,max_iter=10000).fit(X=np.arange(12).reshape(-1,1),y=pd.Series([0,0,0,0,0,0,0,0,0,0,0,2])).coef_

数组([-2.20536164e-10])

HuberRegressor(epsilon=1.35,max_iter=10000000).fit(X=np.arange(12).reshape(-1,1),y=pd.Series([0,0,0,0,0,0,0,0,0,0,0,5])).coef_

数组([7.63157014e-07])

HuberRegressor(epsilon=1.35,max_iter=10000).fit(X=np.arange(12).reshape(-1,1),y=pd.Series([0,0,0,0,0,0,0,0,0,0,0,248])).coef_

数组([-4.49809127e-07])

所以,我所做的只是提高最后一个观察值 (1,2,5,248),但系数的符号发生了变化。 由于这是 Huber 回归,因此 1,3,5,248 都被识别为异常值,因为所有其他都是零。我应该在模型中找出不同的东西吗?

【问题讨论】:

    标签: python regression robust


    【解决方案1】:

    TL;DR

    在调整您的示例以重现错误时,我觉得这是由于浮点算术错误,因为您正在使用带有浮点算术的数值算法评估空斜率。

    浮点运算错误

    如果使用实数执行计算,得到错误的符号可能很奇怪,但这是浮点数的常见现象。

    让您的 MCVE 适应:

    import numpy as np
    from sklearn import linear_model 
    
    u = 1
    c = []
    x = np.arange(12).reshape(-1,1)
    for k in [0, 1, 2, 5, 25, 100, 200, 500, 1000]:
        y = np.array([u]*(len(x)-1)+[k])
        m = linear_model.HuberRegressor(tol=1e-16).fit(X=x, y=y)
        c.append(m.coef_[0])
    
    [-5.923749784709837e-09,
     -4.9322755264475916e-11,
     2.5190368660836694e-10,
     8.3699110105873e-07,
     -4.3671163925160265e-10,
     1.2964166828133428e-08,
     1.5063190859596705e-06,
     1.5063100994140354e-06,
     1.5063152932632047e-06]
    

    我承认在这种情况下大多数返回的数字通常太大而不能被视为零,但我仍然怀疑这种情况,因为更改 tol 开关确实会影响结果并且更改为非空斜率确实会返回预期的结果。

    工作用例

    我们可以改变数据来评估一个单一的斜率,我们得到以下结果:

    c = []
    x = np.arange(12).reshape(-1,1)
    for k in [0, 1, 2, 5, 25, 100, 200, 500, 1000]:
        y = np.array(list(x[:-1])+[k])
        m = linear_model.HuberRegressor(tol=1e-16).fit(X=x, y=y)
        c.append(m.coef_[0])
    
    [0.9999999423436053,
     0.9999991468916037,
     0.9999999916835522,
     0.9999999916837012,
     1.0000000059171992,
     1.000000006233575,
     1.000000006237059,
     1.000002303772441,
     1.0000023037721706]
    

    现在信息低于或高于单位,这是预期的结果。

    我的直觉是:您执行的测试给出了一个奇怪的结果,因为它处于机器精度(零的可接受值)和算法精度具有相同幅度的边界,因此是不好的迹象。当系数值明显大于算法精度时,该现象消失。

    这是浮点运算的常见问题,需要开发人员设计stable 和准确的算法,这是一项复杂的任务。涵盖它许多方面的一个很好的参考是:

    N。 J. 海厄姆。数值算法的准确性和稳定性。社会 工业和应用数学专业,美国宾夕法尼亚州费城,第二 2002 年版。ISBN 0-89871-521-0

    我的建议:您可以在 sklearn 上打开一个问题以突出显示这一观察结果,他们可能会在其单元测试套件中添加一个新测试以应对此特定用例,并为您提供更多关于在引擎盖。

    【讨论】:

    • 谢谢!这是一个很好的解释。我一直在减少我的结果,但仍然没有变化。您已经提到它确实会改变结果。你指的是我的例子吗?如果不是 - 在这种情况下,最好的方法似乎只是添加一个代码,当它们非常接近零时将斜率更改为零,不是吗?
    • 改为增加它,检查文档以查看使用的标准。
    • 我可以增加它,然后它显示 0,但增加 tol 会危及我所有其他斜率不接近零的情况。
    • 当然,您只需要接受对于这个版本的算法,零斜率的符号是没有意义的,但是值本身接近于零,这对于异常值和 OLS 而言似乎没问题会受到影响。
    • 我怀疑0是初始值,tol太大时不进行优化。
    猜你喜欢
    • 2019-04-24
    • 2018-10-02
    • 2015-01-04
    • 1970-01-01
    • 2016-09-13
    • 2018-06-02
    • 2020-10-14
    • 2017-10-24
    • 1970-01-01
    相关资源
    最近更新 更多