基于Numpy的Python线性回归梯度下降:theta更新异常问题
嘿,我当初做这个作业的时候也踩过一模一样的坑!咱们来一步步拆解问题,找到theta更新异常的原因:
可能的问题排查与解决方法
1. 忘记做特征缩放(Feature Scaling)
这是最常见的原因!原作业里的输入特征(比如房屋面积)和目标值(价格)数值范围差异极大,如果不对特征做归一化/标准化,梯度下降会收敛得极慢——1500次循环根本不足以让theta走到正确的收敛点,反而会停在一个错误的局部位置。
你可以试试把特征转换成标准化形式:
def feature_normalize(X): mean = np.mean(X, axis=0) std = np.std(X, axis=0) return (X - mean) / std, mean, std
注意:截距项对应的全1列不需要缩放,只处理实际特征列即可。
2. 梯度更新的实现逻辑错误
要确保所有theta参数是同时更新的,不能先更新theta₀,再用更新后的theta₀去计算theta₁的梯度。正确的做法是先把所有梯度值存在临时变量里,再一次性更新所有theta:
# 正确的更新方式 hypothesis = X @ theta error = hypothesis - y # 计算所有theta的梯度 grad = (1/m) * X.T @ error # 同时更新theta₀和theta₁ theta = theta - alpha * grad
如果你的代码是分开更新theta₀和theta₁,且用了更新后的theta₀去计算theta₁,那结果肯定会出错。
3. 数据预处理与维度错误
检查以下几点:
- 你的X矩阵是否添加了全1的截距项列?原作业里的theta是2维的,X必须是(m,2)的矩阵(m是样本数)。
- 确认y的维度是(m,1)的向量,不是一维数组,否则矩阵乘法会出现广播错误。
- 加载的数据集是否和原作业一致?比如原数据集是97个样本,别不小心漏了或者多了数据。
4. 损失函数计算验证
先计算初始theta=[0,0]时的损失函数J(theta),和原作业的预期值(约32.07)对比。如果J值不对,说明你的假设函数或损失函数实现有误:
hypothesis = X @ theta J = (1/(2*m)) * np.sum((hypothesis - y)**2)
注意分母是2*m,不是m,这也是容易踩的小坑。
示例正确代码片段
import numpy as np # 加载数据集 data = np.loadtxt('ex1data1.txt', delimiter=',') X = data[:, 0].reshape(-1, 1) y = data[:, 1].reshape(-1, 1) m = len(y) # 添加截距项 X = np.hstack((np.ones((m, 1)), X)) # 特征缩放(仅处理第二列特征) X[:, 1], _, _ = feature_normalize(X[:, 1]) # 初始化参数 theta = np.zeros((2, 1)) alpha = 0.01 iterations = 1500 # 梯度下降循环 for _ in range(iterations): hypothesis = X @ theta error = hypothesis - y grad = (1/m) * X.T @ error theta = theta - alpha * grad print(theta)
运行这段代码后,应该就能得到预期的[[-3.630291], [1.166362]]结果了。
内容的提问来源于stack exchange,提问作者Patterson
相关产品推荐
相关产品推荐

