學習筆記(四)線性迴歸

《機器學習實戰》學習筆記(四)線性迴歸

1. 概念

  1. 線性迴歸(Linear Regression):是通過已知的一些數據輸入和其對應的輸出總結學習得出一個線性方程,通過該方程可以對一些未知輸出的輸入進行預測。

2. 特點

  1. 優點:結果易於理解,計算上不復雜。
  2. 缺點:對非線性的數據擬合不好。
  3. 適用數據類型:數值型和標稱型數據。

3. 原理

  1. 線性迴歸函數模型:yi=w0i+w1ix1i+...+wnixniy_i = w_0^i+w_1^ix_1^i+...+w_n^ix_n^i
  2. 爲了便於計算:將w0的係數作爲x0 = 1,原式就可以寫爲矩陣形式:Y=WXY = WX
  3. 以平方誤差來評估實際y值和預測值之間的誤差:loss=i=0n(yixiTw)2=(yXw)T(yXw)loss = \sum_{i=0}^n{(y_i-x_i^Tw)^2} =(y-Xw)^T(y-Xw)
  4. 現在需要求使loss最小的w:
    求導然後是其爲0可得:w=(XTX)1XTyw=(X^TX)^{-1}X^Ty
    1. xTx可逆時:直接求解
    2. 不可逆時:
      1. 直接使用梯度下降法求取平方誤差的最小值。
      2. 採用嶺迴歸的思路,引入參數lambda:w=(XTX+lamI)1XTyw=(X^TX+lamI)^{-1}X^Ty

4. 算法實現

這裏實現了,模擬數據的生成,xTx可逆時求解方法,不可逆時採用了嶺迴歸方法,結果的繪製和預測。

# -*- coding: utf-8 -*-
"""
Created on Thu Feb 28 20:50:30 2019

@author: xinglin
"""
import numpy as np 
import matplotlib.pyplot as plt 

class LinearRegression:
    def __init__(self):
        self.weight = None
    def creatData(self,pointNumber = 100):
        #生成模擬數據
        train_X = np.linspace(-1, 1,pointNumber)
        train_Y = -2 * train_X + 10 + np.random.randn(*train_X.shape) * 0.5 # y=2x,但是加入了噪聲
        #顯示模擬數據點
        # plt.plot(train_X, train_Y, 'ro', label='Original data')
        # plt.legend()
        # plt.show()
        resX = train_X.reshape(pointNumber,1)
        b = np.ones((pointNumber,1))
        # 在特徵前曾加列,值全爲1,表示常數項
        trainDataSet = np.concatenate([b,resX],axis = 1)
        return trainDataSet,train_Y,train_X

    # 基本方法,xTx矩陣不可逆時無法求出結果 w = (XTX)^-1XTy
    def standRegres(self,xArr,yArr):
        xMat = np.mat(xArr)
        yMat = np.mat(yArr)
        xTx = xMat.T*xMat
        if np.linalg.det(xTx) == 0:
            print('This matrix is singular, cannot do inverse')
            return
        ws=np.linalg.solve(xTx,xMat.T*yMat.T)
        self.weight = ws
        return ws
        
    #w = (XTX + lamI)^-1XTy 增加參數,使(XTX + lamI)始終可逆,嶺迴歸,當lam爲0時和standRegres方法一樣
    def linear_regression(self,x_arr, y_arr, lam=0.2):
        x_mat = np.mat(x_arr)
        y_mat = np.mat(y_arr)
    
        x_tx = x_mat.T * x_mat
        denom = x_tx + np.eye(np.shape(x_mat)[1]) * lam
    
        # if lam == 0.0
        if np.linalg.det(denom) == 0.0:
            print('This matrix is singular, cannot do inverse')
            return
        ws = np.linalg.solve(denom,x_mat.T*y_mat.T)
        self.weight = ws
        return ws
    # 接受原始數據點,繪製迴歸線
    def showResult(self,train_x,train_y):
    	if self.weight is None:
    		return
        plt.scatter(train_x,train_y)
        x = np.arange(-1, 2)
        y =  self.weight[1,0]  * x +  self.weight[0,0]
        plt.plot(x,y,'r')
        plt.show()
    
    # 預測
    def predict(self,test_x):
        y =  self.weight[1,0]  * test_x +  self.weight[0,0]
        return y


if __name__=='__main__':
    Model = LinearRegression()
    train_X,train_Y,point_x = Model.creatData()
    #方法一
    Model.standRegres(train_X,train_Y)
    Model.showResult(point_x,train_Y)
    #方法二
    Model.linear_regression(train_X,train_Y)
    # 預測
    print(Model.predict(0.5))

    Model.showResult(point_x,train_Y)


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