我目前正在学习梯度下降,所以我编写了一段使用梯度下降和线性回归的代码。然而,我得到的线不是最好的线。我计算了线性回归与梯度下降和最小二乘误差回归的误差。无论我使用什么数据,最小二乘误差总是给我一个低得多的误差。我决定看看斜坡和y拦截两者都会出现。使用梯度下降的y截距总是非常接近于零,就好像它没有正确地改变一样。我发现这很奇怪,我不知道发生了什么。我是否以某种方式错误地实施了梯度下降?
import matplotlib.pyplot as plt
datax=[]
datay=[]
def gradient(b_current,m_current,learningRate):
bgradient=0
mgradient=0
N=float(len(datax))
for i in range(0,len(datax)):
bgradient+= (-2/N)*(datay[i]-((m_current*datax[i])+b_current))
mgradient+= (-2/N)*datax[i]*(datay[i]-((m_current*datax[i])+b_current))
newb=b_current-(bgradient*learningRate)
newm=m_current-(mgradient*learningRate)
return newm,newb
def basic_linear_regression(x, y):
# Basic computations to save a little time.
length = len(x)
sum_x = sum(x)
sum_y = sum(y)
# sigma x^2, and sigma xy respectively.
sum_x_squared = sum(map(lambda a: a * a, x))
sum_of_products = sum([x[i] * y[i] for i in range(length)])
# Magic formulae!
a = (sum_of_products - (sum_x * sum_y) / length) / (sum_x_squared - ((sum_x ** 2) / length))
b = (sum_y - a * sum_x) / length
return a, b
def error(m,b,datax,datay):
error=0
for i in range(0,len(datax)):
error+=(datay[i]-(m*datax[i]+b))
return error/len(datax)
def run():
m=0
b=0
iterations=1000
learningRate=.00001
for i in range(0,iterations):
m,b=gradient(b,m,learningRate)
print(m,b)
c,d=basic_linear_regression(datax,datay)
print(c,d)
gradientdescent=error(m,b,datax,datay)
leastsquarederrors=error(c,d,datax,datay)
print(gradientdescent)
print(leastsquarederrors)
plt.scatter(datax,datay)
plt.plot([0,300],[b,300*m+b])
plt.axis('equal')
plt.show()
run()
答案 0 :(得分:0)
我看到学习率有时在0.01的范围内。这可能是您需要超过1000次迭代的原因,因为您的学习率为0.00001,除非您的数据集很小。学习率越小,收敛所需的迭代越多。
我注意到的另一件事是你正在修复迭代次数。你永远无法确定你的成本函数是否会在第1000次迭代时达到/接近全局最小值。特别是如此低的学习率,如果您需要超过1000次迭代怎么办?为了解决这个问题 - 尝试使用while循环并在此循环内部,添加成本函数差异的计算(delta J)并保持循环直到(delta J < Threshold)
,其中阈值通常保持非常低(在0.01的范围内)或0.001)。然后在跳出while循环后再使用cost函数,并将其与从OLS方法获得的函数进行比较。