线性回归中遇到的双精度溢出错误

大家好,我正在尝试进行线性回归,当我运行代码时出现了以下问题,我的代码是这样的:

    import numpy as npimport pandas as pdimport matplotlib.pyplot as pltdata = pd.read_csv('train.csv')df = data.dropna()X = np.array(df.x)Y = np.array(df.y)def compute_error(x,y,m,b):    error = 0    for i in range(len(x)):        error+= (y[i]-(m*x[i]+b))**2    return error / float(len(x))def step_graident_descent(x,y,m,b , alpha):    N = float(len(x))    b_graident = 0    m_graident = 0    for i in range(0 , len(x)):        x = X[i]        y = Y[i]        b_graident +=(-2/N) * (y-(m*x+b))        m_graident += (-2/N) * x*(y-(m*x+b))    new_m = m - alpha*m_graident    new_b = b - alpha*b_graident    return new_m , new_bdef graident_decsent(x,y,m,b,num_itters,alpha):    for i in range(num_itters):        m,b = step_graident_descent(x,y,m,b,alpha)    return m,bdef run():    b=0    m=0    numberOfIttertions = 1000    m,b = graident_decsent(X , Y ,m,b,numberOfIttertions , 0.001)    print(m,b)    if __name__ == '__main__':    run()   

我得到的错误是:

    linearRegression.py:22: RuntimeWarning: overflow encountered in double_scalars  m_graident += (-2/N) * x*(y-(m*x+b))linearRegression.py:21: RuntimeWarning: invalid value encountered in double_scalars  b_graident +=(-2/N) * (y-(m*x+b))linearRegression.py:22: RuntimeWarning: invalid value encountered in double_scalars  m_graident += (-2/N) * x*(y-(m*x+b))

如果有人能帮我解决这个问题,我将不胜感激,因为我已经卡在这上面两个月了,谢谢大家


回答:

编辑:简短解决方案

好的,这就是我之前提到的最小的可重现示例。我将你的X,Y替换为以下内容。

n = 10**2X = np.linspace(0,10**6,n)Y = 1.5*X+0.2*10**6*np.random.normal(size=n)

如果我然后运行

b=0m=0numberOfIttertions = 1000m,b = graident_decsent(X , Y ,m,b,numberOfIttertions , 0.001)

我得到了你描述的问题。唯一令人惊讶的是解决方案的简单性。我只需将你的alpha替换为10**-14,一切就都正常工作了。

如何提供一个最小、可重现的示例

你的示例不可重现,因为我们没有train.csv。一般来说,无论是为了自己理解问题,还是为了得到具体的答案,拥有一个非常小的可运行和调整的示例是非常有帮助的。例如,你可以考虑一个更短的输入来进行回归,从而也导致这个错误。

第一个运行时警告

但现在回到你的问题。你的第一个RuntimeWarning,即

    linearRegression.py:22: RuntimeWarning: overflow encountered in double_scalars  m_graident += (-2/N) * x*(y-(m*x+b))

意味着x和因此m_graidentnumpy.double=numpy.float64类型。这个数据类型可以存储范围为(-1.79769313486e+308, 1.79769313486e+308)的数字。如果你超出这个范围,这就是所谓的溢出。例如,np.double(1.79769313486e+308)仍然可以,但如果你乘以1.1,你就会得到你喜欢的运行时警告。请注意,这只是一个警告,程序仍然可以运行。但它不能给你一个数字,因为它太大了。相反,它会给你inf(无穷大)。

其他运行时警告

那么

linearRegression.py:21: RuntimeWarning: invalid value encountered in double_scalars  b_graident +=(-2/N) * (y-(m*x+b))

意味着什么呢?

这是因为计算使用了刚刚提到的无穷大。一些使用无穷大的计算是有效的。

np.inf-10**6 -> infnp.inf+10**6 -> infnp.inf/10**6 -> infnp.inf*10**6 -> infnp.inf*(-10**6) -> -inf1/np.inf -> 0np.inf *np.inf -> inf

但有些则不是,会给出nan,即非数字。

np.inf/np.inf np.inf-np.inf 

这些在数学中被称为不定形式,因为这取决于你是如何得到无穷大的,你会得到什么结果。例如,

(np.double(1e+309)+np.double(1e+309))-np.double(1e+309)np.double(1e+309)-(np.double(1e+309)+np.double(1e+309))

都是inf-inf,但你会期望得到不同的结果。得到nan是不幸的,因为与nan的计算总是会得到nan。一旦你添加了一个nan,你就不能再使用你的梯度了。

其他资源

另一个选择是使用现有的线性回归实现。例如,来自scikit-learn的实现。参见

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注