You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义LinearModel类predict方法报错:矩阵广播不匹配求助

解决自定义LinearModel线性回归类的predict方法广播错误

我手动实现了一个不依赖Sklearn的线性回归类LinearModel,但在调用predict方法时出现矩阵广播错误,报错信息如下:

ValueError: operands could not be broadcast together with shapes (4,3) (2,)

初始代码

import numpy as np

class LinearModel:
    def __init__(self, X, y):
        self.X = X
        self.y = y
        # X columns of 1s appended on its left,
        X = np.vstack((np.ones((X.shape[0], )), X.T)).T
        
        if len(self.X)!=len(y):
            raise ("they are not similar")

    def fit(self):
        # stores this coefficient vector in the object.
        Xt = np.transpose(X)
        XtX = np.dot(Xt,X)
        Xty = np.dot(Xt,y)
        beta = np.linalg.solve(XtX,Xty)
        self.fit = beta
        
     
    def coef(self):
       # raise an error if called before the model has been fitted

        if not self.fit:
            raise ValueError("Need to call the fit function first")

        #returns βˆ.
        return self.fit

    
    def predict(self,X0=None): # Takes an optional argument X0
           
        if not self.fit:
            raise ValueError("Need to call the fit function first")
        if X0==None:
            X0 = X
        X0 = np.vstack((np.ones((X0.shape[0], )), X0.T)).T

        # where X0 is X0 with column of 1s added on its left. 
        prediction = self.fit * X0  # method should return X0 * βˆ 
        return prediction



X = np.array([[-1.34164079, -1.25675744], [-0.4472136, -0.48336824],
                          [0.4472136, 0.29002095], [1.34164079, 1.45010473]])
y = np.array([1, 3, 4, 6])
model = LinearModel(X, y)
model.fit()
print(model.coef())
print(model.predict())

修改后的代码

import numpy as np

class LinearModel:
    def __init__(self, X, y):
        self.X = X
        self.y = y
        #X columns of 1s appended on its left,
        X = np.vstack((np.ones((X.shape[0], )), X.T)).T
       
        
        if len(self.X)!=len(y):
            raise ("they are not similar")

        self._is_fitted : bool = False

    def fit(self):
        
        Xt = np.transpose(X)
        XtX = np.dot(Xt,X)
        Xty = np.dot(Xt,y)
        beta = np.linalg.solve(XtX,Xty)
        beta_array = np.array(beta)
        self.fit = beta_array
        self._is_fitted = True
        
        
     
    def coef(self):
       # raise an error if called before the model has been fitted

        if not self._is_fitted:
            raise ValueError("Need to call the fit function first")

        #returns βˆ
        return self.fit

    
    def predict(self,X0=None): # Takes an optional argument X0
           
       
        if not self._is_fitted:
            raise ValueError("Need to call the fit function first")
        if X0==None:
            X0 = X
        X0 = np.vstack((np.ones((X0.shape[0], )), X0.T)).T
        # where X0 is X0 with column of 1s added on its left. 
        prediction = np.multiply(X0, self.fit)  # method should return X0 * βˆ 
        return prediction
         


X = np.array([[-1.34164079, -1.25675744], [-0.4472136, -0.48336824],
                          [0.4472136, 0.29002095], [1.34164079, 1.45010473]])
y = np.array([1, 3, 4, 6])

model = LinearModel(X, y)
model.fit()
print(model.coef())
print(model.predict())

错误原因分析

  1. 变量作用域错误:__init__中处理后的带截距的X是局部变量,fit方法中直接使用的X实际是全局的原始特征数组(未加截距),导致计算出的beta维度为(2,),而predict中生成的X0是加了截距的(4,3)数组,两者形状不匹配,触发广播错误。
  2. 矩阵乘法方式错误:predict中使用np.multiply(元素级相乘)而非矩阵点乘,线性回归的预测应该是带截距的特征矩阵与系数向量做矩阵乘法,得到每个样本的预测值。
  3. 属性命名冲突:将系数赋值给self.fit,覆盖了类的fit方法,属于不合理命名。

修复方案

修改后的完整代码如下:

import numpy as np

class LinearModel:
    def __init__(self, X, y):
        self.X = X
        self.y = y
        # 保存带截距的特征矩阵为实例变量
        self.X_with_intercept = np.vstack((np.ones((X.shape[0], )), X.T)).T
        
        if len(self.X) != len(y):
            raise ValueError("Feature and target lengths do not match")

        self._is_fitted = False
        self.beta = None  # 用beta存储系数,避免覆盖fit方法

    def fit(self):
        # 使用实例中的带截距特征矩阵计算系数
        Xt = self.X_with_intercept.T
        XtX = np.dot(Xt, self.X_with_intercept)
        Xty = np.dot(Xt, self.y)
        self.beta = np.linalg.solve(XtX, Xty)
        self._is_fitted = True
        
    def coef(self):
        if not self._is_fitted:
            raise ValueError("Need to call the fit function first")
        return self.beta

    def predict(self, X0=None):
        if not self._is_fitted:
            raise ValueError("Need to call the fit function first")
        
        if X0 is None:
            X0 = self.X
        # 对输入的X0添加截距列
        X0_with_intercept = np.vstack((np.ones((X0.shape[0], )), X0.T)).T
        # 使用矩阵点乘计算预测值,X0_with_intercept (n,3) @ beta (3,) -> (n,)
        prediction = np.dot(X0_with_intercept, self.beta)
        return prediction


X = np.array([[-1.34164079, -1.25675744], [-0.4472136, -0.48336824],
                          [0.4472136, 0.29002095], [1.34164079, 1.45010473]])
y = np.array([1, 3, 4, 6])

model = LinearModel(X, y)
model.fit()
print(model.coef())
print(model.predict())

修复要点说明

  • 将带截距的特征矩阵保存为实例变量self.X_with_intercept,确保fit方法使用正确的特征矩阵计算系数,得到维度为(3,)的系数向量(截距+两个特征系数)。
  • 使用self.beta存储系数,避免与fit方法名冲突。
  • predict方法中使用np.dot(或@运算符)进行矩阵点乘,确保形状匹配,得到正确的预测值数组(形状为(4,))。
  • 修正异常抛出方式,使用ValueError而非直接抛出字符串。

内容的提问来源于stack exchange,提问作者Dome

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:40:39