回歸(一):標准線性回歸


概念


線性回歸(linear regression)意味着可以把輸入項分別乘以一些 常量,然后把結果加起來得到輸出。
這個輸出就是我們需要預測的 目標值
而這些 常量就是所謂的 回歸系數
我們把求這些回歸系數的過程叫做 回歸,這個過程是對已知數據點的 擬合過程
更一般化的解釋來自 Tom M.Mitchell的《機器學習》:回歸的含義是逼近一個實數值的目標函數

標准線性回歸


那應該怎么求回歸系數 w呢。一個常用的方法是找出使得預測值和實際值之間的誤差最小的,為了避免正負誤差之間的相互抵消,我們采用平方誤差,也就是傳說中的 最小二乘法。

平方誤差可以寫作:
graphic
用矩陣表示寫作:

現在需要對這個公式求最小,其實就變成了一個最優化問題。
對w求導,得到:

令其等於0,解出w如下:

這個公式中包含了對矩陣求逆的操作,所以需要在實際計算過程中判斷矩陣是否可逆。

到這里,線性回歸的主要思想就算完成,下面用數據集來試一下
例子中用到的數據集ex0.txt大概長成這樣:


代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# -*- coding: utf-8 -*-
# Author: Alan
# date: 2016/4/7
from  numpy  import  *
 
def  loadData(filename):
     # 計算特征數量
     numFeat  =  len ( open (filename).readline().split( '\t' ))  -  1
     fr  =  open (filename)
     dataMat  =  []; labelMat  =  []
     for  line  in  fr.readlines():
         lineArr  =  []
         currLine  =  line.strip().split( '\t' )
         for  in  range (numFeat):
             lineArr.append( float (currLine[i]))
         dataMat.append(lineArr)
         labelMat.append( float (currLine[ - 1 ]))
     return  dataMat, labelMat
 
 
# 標准的線性回歸函數,使用最小二乘法
def  standRegres(xArr, yArr):
     xMat  =  mat(xArr)
     # 和transpose()一個意思
     yMat  =  mat(yArr).T
     xTx  =  xMat.T * xMat
     # 計算行列式的值,如果等於零,則不可求逆
     if  linalg.det(xTx)  = =  0.0 :
         print  'cannot do inverse!'
         return
     # 回歸系數
     ws  =  xTx.I  *  (xMat.T  *  yMat)
     return  ws
 
# 測試標准回歸,查看其求出的回歸系數
def  testStandR():
     filename  =  'E:\ml\machinelearninginaction\Ch08\ex0.txt'
     xArr, yArr  =  loadData(filename)
     print  "查看數據集的前兩個實例的特征:"
     print   xArr[ 0 : 2 ]
     weights  =  standRegres(xArr, yArr)
     print  "求出的系數為:"
     print  weights
 
standRegres()函數實現了線性回歸算法,然后用過運行testStandR()函數測試之,結果如下:

得出了系數就相當於得到了回歸方程,現在通過一個輸入就可以分別乘以回歸系數得到輸出,實現了預測的目的。


圖示原始數據和擬合直線


我們可以通過直觀的展示數據分布和擬合的直線來觀察擬合的效果
繪圖代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
def  plotData():
     import  matplotlib.pyplot as plt
     
     '''下面這段代碼繪制原始數據的散點圖'''
     filename  =  'E:\ml\machinelearninginaction\Ch08\ex0.txt'
     xArr, yArr  =  loadData(filename)
     xMat  =  mat(xArr);yMat  =  mat(yArr)
     figure  =  plt.figure()
     ax  =  figure.add_subplot( 111 )
     # 取第二個特征繪圖
     # flatten()函數轉化成一維數組
     # matrix.A屬性返回矩陣變成的數組,和getA()方法一樣
     ax.scatter(xMat[:, 1 ].flatten().A[ 0 ], yMat.T[:, 0 ].flatten().A[ 0 ])
     '''下面這段代碼繪制擬合直線'''
     # 返回給定數據的數組形式的拷貝
     xCopy  =  xMat.copy()
     xCopy.sort( 0 )
     weights  =  standRegres(xArr, yArr)
     print  weights.shape
     yHat  =  xCopy  *  weights  # yHat 表示擬合直線的縱坐標,用回歸系數求出
     ax.plot(xCopy[:, 1 ], yHat, c  =  'green' )
     plt.show()
繪圖效果:

評價模型


這樣的一個建模過程是非常直觀也非常容易理解的。
幾乎任一數據集都可以用上述方法建立模型,那么如何判斷模型好壞呢?
這里引入一種計算 預測序列真實值序列匹配程度的方法,就是計算兩個序列的 相關系數
很方便的是Numpy庫提供了相關系數的計算方法:
corrcoef(yEstimate, yActual)
運行代碼:
1
2
3
4
5
6
     # 利用相關系數評價模型的匹配程度
     def  eval ():
         xMat  =  mat(xArr)
         yMat  =  mat(yArr)
         yHat  =  xMat  *  weights
         print  corrcoef(yHat.T, yMat)
顯示結果如下:
表示兩者的相關系數為0.98,說明兩者的相關性很大
這樣就完成了一個標准的線性回歸,但是很明顯地,被擬合的數據中還有波動的特性沒有被表達出來,
也就說事實上這樣是欠擬合的。
那么如何才能進一步增強模型的表達能力呢,下一篇筆記將會解決這個問題。

總結

  1. 這種簡單的最佳擬合直線把數據當做直線進行擬合,表現不錯。
  2. 但是從繪制的散點圖中可以看出數據還具有明顯的波動特性,而這個特性是直線擬合所不能表達的,是它的缺陷
  3. 回歸需要數值型數據,標稱型數據需要轉換才能使用

參考文獻

《機器學習實戰》
這里是比較好的關於矩陣求導的講解



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM