自定义线性回归调用scikit-learn的mean_squared_error报形状错误如何解决
问题根因
- 标签
y的维度不匹配,引发广播错误:你生成的y是形状为(100, 1)的二维数组,而fit方法中计算出的y_predicted是(80,)的一维数组,两者做差时numpy触发广播机制得到(80, 80)的二维数组,后续梯度计算错误,导致最终weights变成80维的向量。预测时X_test(20,1)点乘80维weights,自然得到形状为(20, 80)的错误输出。 - 梯度更新公式写反:梯度下降的更新逻辑是参数 = 参数 - 学习率 * 梯度,你的代码把顺序写反了,即便维度问题修复后也无法正常收敛。
- 噪声参数异常:你设置的高斯噪声标准差为0,相当于没有添加噪声,属于可优化的小问题。
解决步骤
- 修正
y的维度,将y转为一维数组,避免广播错误 - 修正梯度更新公式,符合梯度下降的逻辑
修正后的完整代码
import numpy as np from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error class LinearRegression: def __init__(self, learning_rate=0.001, n_iters=1000): self.lr = learning_rate self.n_iters = n_iters self.weights = None self.bias = None def fit(self, X, y): n_samples, n_features = X.shape # 初始化参数 self.weights = np.zeros(n_features) self.bias = 0 # 确保y是一维数组,避免广播错误 y = y.flatten() for _ in range(self.n_iters): y_predicted = np.dot(X, self.weights) + self.bias # 计算梯度 dw = (1 / n_samples) * np.dot(X.T, (y_predicted - y)) db = (1 / n_samples) * np.sum(y_predicted - y) # 修正更新公式 self.weights -= self.lr * dw self.bias -= self.lr * db def predict(self, X): return np.dot(X, self.weights) + self.bias
# 生成测试数据 X = np.random.uniform(0, 1, 100) X = X.reshape(-1, 1) print(X.shape) # 输出(100, 1) y = [(-19 * i - 9) for i in X] y = np.array(y).flatten() # 修正y为一维数组 # 修正噪声标准差为非0值,可选 noise = np.random.normal(1, 0.1, size=y.shape) y = y + noise # 数据集拆分 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234) print(X_test.shape) # 输出(20, 1) # 训练预测 regression = LinearRegression(learning_rate=0.01, n_iters=1000) regression.fit(X_train, y_train) y_pred = regression.predict(X_test) print(y_pred.shape) # 输出(20,),和y_test的(20,)匹配 # 计算MSE print(mean_squared_error(y_test, y_pred))
内容的提问来源于stack exchange,提问作者Mohsin Mehmood
相关产品推荐
相关产品推荐

