如何修复二元线性回归代码中的Invalid index to scalar variable错误?
解决二元线性回归中的
IndexError: invalid index to scalar variable问题 咱先拆解一下你代码里的几个关键问题,正是这些小疏漏导致了这个错误,一步步来修正:
错误根源分析
你遇到的IndexError是因为在cost函数里,传入的x变成了单个数值(标量),然后你尝试用x[0]去索引它——标量根本没有索引,自然就报错了。追根溯源是gradientDescent函数里错误地把单个样本传给了cost和diffGradient,再加上其他几个函数的小错误,连锁导致了这个问题。
逐个修正问题
1. 修正gradientDescent函数的样本传递错误
在你的gradientDescent循环里,d = x[i]这一行完全没必要,而且会把单个样本传给cost和diffGradient——这两个函数都是为整个数据集设计的,应该直接传入完整的x,而不是单个样本。
同时,循环里的theta更新要基于整个数据集计算的梯度,而不是单个样本。
2. 修正diffGradient函数的逻辑错误
- 这个函数的目的是计算梯度,最后应该返回计算好的
grad,而不是return 0; - 循环中要针对每个样本计算预测值,所以
hx = hypothesis(theta, x[i]),而不是x; - 梯度计算时,要取当前样本的特征,也就是
x[i][0]和x[i][1],而不是x[0]和x[1]。
3. 梯度更新时添加样本数归一化(重要优化)
标准的梯度下降计算中,梯度需要除以样本数量m,避免因为样本数多少导致梯度幅度过大,影响收敛速度和稳定性。
修正后的完整代码
import matplotlib.pyplot as plt import numpy as np x = np.array([[1,1],[1,2],[2,3],[3,4],[4,5],[5,6]]) y = np.array([2,3,5,7,9,11]) # 假设函数 def hypothesis(theta, x): return theta[0] + theta[1]*x[0] + theta[2]*x[1] # 代价函数 def cost(theta, x, y): m = x.shape[0] error = 0 for i in range(m): d = x[i] hx = hypothesis(theta, d) error += (hx - y[i])**2 return error # 梯度计算函数 def diffGradient(theta, x, y): grad = np.zeros((3,)) m = x.shape[0] for i in range(m): hx = hypothesis(theta, x[i]) # 针对单个样本计算预测值 grad[0] += (hx - y[i]) grad[1] += (hx - y[i]) * x[i][0] # 取当前样本的第一个特征 grad[2] += (hx - y[i]) * x[i][1] # 取当前样本的第二个特征 return grad # 返回计算好的梯度 # 梯度下降函数 def gradientDescent(x, y, learning_rate = 0.001): theta = [-2.0,0.0,1.0] iter_num = 1000 # 增加迭代次数,让收敛更充分 error_list = [] theta_list = [] m = x.shape[0] for i in range(iter_num): grad = diffGradient(theta, x, y) # 传入完整数据集计算梯度 e = cost(theta, x, y) # 传入完整数据集计算代价 error_list.append(e) theta_list.append((theta[0],theta[1],theta[2])) # 同步更新theta,同时除以样本数m theta[0] -= learning_rate * grad[0] / m theta[1] -= learning_rate * grad[1] / m theta[2] -= learning_rate * grad[2] / m return theta, theta_list, error_list final_theta, theta_list, error_list = gradientDescent(x,y) print("最终theta值:", final_theta)
运行结果说明
修正后的代码运行后,你会发现错误消失了,最终的theta会趋近于理想值[0, 1, 1](因为你的y正好是两个输入特征的和),同时error_list会呈现逐渐下降的趋势,说明梯度下降在正常收敛。
内容的提问来源于stack exchange,提问作者iwrestledthebeartwice
相关产品推荐
相关产品推荐

