《機器學習實戰》學習筆記(5、Logistic迴歸)

迴歸:若有一些數據點,用一條直線對這些點進行擬合的過程。

訓練分類器時的做法,尋找最佳擬合參數,使用最優化算法。

準備數據,要求數據類型爲數值型;訓練算法,尋找最佳的分類迴歸係數。使用算法,輸入數據,轉化爲結構化數值,基於迴歸係數,對這些數值進行迴歸計算,判定分類。

基於Logistic迴歸和Sigmoid函數的分類:

計算代價不高,但容易欠擬合,分類精度不高。

Sigmoid函數,看起來很像一個階躍函數,隨着x增大,會逼近於1。

Logistic迴歸分類器的原理:每個特徵上都乘以一個迴歸係數,然後把所有結果相加,代入Sigmoid函數,進而得到0~1之間的數值。

梯度上升法:用來求函數的最大值

f(x,y)的梯度:;梯度上升算法的迭代公式:,α爲步長。

 

對某數據集,使用梯度上升法,找到最佳迴歸係數:

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)  # 100行數據,每行有兩個特徵X1和X2
    labelMat = mat(classLabels).transpose()  # 轉化爲100x1的列向量
    m, n = shape(dataMatrix)  # 100x3
    alpha = 0.001  # 目標移動的步長
    maxCycles = 500  # 迭代次數
    weights = ones((n, 1))  # 3x1
    for k in range(maxCycles):
        h = sigmoid(dataMatrix * weights)  # h是一個列向量,100x1
        error = (labelMat - h)  # 100x1
        weights = weights + alpha * dataMatrix.transpose() * error  # 3x1
    return weights

分析數據:畫出決策邊界:

def plotBestFit(weights):
    import matplotlib.pyplot as plt
    dataMat, labelMat = loadDataSet()
    dataArr = array(dataMat)
    n = shape(dataArr)[0]
    xcord1 = []
    ycord1 = []
    xcord2 = []
    ycord2 = []
    for i in range(n):
        if int(labelMat[i]) == 1:
            xcord1.append(dataArr[i, 1])
            ycord1.append(dataArr[i, 2])
        else:
            xcord2.append(dataArr[i, 1])
            ycord2.append(dataArr[i, 2])
    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
    ax.scatter(xcord2, ycord2, s=30, c='green')
    x = arange(-3.0, 3.0, 0.1)
    y = (-weights[0] - weights[1] * x) / weights[2]
    ax.plot(x, y)
    plt.xlabel('X1')
    plt.ylabel('X2')
    plt.show()

這裏設置sigmoid函數的x爲0,因此設定 0=w_0x_0+w_1x_1+w_2x_2,然後解出兩個特徵X2和X1的關係式,此處X0=1。

訓練算法:隨機梯度上升:

上述算法,每次更新迴歸係數,都需要遍歷整個數據集,就會使得計算複雜度過高。

隨機梯度上升算法:一次僅用,一個樣本點來更新迴歸係數。因此可在新樣本到來時,對分類器進行增量式更新(在線學習)

一個判斷優化算法優劣的可靠方法是:看它是否收斂,也就是說參數是否達到了穩定值

def stocGradAscent1(dataMatrix, classLabels, numIter=150):
    m, n = shape(dataMatrix)  # 100x3
    weights = ones(n)  # 3
    for j in range(numIter):
        dataIndex = range(m)
        for i in range(m):
            # 每次迭代都會調整,0.0001防止α爲0
            # 若處理的問題是動態變化,則適當加大上述常數項,確保新的值,獲得更大的迴歸係數
            alpha = 4 / (1.0 + j + i) + 0.0001
            # 當j<<max(i)時,alpha就不是嚴格下降的,避免參數嚴格下降,見於模擬退火算法
            randIndex = int(random.uniform(0, len(dataIndex)))
            # 隨機選取樣本來更新迴歸係數
            h = sigmoid(sum(dataMatrix[randIndex] * weights))
            error = classLabels[randIndex] - h
            weights = weights + alpha * error * dataMatrix[randIndex]
            # 從列表中刪除該值
            del (dataIndex[randIndex])
    return weights

ps:係數沒有出現週期性波動,歸功於樣本隨機選擇機制。僅遍歷20次左右數據集,係數即可收斂。

 

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