波士顿房价预测项目Cost Function报错:Data must be 1-dimensional
解决波士顿房价预测中Cost Function的"Data must be 1-dimensional"错误
嘿,看起来你在手动实现线性回归模型时踩了维度不匹配的坑!这个错误的核心是你的预测输出Z_train和真实标签Y_train维度完全不兼容,导致运算后生成了二维数据,而pandas在处理时要求数据必须是一维的。咱们一步步拆解问题并修复:
错误根源分析
- 权重矩阵维度完全搞反了:你初始化的
self.w = 2 * np.random.rand(2,455) -1不符合线性回归的维度逻辑——假设你的X_train是455个样本、2个特征(维度(455,2)),那权重w应该是(2,1)(特征数×1),这样和X_train做矩阵乘法后才能得到(455,1)的预测值,和Y_train的维度匹配。现在的w会让你得到(455,455)的二维预测结果,和一维的Y_train相减后必然出问题。 - 反向传播的梯度计算顺序错误:
dw = np.dot(dz, X.T)的矩阵乘法顺序不对,会导致维度不匹配,而且损失函数的梯度符号也写反了。 - 数据类型/维度未统一:如果
Y_train是pandas Series,而Z_train是numpy二维数组,两者运算后pandas无法处理二维结构,直接抛出"Data must be 1-dimensional"错误。
修正后的完整代码
import numpy as np # 注意:提前确保X_train是numpy数组;如果Y_train是pandas Series,先转成numpy数组:Y_train = Y_train.values.reshape(-1,1) class Predictor(): def __init__(self, feature_num): np.random.seed(1) # 正确初始化权重:(特征数, 1) self.w = 2 * np.random.rand(feature_num, 1) - 1 # 偏置保持(1,1)维度 self.b = 2 * np.random.rand(1, 1) - 1 def forward_pass(self, X): # X维度:(样本数, 特征数),dot后得到(样本数,1)的预测值 Y_pred = np.dot(X, self.w) + self.b return Y_pred def cost_function(self, Z_train, Y_train): m = Z_train.shape[0] # 现在Z_train和Y_train都是(455,1)的numpy数组,运算不会有维度问题 J = (1/m) * np.sum(np.square(Z_train - Y_train)) print(f"当前损失值:{J:.4f}") return J def back_prop(self, X, Y_train, Z_train): m = X.shape[0] # 修正梯度符号:应该是预测值减真实值 dz = (2/m) * (Z_train - Y_train) # 修正矩阵乘法顺序:X.T在前,得到(特征数,1)的dw,和w维度匹配 dw = np.dot(X.T, dz) # 偏置梯度取平均,保持(1,1)维度 db = np.sum(dz) / m return dw, db def gradient_descent(self, dw, db, learning_rate=0.01): # 更新权重和偏置,学习率改成可配置参数(原来的0.5太大容易爆炸) self.w = self.w - learning_rate * dw self.b = self.b - learning_rate * db return self.w, self.b def linear_regression_model(self, X_train, Y_train, epochs, learning_rate=0.01): # 统一Y_train维度:如果是一维数组,转成(样本数,1) if len(Y_train.shape) == 1: Y_train = Y_train.reshape(-1,1) costs_train = [] for i in range(epochs): Z_train = self.forward_pass(X_train) cost_train = self.cost_function(Z_train, Y_train) dw, db = self.back_prop(X_train, Y_train, Z_train) self.w, self.b = self.gradient_descent(dw, db, learning_rate) if i % 10 == 0: costs_train.append(cost_train) print(f"迭代次数:{i},训练损失:{cost_train:.4f}") return costs_train if __name__ == "__main__": # 替换成你实际的训练数据,这里用随机数做示例 X_train = np.random.rand(455, 2) Y_train = np.random.rand(455, 1) predictor = Predictor(feature_num=2) print("初始随机权重 W: ") print(predictor.w) print("初始随机偏置 B: ") print(predictor.b) # 建议从0.01开始尝试学习率,避免梯度爆炸 costs = predictor.linear_regression_model(X_train, Y_train, epochs=10000, learning_rate=0.01) print("训练后的权重 W: ") print(predictor.w) print("训练后的偏置 B: ") print(predictor.b)
关键修正点总结
- 把权重
w的维度改成(特征数, 1),确保矩阵乘法后得到正确的一维预测结果(相对于样本维度)。 - 在模型入口统一
Y_train的维度,避免pandas和numpy混合运算的兼容性问题。 - 修正反向传播的梯度符号和矩阵乘法顺序,保证梯度更新的维度正确。
- 降低学习率并改成可配置参数,防止过大的学习率导致模型无法收敛。
内容的提问来源于stack exchange,提问作者Oscar Fuentes
相关产品推荐
相关产品推荐

