1. 程式人生 > >機器學習python實戰----線性回歸

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

pyplot 理論 普通 遍歷 sca def blog reg .so

一、綱要

  線性回歸的正規方程解法

  局部加權線性回歸

二、內容詳述

  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

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