多元回归值不收敛的梯度下降
Gradient Descent for multivariate Regression value not converging
我已经尝试了这段用于多变量回归的代码来查找系数,但找不到我在哪里出错或者我是否走在正确的道路上?
问题是 mse 值没有收敛。
这里 x1 、 x2 、 x3 是我拥有的 3 个特征变量(我已将每个特征列切成这些 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))
看起来你的程序应该可以工作。但是,您的学习率可能太小了。请记住,学习率是您降低成本函数的步长。学习率太小,成本曲线下移速度太慢,收敛时间长(需要大迭代次数)。但是,如果学习率太大,就会出现发散问题。选择正确的学习率和迭代次数(换句话说,调整超参数)与其说是一门科学,不如说是一门艺术。你应该尝试不同的学习率。
我创建了自己的数据集和 运行domly 生成的数据(其中 (m1, m2, m3, b) = (10, 5, 4, 2)
)和 运行 你的代码:
import pandas as pd
import numpy as np
x1 = 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
) 差别不大。就像我之前说的,学习率很小,所以我们改变系数的速度太小了,因为我们正在以超小的步长向下移动成本函数。
我添加了一张图片来帮助可视化选择步长。注意第一张图片使用了小的学习率,第二张使用了较大的学习率
小学习率:
大学习率:
这里 x1 、 x2 、 x3 是我拥有的 3 个特征变量(我已将每个特征列切成这些 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))
看起来你的程序应该可以工作。但是,您的学习率可能太小了。请记住,学习率是您降低成本函数的步长。学习率太小,成本曲线下移速度太慢,收敛时间长(需要大迭代次数)。但是,如果学习率太大,就会出现发散问题。选择正确的学习率和迭代次数(换句话说,调整超参数)与其说是一门科学,不如说是一门艺术。你应该尝试不同的学习率。
我创建了自己的数据集和 运行domly 生成的数据(其中 (m1, m2, m3, b) = (10, 5, 4, 2)
)和 运行 你的代码:
import pandas as pd
import numpy as np
x1 = 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
) 差别不大。就像我之前说的,学习率很小,所以我们改变系数的速度太小了,因为我们正在以超小的步长向下移动成本函数。
我添加了一张图片来帮助可视化选择步长。注意第一张图片使用了小的学习率,第二张使用了较大的学习率
小学习率:
大学习率: