ML入門4.0 手寫邏輯斯蒂迴歸 (Logistic Regression)

邏輯斯蒂迴歸簡介

Logistic Regression 即對數概率迴歸,是一種廣義的線性迴歸分析模型,是一種應用於二分類問題的分類算法
常用於數據挖掘,疾病自動診斷,經濟預測等領域。例如,探討引發疾病的危險因素,並根據危險因素預測疾病發生的概率等。以胃癌病情分析爲例,選擇兩組人羣,一組是胃癌組,一組是非胃癌組,兩組人羣必定具有不同的體徵與生活方式等。因此因變量就爲是否胃癌,值爲“是”或“否”,自變量就可以包括很多了,如年齡、性別、飲食習慣、幽門螺桿菌感染等。自變量既可以是連續的,也可以是分類的。然後通過logistic迴歸分析,可以得到自變量的權重,從而可以大致瞭解到底哪些因素是胃癌的危險因素。同時根據該權值可以根據危險因素預測一個人患癌症的可能性。百度百科

原理簡介

邏輯迴歸解決二分類問題,所謂分類就是分割數據,那麼邏輯迴歸的本質就是通過在數據集中學習,擬合出分類的決策邊界(決策函數)

決策邊界

兩個條件屬性(二維平面直角座標系中)決策邊界爲直線
三個條件屬性(三維空間直角座標系中)決策邊界爲平面
四個條件屬性(四維座標系中)決策邊界爲超平面

線性分割面的表達

