嶺回歸、前向逐步回歸

線性回歸的局限性

線性回歸是利用已有觀測(cè)樣本的自變量和因變量之間的線性關(guān)系,建立回歸方程。

通常采用最小二乘法求解,\hat{w} = (\mathbf{X}^T\mathbf{X})^{-1}\mathbf{X}^Ty

公式中包含(\mathbf{X}^T\mathbf{X})^{-1},也就是需要對(duì)矩陣求逆,因此這個(gè)方程只在逆矩陣存在時(shí)適用

如果特征比樣本點(diǎn)還多(n \gt m),也就是說(shuō)輸入數(shù)據(jù)的矩陣不是滿秩矩陣。非滿秩矩陣求逆時(shí)會(huì)出現(xiàn)問(wèn)題。

為了解決這個(gè)問(wèn)題,統(tǒng)計(jì)學(xué)家引入了嶺回歸(ridge regression)的概念,本文將介紹的第一種縮減方法。

嶺回歸

簡(jiǎn)單來(lái)說(shuō),嶺回歸就是在矩陣(\mathbf{X}^T\mathbf{X})上加一個(gè)\lambda I,從而使得矩陣非奇異(矩陣可逆),其中矩陣I是一個(gè)mxm的單位矩陣,對(duì)角線上元素全為1,其它元素全為0?;貧w系數(shù)的計(jì)算公式將變成:
\hat{w} = (\mathbf{X}^T\mathbf{X} + \lambda I)^{-1}\mathbf{X}^Ty
通過(guò)引入懲罰項(xiàng)\lambda,能夠減少不重要的參數(shù),這個(gè)技術(shù)在統(tǒng)計(jì)學(xué)中也叫做縮減(shrinkage)。

import numpy as np

def loadDataSet(fileName):      
    numFeat = len(open(fileName).readline().split('\t')) - 1
    dataMat = []; labelMat = []
    fr = open(fileName)
    for line in fr.readlines():
        lineArr =[]
        curLine = line.strip().split('\t')
        for i in range(numFeat):
            lineArr.append(float(curLine[I]))
        dataMat.append(lineArr)
        labelMat.append(float(curLine[-1]))
    return dataMat,labelMat

# 計(jì)算回歸系數(shù)
def ridgeRegres(xMat, yMat, lam = 0.2):
    xTx = xMat.T * xMat
    demon = xTx + np.eye(xMat.shape[1]) * lam
    if np.linalg.det(demon) == 0:
        print('矩陣無(wú)法求逆')
        return
    ws = demon.I * (xMat.T * yMat)
    return ws

def ridgeTest(xArr, yArr):
    xMat = np.mat(xArr)
    yMat = np.mat(yArr).T
    # 數(shù)據(jù)標(biāo)準(zhǔn)化
    ymean = np.mean(yMat, 0)
    yMat = yMat - ymean
    xMean = np.mean(xMat, 0)
    xVar = np.var(xMat, 0)
    xMat = (xMat - xMean)/xVar

    numTest = 30
    wMat = np.zeros((numTest, xMat.shape[1]))
    for i in range(numTest):
        ws = ridgeRegres(xMat, yMat, np.exp(i-10))
        wMat[i,:] = ws.T
    return wMat

ridgeRegres()函數(shù)用于計(jì)算回歸系數(shù),ridgeTest()函數(shù)在一組\lambda上測(cè)試結(jié)果。

abX, abY = loadDataSet('abalone.txt')
ridgeWeights = ridgeTest(abX, abY)

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(ridgeWeights)
plt.xlabel('log(lambda)')
plt.show()

上圖繪出了回歸系數(shù)與log(\lambda)的關(guān)系。在\lambda較小時(shí),可以得到所有系數(shù)的原始值;而在最右邊,\lambda達(dá)到一個(gè)很大的值,所有系數(shù)縮減為0。在中間部分的某值將可以取得最好的預(yù)測(cè)效果。需要進(jìn)行交叉驗(yàn)證來(lái)找到最佳參數(shù)值。

還有一些其他縮減方法,如lasso、LAR、PCA回歸以及子集選擇等。

前向逐步回歸

前向逐步回歸算法,屬于一種貪心算法,即每一步都盡可能減少誤差。算法偽代碼如下。

數(shù)據(jù)標(biāo)準(zhǔn)化,使其分布滿足0均值和單位方差
每次迭代:
    設(shè)置當(dāng)前最小誤差lowestError為正無(wú)窮
    對(duì)每個(gè)特征:
        增大或縮小:
            改變一個(gè)系數(shù)得到一個(gè)新的W
            計(jì)算新W下的誤差
            如果誤差Error小于lowestError:
                設(shè)置WBest等于當(dāng)前W
    將W設(shè)置為新的WBest

實(shí)際代碼如下。

# 計(jì)算殘差平方和
def rssError(yArr,yHatArr): 
    return ((yArr-yHatArr)**2).sum()

# 標(biāo)準(zhǔn)化數(shù)據(jù)
def regularize(xMat, axis = 0):
    inMat = xMat.copy()
    inMeans = np.mean(inMat, axis)   
    inVar = np.var(inMat, axis)     
    inMat = (inMat - inMeans)/inVar
    return inMat

# 前向逐步回歸
def stageWise(xArr, yArr, eps = 0.01, maxIter = 100):
    '''
    xArr:輸入數(shù)據(jù)
    yArr預(yù)測(cè)變量
    eps:需要調(diào)整的步長(zhǎng)
    maxIter:最大迭代次數(shù)
    '''
    xMat = np.mat(xArr)
    yMat = np.mat(yArr).T
    yMean = np.mean(yMat, 0)
    yMat = yMat - yMean
    xMat = regularize(xMat)
    m,n = xMat.shape
    returnMat = np.zeros((maxIter, n))
    ws = np.zeros((n, 1))
    wsTest = ws.copy()
    wsMax = ws.copy()
    for i in range(maxIter):
        lowestError = np.inf
        for j in range(n):
            for sign in [-1, 1]:
                wsTest = ws.copy()
                wsTest[j] += eps*sign
                yTest = xMat * wsTest
                rssE = rssError(yMat.A, yTest.A)
                if rssE < lowestError:
                    lowestError = rssE
                    wsMax = wsTest
        ws = wsMax.copy()
        returnMat[i, :] = ws.T
    return returnMat

下面看下實(shí)際效果。

ws = stageWise(abX, abY, 0.005, 1000)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(ws)
plt.show()

逐步線性回歸算法可以找出重要的特征,這樣就可能及時(shí)停止對(duì)那些不重要特征的收集。

當(dāng)應(yīng)用縮減方法(如逐步線性回歸或嶺回歸)時(shí),模型就增加了偏差(bias),與此同時(shí),減小了模型的方差。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容