機器學習之線性迴歸

我們有一個數據集,其中包含有關“學習小時數”與“獲得的分數”之間關係的信息。已經觀察到許多學生,並記錄他們的學習時間和成績。這將是我們的訓練數據。目標是設計一個模型,給定學習時間可以預測成績。使用訓練數據,獲得將會給出最小誤差的迴歸線。然後這個線性方程可以用於任何新的數據。也就是說,如果我們將學習時間作爲輸入,我們的模型應該以最小誤差預測它們的分數。

 

Y(pred)= alpha + beta * x

 

爲了使誤差最小化,必須確定alpha和beta。如果平方誤差和被用作評估模型的度量,目標是獲得最小化這個誤差的直線。

如果我們不對這個錯誤進行平方,那麼正面和負面的樣本誤差就會相互抵消。

爲了估計模型的參數alpha和beta,我們已知一組樣本(yi, xi)(其中i=1,2,…,n),其計算的目標爲最小化殘差平方和:

使用微分法求極值:將上式分別對alpha 和 beta 做一階偏微分,並令其等於0:

此二元一次線性方程組可用克萊姆法則求解,得解

探索

• 如果> 0,則x(預測變量)和y(目標)具有正相關關係,y隨x的增加而增加。

• 如果 <0,則x(自變量)和y(目標)具有負相關關係,y隨x的增加而減少。

 

探索

• 如果沒有這個項,那麼擬合線將超過原點。 迴歸係數和預測都會有偏差。偏置補償了目標值y的平均值(在訓練集)與自變量x平均值和的乘積之間的偏差。

 

 

標準方程係數(Co-efficient from Normal equations)

 

除了上述方程外,模型的係數也可以用標準方程計算。

Theta包含所有預測因子的係數,包括常數項。 標準方程通過對輸入矩陣取逆來執行計算。 隨着函數數量的增加,計算的複雜性將會增加。 當樣本特徵維數變大時,求逆會比較耗時。

 

 

 

import numpy as np
from sklearn.utils import shuffle
from sklearn.datasets import load_diabetes

class lr_model():    
    def __init__(self):        
        pass

    def prepare_data(self):
        data = load_diabetes().data
        target = load_diabetes().target
        X, y = shuffle(data, target, random_state=42)
        X = X.astype(np.float32)
        y = y.reshape((-1, 1))
        data = np.concatenate((X, y), axis=1)        
        return data   
         
    def initialize_params(self, dims):
        w = np.zeros((dims, 1))
        b = 0
        return w, b    
    
    def linear_loss(self, X, y, w, b):
        num_train = X.shape[0]
        num_feature = X.shape[1]

        y_hat = np.dot(X, w) + b
        loss = np.sum((y_hat-y)**2) / num_train
        dw = np.dot(X.T, (y_hat - y)) / num_train
        db = np.sum((y_hat - y)) / num_train        
        return y_hat, loss, dw, db    
    
    def linear_train(self, X, y, learning_rate, epochs):
        w, b = self.initialize_params(X.shape[1])        
        for i in range(1, epochs):
            y_hat, loss, dw, db = self.linear_loss(X, y, w, b)
            w += -learning_rate * dw
            b += -learning_rate * db            
            if i % 10000 == 0:
                print('epoch %d loss %f' % (i, loss))
            
            params = {                
                'w': w,                
                'b': b
            }
            grads = {                
                'dw': dw,                
                'db': db
            }        
         return loss, params, grads    
    
     def predict(self, X, params):
        w = params['w']
        b = params['b']
        y_pred = np.dot(X, w) + b        
        return y_pred    
        
     def linear_cross_validation(self, data, k, randomize=True):        
        if randomize:
            data = list(data)
            shuffle(data)

        slices = [data[i::k] for i in range(k)]        
        for i in range(k):
            validation = slices[i]
            train = [data                        
            for s in slices if s is not validation for data in s]
            train = np.array(train)
            validation = np.array(validation)            
            yield train, validation
            
            
if __name__ == '__main__':
    lr = lr_model()
    data = lr.prepare_data()   
 
    for train, validation in lr.linear_cross_validation(data, 5):
        X_train = train[:, :10]
        y_train = train[:, -1].reshape((-1, 1))
        X_valid = validation[:, :10]
        y_valid = validation[:, -1].reshape((-1, 1))

        loss5 = []
        loss, params, grads = lr.linear_train(X_train, y_train, 0.001, 100000)
        loss5.append(loss)
        score = np.mean(loss5)
        print('five kold cross validation score is', score)
        y_pred = lr.predict(X_valid, params)
        valid_score = np.sum(((y_pred - y_valid) ** 2)) / len(X_valid)
        print('valid score is', valid_score)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章