二維:w0x0+w1x1+w2x2=0w_{0}x_{0} + w_{1}x_{1} + w_{2}x_{2} = 0 (PS:x01x_{0} \equiv 1

三維:w0x0+w1x1+w2x2+w3x3=0w_{0}x_{0} + w_{1}x_{1} + w_{2}x_{2} + w_{3}x_{3} = 0

四維:w0x0+w1x1+w2x2+w3x3+w4x4=0w_{0}x_{0} + w_{1}x_{1} + w_{2}x_{2} + w_{3}x_{3} + w_{4}x_{4} = 0

向量表達:
n維:XW\boldsymbol X \boldsymbol W (X爲行向量,W爲列向量)

學習與分類

Logistic Regression 的迴歸任務就是計算向量W
二分類:對於新的對象X’,計算X’W:結果小於0則爲0類,否則爲1類

損失函數

定義:度量預測結果和實際結果之間的差別

第一種損失函數

X={x1,...,xm}X=\{x_{1},...,x_{m}\} ,

MSE =1mi=1mH(xiw)yi\frac{1}{m}\sum_{i=1}^{m}|H(x_{i}w)-y{i}|

其中H(z)={0if z<012if z=01otherwise H(z)= \begin{cases} 0& \text{if z<0}\\ \frac{1}{2}& \text{if z=0}\\ 1& \text{otherwise} \end{cases}

H(xiw)H(x_{i}w)就是分類函數給出的標籤,yiy_{i}是真實標籤

優點:表達了錯誤率
缺點:函數H不連續,無法使用優化理論

第二種損失函數

MSE =1mi=1m12(yi^yi)2\frac{1}{m}\sum_{i=1}^{m}\frac{1}{2}(\widehat{y_{i}}-y_{i})^2

其中 yi^=σ(xiw)\widehat{y_{i}}=\sigma(x_{i}w),

σ(z)=11+ez\sigma(z) = \frac{1}{1+e^{-z}} ;

σ(z)=σ(z)(1σ(z))\sigma(z)' = \sigma(z)(1-\sigma(z))
在這裏插入圖片描述

缺點:非凸優化,多個局部最優解

第三種損失函數

因爲0<σ(z)<10 < \sigma(z) < 1, 所以將分類函數強行看作概率。
假設:

P(yi=1xi;w)=σ(xiw)P (y_{i} = 1|x_{i}; w) = σ(x_{i}w)
$P (y_{i} = 0|x_{i}; w) = 1 - σ(x_{i}w)

綜合兩式可得
P(yixi;w)=(σ(xiw))yi(1σ(xiw))1yiP (y_{i}|x_{i}; w) = (σ(x_{i}w))^{y_{i}} (1 − σ(x_{i}w))^{1−y_{i}}

由此獲得似然函數:

L(w)=P(YX;w)=i=1m(σ(xiw))yi(1σ(xiw))1yiL(w) = P (Y|X; w)=\prod_{i=1}^{m}(σ(x_{i}w))^{y_{i}} (1 − σ(x_{i}w))^{1−y_{i}}

因爲log具有單調性

l(w)=logL(w)l(w) = log L(w)

優化目標爲 :

minw1mi=1myilogσ(xiw)(1yi)log(1σ(xiw))min_{w}\frac{1}{m}\sum_{i=1}^{m} −y_{i}logσ(x_{i}w) − (1 − y_{i}) log(1 − σ(x_{i}w))

梯度下降法

l(w)wj=i=1m(yiσ(xiw))xij\frac{∂l(w)} {∂wj}=\sum_{i=1}^{m}(y_{i} − σ(x_{i}w))x_{ij}

通過求得優化目標的方向導數(梯度),來確定函數下降的最快方向,由此來更新W以獲得最佳W

代碼實現

Func1: LoadDataSet(paraFileName)加載數據集

def LoadDataSet(paraFileName):
    '''
    LoadDataSet
    :param paraFileName:
    :return: 特徵&標籤
    '''
    dataMat = []
    labelMat = []
    txt = open(paraFileName)
    for line in txt.readlines():
        tempValuesStringArray = np.array(line.replace("\n", "").split(','))
        tempValues = [float(tempValue) for tempValue in tempValuesStringArray]
        tempArray = [1.0] + [tempValue for tempValue in tempValues] # 相當於w0對應的x0
        tempX = tempArray[:-1]
        tempY = tempArray[-1]
        dataMat.append(tempX)
        labelMat.append(tempY)

    return dataMat, labelMat

Func2: sigmoid(paraX)分類函數實現

def sigmoid(paraX):
    '''
    sigmoid函數實現
    :param paraX:參數
    :return: 計算結果
    '''
    return 1.0/(1 + np.exp(-paraX))

Func3: gradAscent(dataMat, labelMat)梯度上升法(因爲取了優化目標的相反數,所以要求上升最快的方向)求W

def gradAscent(dataMat, labelMat):
    '''
    用梯度上升法求得最優權重
    :param dataMat:
    :param labelMat:
    :return:
    '''
    X = np.mat(dataMat)
    Y = np.mat(labelMat) #transfer the input to matrix
    Y = Y.transpose()
    m, n = np.shape(X)
    alpha = 0.001 # 學習步長
    maxCycles = 1000
    W = np.ones( (n,1))
    for i in range(maxCycles):
        y = sigmoid(X * W)
        error = Y - y
        W = W + alpha * X.transpose() * error

    return W

Func4: STLogisticClassifierTest ()手寫分類器

def STLogisticClassifierTest():
    '''
    Logistic 分類器
    '''
    X, Y = LoadDataSet('iris2condition2class.csv')

    tempStartTime = time.time()
    tempScore = 0
    numInstances = len(Y)
    weights = gradAscent(X, Y)

    tempPredicts = np.zeros((numInstances))

    for i in range(numInstances):
        tempPrediction = X[i] * weights
        if tempPrediction > 0:
            tempPredicts[i] = 1
        else:
            tempPredicts[i] = 0

    tempCorrect = 0
    for i in range(numInstances):
        if tempPredicts[i] == Y[i]:
            tempCorrect += 1

    tempScore = tempCorrect / numInstances
    tempEndTime = time.time()
    tempRunTime = tempEndTime - tempStartTime

    print('STLogistic Score: {}, runtime = {}'.format(tempScore, tempRunTime))

    rowWeights = np.transpose(weights).A[0]
    plotBestFit(rowWeights)

運行結果

在這裏插入圖片描述
在這裏插入圖片描述

GitHub地址

完整代碼和數據集見github.

優缺點

優點:
1.適合需要得到一個分類概率的場景。2.計算代價不高,容易理解實現。LR在時間和內存需求上相當高效。它可以應用於分佈式數據,並且還有在線算法實現,用較少的資源處理大型數據。3.LR對於數據中小噪聲的魯棒性很好,並且不會受到輕微的多重共線性的特別影響。

缺點
1.容易欠擬合,分類精度不高。2.數據特徵有缺失或者特徵空間很大時表現效果並不好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章