機器學習python實戰----線性回歸


一、綱要

  線性回歸的正規方程解法

  局部加權線性回歸

二、內容詳述

  1、線性回歸的正規方程解法

  線性回歸是對連續型的數據進行預測。這里討論的是線性回歸的例子,對於非線性回歸先不做討論。這部分內容我們用的是正規方程的解法,理論內容在之前已經解釋過了,正規方程為θ = (XT·X)-1·XT·y。值得注意的是這里需要對XT·X求逆矩陣,因此這個方程只有在逆矩陣存在的時候才適用,所以需要在代碼中進行判斷。

from numpy import *
import matplotlib.pyplot as plt

def loaddataSet(filename):
    numfeat = len(open(filename).readline().split('\t'))-1
    dataMat = [];labelsVec = []
    file = open(filename)
    for line in file.readlines():
        lineArr = []
        curLine = line.strip().split('\t')
        for i in range(numfeat):
            lineArr.append(float(curLine[i]))
        dataMat.append(lineArr)
        labelsVec.append(float(curLine[-1]))
    return dataMat,labelsVec

def standRegression(xArr,yArr):
    xMat = mat(xArr);yMat = mat(yArr)
    xTx = xMat.T * xMat
    if linalg.det(xTx)==0.0:
        print('this matrix is singular,cannot do inverse\n')
        return
    sigma = xTx.I * (xMat.T * yMat.T)
    return sigma

loaddataSet()函數是將文本數據分成特征集和標簽。standRegression()是利用正規方程求回歸系數sigma,當然在使用正規方程前需要判斷其是否有逆矩陣。這種解法很簡單,但是它的缺點我也在之前的理論部分說過了。下面我們來看擬合的結果,利用PlotLine()函數來畫圖。注意這個函數的傳入參數xMay和yMat需要為矩陣形式

def PlotLine(xMat,yMat,sigma):
    ax = plt.subplot(111)
    ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0])
    xCopy = xMat.copy()
    xCopy.sort(0)
    yHat = xCopy*sigma
    ax.plot(xCopy[:,1],yHat)
    plt.show()
    

我們得到的擬合直線如圖所示,這看起來有點欠擬合的狀態。如果用另外一個數據集,得到的擬合直線也是這樣的,這也是我們不希望的結果

所以,我們后面對該方法進行改進,對回歸系數進行局部加權處理。這里的方法叫做局部加權線性回歸(LWLR)

  2、局部加權線性回歸

  該算法中,我們給待預測點附近的每個店賦予一定的權重,然后在其上基於最小均方差進行普通的線性回歸。其正規方程變為 θ=(XTX)-1XTWy。這里的W為權重。LWLR使用“核”來對附近的點賦予更高的權重,最常用的就是高斯核,其權重為。這樣就構建了只含對角元素的權重矩陣,並且點x與x(i)越近,權重越大。

def lwlr(testPoint,xArr,yArr,k = 1.0):
    xMat = mat(xArr);yMat = mat(yArr).T
    m = shape(xMat)[0]
    weights = mat(eye(m))
    for i in range(m):
        diffMat = testPoint - xMat[i,:]
        weights[i,i] = exp(diffMat * diffMat.T/(-2.0*k**2))
    xTWx = xMat.T * (weights*xMat)
    if linalg.det(xTWx)==0.0:
        print('this matrix is singular,cannot do inverse\n')
        return
    sigma = xTWx.I * (xMat.T * (weights * yMat))
    return testPoint * sigma

def lwlrTest(testArr,xArr,yArr,k = 1.0):
    m = shape(testArr)[0]
    yHat = zeros(m)
    for i in range(m):
        yHat[i] = lwlr(testArr[i],xArr,yArr,k)
    return yHat

lwlr()函數即為局部加權線性回歸法的代碼,lwlrTest()函數的作用是使lwlr()函數遍歷整個數據集。我們同樣需要畫出圖來看擬合結果

def PlotLine1(testArr,xArr,yArr,k = 1.0):
    xMat = mat(xArr)
    yMat = mat(yArr)
    yHat = lwlrTest(testArr,xArr,yArr,k)
    srtInd = xMat[:,1].argsort(0)
    xsort = xMat[srtInd][:,0,:]
    ax = plt.subplot(111)
    ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0],s = 2,c = 'red')
    ax.plot(xsort[:,1],yHat[srtInd])
    plt.show()

當                                       k=1.0                                                                                k=0.01                                                                       k=0.003

 

k=1.0就是前面的欠擬合狀態,而k=0.003就是過擬合狀態了,所以當k=0.01時才是比較好的回歸。

 

 

數據集和代碼下載地址:http://pan.baidu.com/s/1i5AayXn

 


免責聲明!

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



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