機器學習之logistic迴歸的梯度上升算法

機器學習之logistic迴歸的梯度上升算法

算法背景:

一般來說,迴歸模型一般不用在分類問題上,因爲迴歸是連續型模型,而且受噪聲的因素很大,但是,若需要選擇,可以選擇使用logisti 迴歸。
對數迴歸本質上是線性迴歸,只是在特徵到結果的映射里加入了一層函數映射,選擇g(z)=1/(1+exp(-z))作爲sigmoid函數進行映射,可以將連續值映射到0-1之間。其中g(z)函數的圖像如下:可以看到,函數的取值始終在0-1之間。


對於分類問題,我們可以建立假設:
          if(z >= 0.5) g(z)=1;  if(z < 0.5) g(z)=0;


算法思想:
對於輸出值爲y={0,1}的兩類分類問題,我們做出一個假設

函數g(z)即爲上文提到的sigmoid函數,其導數形式爲:

根據這個函數,我們可以得到對於一個樣本的概率分佈爲:

綜合起來就是:

現在就可以將問題轉化爲求Logistic迴歸的最佳係數,因爲logistic迴歸可以被看做一種概率模型,且y發生的概率與迴歸參數Θ有關,因此我們可以對Θ進行最大似然估計,使得y發生的概率最大,此時的Θ 便是最優迴歸係數:

對數據集求似然函數,並取對數計算:

要使得最大化,則運用梯度上升法,求出最高點:

計算結果爲:

此公式便是梯度上升算法的更新規則,α是學習率,決定了梯度上升的快慢。可以看到與線性迴歸類似,只是增加了特徵到結果的映射函數。

代碼實現python:
#coding=utf-8
#logistic迴歸的梯度上升法

from numpy import *
import matplotlib.pyplot as plt
#加載數據集
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])])#x0=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)
    labelMat = mat(classLabels).transpose()
    m, n = shape(dataMatrix)#n=3
    alpha = 0.001#學習率
    maxCycles = 500#循環輪數
    theta = ones((n, 1))
    for k in range(maxCycles):
        h = sigmoid(dataMatrix * theta)
        error = (labelMat - h)
        theta = theta + alpha * dataMatrix.transpose() * error
    return theta
#根據訓練好的theta繪圖
def plotBestFit(theta):
    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(1,1,1)
    ax.scatter(xcord1, ycord1, s = 30, c = 'red', marker='s')
    ax.scatter(xcord2, ycord2, s = 30, c = 'blue')
    #生成x的取值 -3.0——3.0,增量爲0.1
    x = arange(-3.0, 3.0, 0.1)
    #y = Θ0+Θ1x1+Θ2x2
    #y=x2
    y = (-theta[0] - theta[1] * x) / theta[2]
    ax.plot(x, y.T)
    plt.xlabel('X1')
    plt.ylabel('X2')
    plt.show()
dataMat,labelMat = loadDataSet()#加載數據集
theta = gradAscent(dataMat,labelMat)#計算參數
plotBestFit(theta)#根據參數畫出分界線以及相應分類點

結果演示:


原文:https://blog.csdn.net/tianse12/article/details/70183348 

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