线性回归梯度计算出现KeyError(1)问题求助
线性回归梯度计算时KeyError(1)问题排查
问题概述
计算线性回归模型梯度时触发KeyError(1),怀疑与维度相关,但无法定位具体原因。
梯度函数说明
计算线性回归的梯度
- 参数:
- X (ndarray (m,n)): 数据集,包含m个样本,每个样本有n个特征
- y (ndarray (m,)) : 样本对应的目标值
- w (ndarray (n,)) : 模型权重参数
- b (scalar) : 模型偏置参数
- 返回值:
- dj_dw (ndarray (n,)): 代价函数关于权重w的梯度
- dj_db (scalar): 代价函数关于偏置b的梯度
实现代码
import numpy as np def gradient(X, y, w, b): m,n = X.shape #(样本数量, 特征数量) dj_dw = np.zeros((n,)) dj_db = 0 for i in range(m): err = (np.dot(X[i],w) + b) - y[i] for j in range(n): dj_dw[j] = dj_dw[j] + err * X[i, j] dj_db = dj_db + err dj_dw = dj_dw / m dj_db = dj_db / m return dj_db, dj_dw b_init = 785.1811367994083 w_init = np.array([ 0.39133535, 18.75376741, -53.36032453, -26.42131618,-33.2342342]) tmp_dj_db, tmp_dj_dw = gradient(X_train, y_train, w_init, b_init) print(f'dj_db at initial w,b: {tmp_dj_db}') print(f'dj_dw at initial w,b: \n {tmp_dj_dw}')
报错信息
KeyError Traceback (most recent call last) /usr/local/lib/python3.7/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance) 3360 try: -> 3361 return self._engine.get_loc(casted_key) 3362 except KeyError as err: 6 frames /usr/local/lib/python3.7/dist-packages/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() /usr/local/lib/python3.7/dist-packages/pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item() pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.Int64HashTable.get_item() KeyError: 1 The above exception was the direct cause of the following exception: KeyError Traceback (most recent call last) <ipython-input-73-1f87825d3f02> in <module> 1 b_init = 785.1811367994083 2 w_init = np.array([ 0.39133535, 18.75376741, -53.36032453, -26.42131618,-33.2342342]) ----> 3 tmp_dj_db, tmp_dj_dw = gradient(X_train, y_train, w_init, b_init) 4 print(f'dj_db at initial w,b: {tmp_dj_db}') 5 print(f'dj_dw at initial w,b: \n {tmp_dj_dw}') <ipython-input-72-52811c00c1ad> in gradient(X, y, w, b) 16 dj_db = 0 17 for i in range(m): ---> 18 err = (np.dot(X.iloc[i,],w) + b) - y[i] 19 for j in range(n): 20 dj_dw[j] = dj_dw[j] + err * X.iloc[i, j] /usr/local/lib/python3.7/dist-packages/pandas/core/series.py in __getitem__(self, key) 940 941 elif key_is_scalar: ---> 942 return self._get_value(key) 943 944 if is_hashable(key): /usr/local/lib/python3.7/dist-packages/pandas/core/series.py in _get_value(self, label, takeable) 1049 1050 # Similar to Index.get_value, but we do not fall back to positional -> 1051 loc = self.index.get_loc(label) 1052 return self.index._get_values_for_loc(self, loc, label) 1053 /usr/local/lib/python3.7/dist-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance) 3361 return self._engine.get_loc(casted_key) 3362 except KeyError as err: -> 3363 raise KeyError(key) from err 3364 3365 if is_scalar(key) and isna(key) and not self.hasnans: KeyError: 1
问题原因与解决方案
原因分析
从报错栈可以看出:
- 代码实际使用
X.iloc[i,],说明X_train是Pandas DataFrame,但函数定义假设输入为numpy ndarray,两者索引逻辑存在差异。 y[i]是按标签索引取值,若y_train为Pandas Series且索引不是连续的0起始整数序列(比如数据筛选后未重置索引),循环到i=1时会因找不到标签为1的元素抛出KeyError。
解决方案
方案1:将输入数据转为numpy数组
在调用梯度函数前,把Pandas格式数据集转为numpy ndarray,匹配函数参数要求:
# 转换数据格式 X_train = X_train.to_numpy() y_train = y_train.to_numpy() # 调用梯度函数 tmp_dj_db, tmp_dj_dw = gradient(X_train, y_train, w_init, b_init)
方案2:修改梯度函数适配Pandas数据
若需保留Pandas格式,修改函数内索引方式,统一使用位置索引:
def gradient(X, y, w, b): m,n = X.shape dj_dw = np.zeros((n,)) dj_db = 0 for i in range(m): # 用iloc按位置取y元素,X转为numpy数组计算点积 err = (np.dot(X.iloc[i].values, w) + b) - y.iloc[i] for j in range(n): dj_dw[j] = dj_dw[j] + err * X.iloc[i, j] dj_db = dj_db + err dj_dw = dj_dw / m dj_db = dj_db / m return dj_db, dj_dw
内容的提问来源于stack exchange,提问作者Arshdeep Singh
相关产品推荐
相关产品推荐

