線性迴歸

1.假設函數 或者 預測函數:

在一維特徵空間,線性迴歸是通過學習一條直線 h_{\theta}(x)=\theta_{0}+\theta_{1} x ,使得這條直線儘可能擬合所有已有的看到的點y,並且希望看到的(數據)也儘可能落落在這條線上(泛化能力),h_{\theta}是預測值,y是實際值。

                                                              h_{\theta}(x)=\theta_{0}+\theta_{1} x

其中參數w0稱爲“偏置”,w1稱爲“權重”,x表示輸入變量X的一個“特徵變量”,這裏先假設只有一個特徵變量。

Note:我這裏用w代表theta,他的實際含義都是“weight”

 

2.成本函數(cost function)或者 損失函數

我們要知道,擬合的函數h(x)有一定的誤差,我們用成本函數J來表示“預測輸出”h(x)與實際輸出y之間的誤差。這裏使用最簡單的“最小均方”(Least mean square)來描述:

                         J\left(\theta_{0}, \theta_{1}\right)=\frac{1}{2 m} \sum_{i=1}^{m}\left(\hat{y}_{i}-y_{i}\right)^{2}=\frac{1}{2 m} \sum_{i=1}^{m}\left(h_{\theta}\left(x_{i}\right)-y_{i}\right)^{2}

所以現在變成了一個優化問題,即找到令損失函數J(theta_)最小的theta,定義均方誤差有着非常好的幾何含義,對應常用的歐式距離,均方誤差最小化進行模型求解的方法稱爲‘最小二乘法’

 

3.參數學習 (梯度下降)或者(最小二乘法)

最小二乘法:

最小二乘法是一種完全數學描述的方法,用矩陣表示J(\theta)=\frac{1}{2}(X \theta-Y)^{2}

,然後展開對其求偏導,令偏導數 \frac{\partial}{\partial \theta} J(\theta)=0,即可得到所求的theta,

                                                        \theta=\left(X^{T} X\right)^{-1} X^{T} Y\theta=\left(X^{T} X\right)^{-1} X^{T} Y

然而用最小二乘法有很多缺陷:例如當特徵數大於樣本數時,這時候的theta會產生很多解,而且當數據量很大時候,矩陣求逆很費時間,所以用到下面的梯度下降法。

梯度下降法:

所以我們現在的目標是,找出怎麼樣的參數,使得假設函數預測得到的誤差最小,也就是最小化成本函數J。

                                                                       \begin{array}{c}{\text { Hypothesis: }} \\ {h_{\theta}(x)=\theta_{0}+\theta_{1} x}\end{array}

                                                                           \begin{array}{c}{\text { Parameters: }} \\ {\theta_{0}, \theta_{1}}\end{array}

                                                         \begin{array}{c}{\text { cost Function: }} \\ {J\left(\theta_{0}, \theta_{1}\right)=\frac{1}{2 m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right)^{2}}\end{array}

                                                                            目標:min J\left(\theta_{0}, \theta_{1}\right)

 

所以按照一般的思路,就是對權重參數求導,使得倒數爲0的參數的值,就是成本函數J取得最小值的地方。但是大多時候,求得的偏導的數學表達式很複雜,所以我們採用一種叫做“梯度下降(gradient descent)”的方法:

                                                                                  \theta_{j} :=\theta_{j}-\alpha \frac{\partial}{\partial \theta_{j}} J\left(\theta_{0}, \theta_{1}\right)

             即:

                                                                \theta_{j} :=\theta_{j}-\frac{\alpha}{m} \sum_{i=1}^{m}\left(h_{\theta}\left(x^{(i)}\right)-y^{(i)}\right) x_{j}^{(i)}

 

 

4.代碼實現(用到梯度下降法):

                  

#導入數據
from sklearn.datasets import load_diabetes
diabetes = load_diabetes()
print(diabetes.keys())

data = diabetes.data
target = diabetes.target
print(data[:5])
print(target[:5])


import numpy as np

X = data[:,:1]
y = target

X_train = X[:-20]#訓練集是除了最後20個
X_test = X[-20:]#測試集是最20個

y_train = y[:-20].reshape((-1,1))
y_test = y[-20:].reshape((-1,1))


#定義線性迴歸到類
class linear():
    def __init__(self):
        self.W = None
        self.b = None
    #定義損失函數
    def loss(self,X,y):
        #num_feature = X.shape(1)#特徵數
        num_train = X.shape[0]#樣本數
        
        h = X.dot(self.W) +self.b
        loss = (0.5/num_train)*np.sum(np.square(h-y))
        
        dW = X.T.dot(h-y)/num_train
        db = np.sum((h-y))/num_train
        
        return loss,dW,db
    
    
    #定義訓練函數
    def train(self,X,y,learn_rate = 0.001,iter = 10000):
        num_feature = X.shape[1]
        self.W = np.zeros((num_feature,1))#這裏如果要成矩陣形狀就需要兩個括號,這裏是看多少特徵就有多少個W
        self.b = 0
        loss_list = []
        
        for i in range(iter):
            loss,dW,db = self.loss(X,y)
            loss_list.append(loss)
            self.W-=learn_rate*dW
            self.b-=learn_rate*db
            
            if i%500 == 0:
                print('迭代次數已經有%d,損失函數爲%f'%(i,loss))
        return loss_list
    #定義測試
    
    def predict(self,X_test):
        y_pred = X_test.dot(self.W) + self.b
        return y_pred
    
    
#開始訓練
classify = linear()
print('start') 
loss_list = classify.train(X_train,y_train) 
print('end')

print(classify.W,classify.b)


#可視化訓練的結果
import matplotlib.pyplot as plt
f = X_train.dot(classify.W) + classify.b
fig = plt.figure()
plt.subplot(211)
plt.scatter(X_train,y_train,color = 'black')
plt.scatter(X_test,y_test,color = 'blue')
plt.plot(X_train,f,color = 'red')
plt.xlabel('X')
plt.ylabel('y')

#查看損失函數
plt.subplot(212)
plt.plot(loss_list,color = 'blue')
plt.xlabel('epochs')
plt.ylabel('errors')
plt.show()

  參考:     https://blog.csdn.net/huakai16/article/details/78123376   

  參考:  https://blog.csdn.net/jk123vip/article/details/80591619                                                                          

 

 

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