我尝试使用这段代码来进行多变量回归以寻找系数,但无法找到我犯错的地方或者确认我是否走在正确的道路上?问题在于均方误差(mse)值无法收敛。
这里的x1, x2, x3是我拥有的三个特征变量(我已经将每个特征列切片到这些x1, x2, x3变量中)。
def gradientDescent(x,y): mCurrent1=mCurrent2=mCurrent3=bCurrent=0 iteration=1000 learningRate=0.0000001 n=len(x) for i in range(0,iteration): y_predict=mCurrent1*x1+mCurrent2*x2+mCurrent3*x3+bCurrent mse=(1/n)*np.sum([val**2 for val in (y-y_predict)]) mPartDerivative1=-(2/n)*np.sum(x1*(y-y_predict)) mPartDerivative2=-(2/n)*np.sum(x2*(y-y_predict)) mPartDerivative3=-(2/n)*np.sum(x3*(y-y_predict)) bPartDerivative=-(2/n)*np.sum(y-y_predict) mCurrent1=mCurrent1-(learningRate*mPartDerivative1) mCurrent2=mCurrent2-(learningRate*mPartDerivative2) mCurrent3=mCurrent3-(learningRate*mPartDerivative3) bCurrent=bCurrent-(learningRate*bPartDerivative) print('m1:{} m2:{} m3:{} b:{} iter:{} mse:{}'.format(mCurrent1,mCurrent2,mCurrent3,bCurrent,i,mse)) return(round(mCurrent1,3),round(mCurrent2,3),round(mCurrent3,3),round(bCurrent,3))
回答:
看起来你的程序应该能工作。然而,你的学习率可能太小了。请记住,学习率是你沿着成本函数下降的步长大小。如果学习率太小,它会在成本曲线上移动得太慢,需要很长时间才能达到收敛(需要大量的迭代次数)。然而,如果学习率太大,那么你会遇到发散的问题。选择正确的学习率和迭代次数(换句话说,调整你的超参数)更像是一门艺术而不是科学。你应该尝试不同的学习率。
我创建了自己的数据集并随机生成了数据(其中(m1, m2, m3, b) = (10, 5, 4, 2)
),然后运行了你的代码:
import pandas as pdimport numpy as npx1 = np.random.rand(100,1)x2 = np.random.rand(100,1)x3 = np.random.rand(100,1)y = 2 + 10 * x1 + 5 * x2 + 4 * x3 + 2 * np.random.randn(100,1)df = pd.DataFrame(np.c_[y,x1,x2,x3],columns=['y','x1','x2','x3'])#df.head()# y x1 x2 x3# 0 11.970573 0.785165 0.012989 0.634274# 1 19.980349 0.919672 0.971063 0.752341# 2 2.884538 0.170164 0.991058 0.003270# 3 8.437686 0.474261 0.326746 0.653011# 4 14.026173 0.509091 0.921010 0.375524
以0.0000001
的学习率运行你的算法会得到以下结果:
(m1, m2, m3, b) = (0.001, 0.001, 0.001, 0.002)
以.1
的学习率运行你的算法会得到以下结果:
(m1, m2, m3, b) = (9.382, 4.841, 4.117, 2.485)
请注意,当学习率为0.0000001
时,你的系数与它们开始时的值(0
)没有太大差异。正如我之前所说,较小的学习率使得我们以非常小的步长沿成本函数移动,从而改变系数的速度太慢了。
我添加了一张图片来帮助可视化选择步长的大小。请注意,第一张图片使用了较小的学习率,第二张使用了较大的学习率。