簡體   English   中英

沒有 Sklearn 的線性回歸

[英]Linear Regression without Sklearn

我正在嘗試編寫一個 class LinearModel,表示線性回歸 model。它給出了 def 預測的錯誤

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

編輯

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

它給出了 ValueError 錯誤:操作數無法與形狀 (4,3) (2,) 一起廣播,這意味着我將不得不廣播以乘以 2 個矩陣。 可以再建議我怎么做嗎?

  1. 您不能將方法名稱用作屬性。 self.fit應該是一種適合的方法嗎? 還是系數?

  2. 您不能簡單地通過說出if self.beta或類似的東西來測試是否分配了該屬性(讓我們稱之為beta )。 首先,如果不是,您將在嘗試讀取未分配的變量時遇到錯誤。 其次,這就是你得到的錯誤,如果那個beta包含既不是真也不是假的東西,你會得到關於真值的錯誤。 因此,在__init__方法中為beta賦值。 例如self.beta=None 然后用if beta is None None

  3. 所有屬性訪問都必須以self. . 您不止一次使用X而不是self.X 這意味着那些X是全局的。 您尚未添加1列的那個。

  4. self.beta * X0沒有做你期望做的事。 *是 member×member 乘法,而不是矩陣乘法(如果它是矩陣乘法,它將是非法的)。 @ (或.dot )是矩陣乘法運算符。 要將 3×n 矩陣乘以 3 元素向量,您需要以另一種方式進行。 所以X0 @ self.beta

  5. [非致命] 有一個np.hstack function,而不是vstack + double transpose

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM