批量梯度下降(Batch Gradient Descent)收敛但误差过大问题排查
批量梯度下降实现线性回归的误差问题
我正在为线性回归模型编写一个基于**批量梯度下降(Batch Gradient Descent)**的函数,其中theta0为截距,theta1为斜率。算法已收敛,但拟合结果存在极大误差——红线是sklearn的linregress()结果,蓝线是我实现的拟合线。
我的实现代码如下:
def gradient_descent(alpha, x, y): m = len(x) theta0 = x.iloc[5] theta1 = x.iloc[6] J = sum([(theta0 + theta1*x.iloc[i] - y.iloc[i])**2 for i in range(m-1)]) for j in range(1, m): grad0 = 1/m * sum([(theta0 + theta1*x.iloc[i] - y.iloc[i]) for i in range(1, m)]) grad1 = 1/m * sum([(theta0 + theta1*x.iloc[k] - y.iloc[k])*x.iloc[k] for k in range(1, m)]) # print(sum([(theta0 + theta1*x.iloc[j] - y.iloc[j]) for j in range(1, m)])) # print(grad1) theta0 -= alpha * grad0 theta1 -= alpha * grad1 # e = sum([(theta0 + theta1*x.iloc[i] - y.iloc[i])**2 for i in range(m)]) # print((e)) return theta0, theta1
问题修复要点
- 参数初始值错误:用
x.iloc[5]和x.iloc[6]作为初始值完全不符合梯度下降的要求,应该将theta0和theta1初始化为0或小随机数。 - 样本遍历不全:计算损失和梯度时,分别漏掉了最后一个样本和第一个样本,必须遍历全部
m个样本(用range(m))。 - 迭代次数不合理:仅迭代
m-1次远远不够,梯度下降需要足够多的迭代次数(如几百到上千次),建议将迭代次数设为可配置的超参数。 - 代码冗余优化:可以利用Pandas的向量运算替代循环求和,提升效率和可读性。
修改后的代码:
def gradient_descent(alpha, x, y, num_iterations=1000): m = len(x) # 初始化参数为0 theta0 = 0.0 theta1 = 0.0 for _ in range(num_iterations): # 计算所有样本的预测误差 error = theta0 + theta1 * x - y # 计算梯度 grad0 = (1/m) * error.sum() grad1 = (1/m) * (error * x).sum() # 更新参数 theta0 -= alpha * grad0 theta1 -= alpha * grad1 # 可选:监控损失变化,确认收敛 # loss = (error ** 2).sum() / (2*m) # print(f"第{_+1}轮迭代,损失值:{loss:.4f}") return theta0, theta1
内容的提问来源于stack exchange,提问作者Yash Sharma
相关产品推荐
相关产品推荐

