機器學習(二):邏輯迴歸

邏輯迴歸(Logistic Regression),是機器學習中的一個分類模型。
按理說邏輯迴歸並不是分類模型中最簡單的一個(最簡單的應該是KNN),但爲什麼要從該模型開始呢?
原因有二:1.邏輯迴歸涉及到的一些知識點是後面機器學習的基礎,2.筆者兩次面試都被問道了邏輯迴歸。。。
本節將順着如下邏輯進行講解:
1.樣本描述
2.處理結果的函數(躍階函數還是sigmoid函數)
3.使用似然函數來確定求θ 的方法
4.使用梯度上升求梯度以求得θ
5.補充:如何使用損失函數

數據描述

這裏什麼是分類聚類就不介紹了,直接引入數據如下:
(xi,yi) 是一條記錄。其中yi{0,1},xi=(xi1,...,xin),xijR ,即該問題是二分類問題。數據維度爲n。

模型參數形式

類似於線性規劃,模型表達式爲:

f(xi)=xiθ,θ=(θ1,...,θn)

到這裏,給出瞭如何獲得模型的值f(xi) ,但卻沒有說明拿到這個值後如何處理。

躍階函數

即使用如下函數來判斷模型對於輸出參數的取值

g1(x)={100x0>x

上式是邏輯迴歸的基本假設,即使用屬性的一階函數(自變量的線性組合)來預測。
x 大於等於0時,模型給出的標籤值爲1,否則爲0.

sigmoid 函數

先介紹其形式:

g2(x)=11+ex

sigmoid 函數可以作爲躍階函數的替代。如果看過講解邏輯迴歸的資料就會發現,大部分相關資料講到邏輯迴歸都會提到sigmoid 函數,並將其作爲得到最後結果的最後一步。
但其實,sigmoid 函數完全不是邏輯迴歸的重點,而只是一種處理模型結果的手段。
我們既可以使用yi^=g1(f(xi)) (即躍階函數)來給出最後的標籤,也可以使用yi^=g2(f(xi)) (sigmoid 函數)來給出最後的標籤。
不論是使用哪一種,yi^=g(f(xi)) 都可以理解爲表示給定樣本點x,模型判斷爲屬於“1”的概率,但同時有能根據yi^ 本身的大小來判斷是取“0”還是“1”。
例如,當g(x) 爲sigmoid函數時yi^=g(f(xi))=11+ef(xi)=11+exiθ 表示當xiθ 越大,yi^ 越靠近1。
此時求得的yi^xi 樣本點屬於類“1”的概率。

p(1|xi;θ)=g(f(xi))

同理可得:
p(0|xi;θ)=1g(f(xi))

上式中,g(x) 代表使用躍階函數或者sigmoid函數。正如上面所說,g(x) 使用什麼並不是邏輯迴歸的重點,在補充材料之前,都一直使用g(x) 而不是常用的sigmoid函數的具體形式,並在最後得出結論爲什麼通常g(x) 會選擇sigmoid函數。

評判指標——似然函數

確定了yi^=g(xiθ) 後,我們就需要思考如何求出θ 的值了。
參考第一節,我們首先使用似然函數來評判模型的好壞,即需要極大化似然函數。
將模型的預測結果記爲yi^ .某個樣本點爲(xi1,...,xin),yi
根據極大似然估計,樣本X 的似然函數爲:

L(θ;x1,...,xn)=1np(yi|xi;θ)

即我們的目標就是求解當L(θ;x1,...,xn) 取最大值時的θ
以上確定了求解y^ 的方法,注意這裏沒有采用通常的損失函數,是爲了方便理解,博客的最後會補充一節來講使用損失函數而不是似然函數求解的過程。
OK,接下來的任務就是最優化問題了,即 求解L(θ;x1,...,xn) 最大值。
爲了使上式的值儘可能大,對於每一個p(yi|xi;θ) 應儘可能的取較大的值。
p(y|xi;θ)={g(f(xi))1g(f(xi))y=1y=0

化簡後得到
p(y|xi;θ)=g(f(xi))y(1g(f(xi)))1y

注意這一步,務必能推導理解。
接着對L(θ;x1,...,xn) 取對數,得到
lnL(θ;x1,...,xn)=ln1np(y|xi;θ)=1nlnp(y|xi;θ)=1nln(g(f(xi))y(1g(f(xi)))1y)=1nylng(f(xi))+(1y)ln(1g(f(xi)))=1nylng(xiθ)+(1y)ln(1g(xiθ))

使用拉格朗日乘數法求極值,對極大似然估計求導得到:
lnL(θ;x1,...,xn)θ=(0,...,0)

lnL(θ;x1,...,xn) 帶入,若能求得θ 那麼該θ 就是所需要的參數。
但遺憾的是,上式的求解及其複雜,是m次多項式(m是樣本數),即沒有根式解。方程無法直接解出(有興趣的可以一試)。

梯度上升法

還記得我們的目標嗎?雖然我們沒法求出精確的θ ,但可以通過各種優化算法一步步迭代,使得lnL(θ;x1,...,xn) 越來越大,直到滿足要求。
其實目標也就是解方程而已,常用的求方程近似根的方法有梯度法和牛頓法。爲了和其他邏輯迴歸的資料接軌,還是採用梯度上升法。

雖然沒法得到lnL(θ;x1,...,xn)θ=(0,...,0) 時的θ ,但給定一個θ 後,可以求得該θ 處的lnL(θ;x1,...,xn)θ ,表示該θ 上升或者下降最快的方向。

此即爲梯度上升法的原理,上述理論不做證明,認真學過高數的應有印象。
求微過程如下:

lnL(θ;x1,...,xn)θ=n1ylng(xiθ)+(1y)ln(1g(xiθ))θ=1nyg(xiθ)xig(xiθ)+(1y)(g(xiθ)xi)1g(xiθ)=1ng(xiθ)g(xiθ)(1g(xiθ))[xi(yg(xiθ))]

最後的結果跟選擇的g(x) 有關。
爲了使上式變得更簡單,我們希望g(xiθ)g(xiθ)(1g(xiθ)) 恆爲1。注意這只是一個假設,作爲附加條件,當g(xiθ)g(xiθ)(1g(xiθ))==1 時,g(x)=11+ex
是的你沒看錯,當g(x)=11+ex 時,有如下等式:
lnL(θ;x1,...,xn)θ=1nxi(yg(xiθ))

這就是爲什麼g(x) 通常取sigmoid 函數的原因。
到這裏,我們就求出了上升的梯度了。
每次取一定的步長,慢慢迭代即可使得似然函數步步變大。
這裏貼一下《機器學習實戰》裏的代碼,說明求解過程。
def loadDataSet():
    dataMat = []; labelMat = []
    fr = open('testSet.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()
        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
        labelMat.append(int(lineArr[2]))
    return dataMat,labelMat

def sigmoid(inX):
    return 1.0/(1+exp(-inX))

def gradAscent(dataMatIn, classLabels):
    dataMatrix = mat(dataMatIn)             #convert to NumPy matrix
    labelMat = mat(classLabels).transpose() #convert to NumPy matrix
    m,n = shape(dataMatrix)
    alpha = 0.001
    maxCycles = 500
    weights = ones((n,1))
    for k in range(maxCycles):              #heavy on matrix operations
        h = sigmoid(dataMatrix*weights)     #matrix mult
        error = (labelMat - h)              #vector subtraction
        weights = weights + alpha * dataMatrix.transpose()* error #matrix mult
    return weights

注意上述代碼的倒數第二行:dataMatrix.transpose()* error用算式來表達就是xi(yg2(xiθ)) .

補充:損失函數

作爲一個補充,我們討論下當不使用似然函數時還有什麼指標可以作爲求解參數θ 的依據,以及g(x) 選擇sigmoid函數的其他依據。
首先提出一個概念——損失函數,常用來作爲模型求解參數的衡量標準。

0-1損失

在講0-1損失前,先討論當不使用似然函數時可以選擇什麼。
一個很直觀的想法——使用錯誤率來衡量模型,並以此來求解參數θ
錯誤率是啥?很簡單的概念——模型分類錯誤的頻率。
當模型對某個樣本分類錯誤時,則錯誤數增加1,正確則錯誤數不增加。

L(xi)=01yi^=yiyi^yi={010xiθ(y1/2)0>xiθ(y1/2)

則任務即是最小化L(xi) .
由於L(xi)xi,yi,θ 的值無關,而只與其運算的符號有關,因此在求解的過程中,會遇到很多困難。
如果你還記得上面的內容,就會發現上式其實也是一種躍階函數。
說到這裏,0-1損失就是上面的內容,沒錯,0-1損失就是我們最常用的錯誤率的另一種形式:

0-1損失:當預測值和實際值相等時,損失取0,否則取1

注意,我們不使用0-1損失的原因是求解複雜。
由於躍階函數的表達式是分段函數,因此一般我們會趨向使用與躍階函數的近似函數來替代,替代的函數需要有類似躍階函數的性質,即單調,且首位收斂。
0-1損失-躍階函數
log損失-sigmoid函數
到這裏sigmoid函數就出場了。

log損失

ok,我們都知道不能使用躍階函數(0-1損失)了,那我們如何使用sigmoid函數呢?
先來看看log損失。

L(xi)=log(1+exiθ(y1/2))

不難看出,其實是將0-1損失的xiθ(y1/2) 換了個位置。
該式的直觀含義是,當xiθy1/2 同號(即預測值與實際值相同)時,exiθ(y1/2) 很小(小於1),則L(xi)=log(1+exiθ(y1/2)) 本身很小;反之則很大,作爲懲罰,正好作爲損失項的含義。
對於該xiθ(y1/2) 乘2並不印象損失函數的最優化,並方便計算。
L(xi)=log(1+exiθ(2y1)) 該式直接求導將很困難,因此做如下變通:
L(xi)=log(1+exiθ(2y1))={log(1+exiθ)log(1+exiθ)y=1y=0={log(1+exiθ)log(1+exiθ)+xiθy=1y=0=log(1+exiθ)+(1y)xiθ

由於y只能去0,1,故可以化簡如上式。
目標是最小化L(xi) ,求導如下:
L(xi)θ=log(1+exiθ)+(1y)xiθθ=exiθ(xi)1+exiθ+(1y)xi=(111+exiθ)(xi)+(1y)xi=xi(11+exiθy)

還記得上面梯度上升法最後的結論嗎?

使用似然函數和梯度上升法,當g(x)sigmoid ,求得的梯度爲n1xi(y11+exiθ) 恰好與上式使用log損失的結果相同,即使用log損失,也就間接的使用了sigmoid函數。

好了到這裏,邏輯迴歸二分類的情況基本告一段落了。
作爲機器學習的開始,我們引入了一個常用的重要概念——損失函數
雖然本節提到了損失函數,但並未系統的介紹損失函數,下下一節將系統的介紹損失函數。
下一節將從整體上介紹梯度上升法

發佈了72 篇原創文章 · 獲贊 50 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章