大家好,我正在尝试进行线性回归,当我运行代码时出现了以下问题,我的代码是这样的:
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_graident
是numpy.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
的实现。参见