简体   繁体   中英

Linear Regression without Sklearn

I am trying to write a class LinearModel, representing a linear regression model. it gives an error for def predict

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())

edits

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())

it gives an error of ValueError: operands could not be broadcast together with shapes (4,3) (2,) meaning that I will have to to broadcasting to multiply 2 matrices. Can anymore suggest me how?

  1. You can't use a method name as an attribute. Is self.fit supposed to be a method to fit? Or the coefficients?

  2. You can't test if that attribute (let's call it beta ) is assigned simply by saying if self.beta or something similar. First of all, if it is not, you'll get an error for trying to read an unassigned variable. Secondly, and that is the error you get, if that beta contains something that is neither True nor False, you'll get an error about Truth value. So, assign a value to beta in the __init__ method. For example self.beta=None . And then test if it is None with if beta is None .

  3. All attributes access must be prefixed with self. . You are using X instead of self.X more than once. Which means that those X are the global one. The one to which you haven't added a column of 1 .

  4. self.beta * X0 is not doing what you expect to do. * is a member×member multiplication, not a matrix multiplication (and if it were a matrix multiplication it would be an illegal one). @ (or .dot ) is the matrix multiplication operator. And to multiply a 3×n matrix by a 3 elements vector, you need to do it the other way. So X0 @ self.beta

  5. [Non fatal] There is a np.hstack function, rather than vstack + double transpose .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM