python實現簡單的邏輯迴歸

1 定義的一些公式

\large Z=W^T\times X+b

\large \hat{y}=sigmoid(Z)=\frac{1}{1+e^{(-Z)}}

邏輯迴歸可以看作是一個單一的神經元,用來實現二分類問題。上述式子是邏輯迴歸的一般定義式。

\large \hat{y}代表單個樣本的預測值,y爲實際值。

  • 最大似然估計原理:

\large l(\hat{y},y)=ylog\hat{y}+(1-y)log(1-\hat{y})

  •  損失函數(單個樣本):

\large L(\hat{y},y)=-l(\hat{y},y)=-[ylog\hat{y}+(1-y)log(1-\hat{y})]

與上式相比多了一個負號,即是求損失函數的最小值.

  • 代價函數(m個樣本的累加):

\large J(\hat{y},y)=-\frac{1}{m}[\sum_{i=1}^my^{(i)} +log\hat{y}^{(i)} +(1-y^{(i)})log(1-\hat{y}^{(i)})]

  • sigmoid函數的導數

\large (\hat{y})'=\hat{y}(1-\hat{y})

2 邏輯迴歸的實現步驟

  • Step1: 前向傳播:

\large Z=WX+b \Longrightarrow A=\sigma(Z) \Longrightarrow J(A,Y)

其中A代表預測輸出,  \large \sigma代表sigmoid函數。

  • Step2: 反向傳播

\large dZ=A-Y

\large dW=\frac{1}{m}dZX^T

\large db=\frac{1}{m}np.sum(dZ)

  • Step3: 梯度下降:

\large W=W-\eta dW

\large b=b-\eta db

 3 python 實現

測試數據:

名字是testSet.txt,部分內容如下,共100個。

下載地址:https://raw.githubusercontent.com/qmh1234567/logistic_regression/master/testSet.txt

1. text文本的讀入

X=[];Y=[]
# 加載數據
def loadDataSet():
    f=open('testSet.txt')
    # 逐行讀入數據  使用strip去掉頭尾的空格  split根據空格分組
    for line in f.readlines():
        nline=line.strip().split()
        # x 需要添加一列
        X.append([float(nline[0]),float(nline[1])])
        Y.append(int(nline[2]))
    return mat(X).T,mat(Y)

2. 定義sigmoid函數

# 定義sigmoid函數
def sigmoid(X):
    return 1.0/(1+exp(-X))

3. 邏輯迴歸的實現(此處與前面的步驟一一對應)

def Logistic(X,Y,W,b,M,alpha,Count):
    J=zeros((Count,1))
    for i in range(Count):
        # step1 前向傳播
        Z=np.dot(W,X)+b
        A=sigmoid(Z)
        # 計算代價函數
        J[i]=-1/M*(np.dot(Y,np.log(A.T))+np.dot((1-Y),np.log((1-A).T)))
        # step2 反向傳播
        dZ=A-Y
        dW=1/M*np.dot(dZ,X.T)
        db=1/M*np.sum(dZ)
        # step3 梯度下降
        W=W-alpha*dW
        b=b-alpha*db
    return A,W,b,J

4. 繪製圖片

def plotBestFit(X,Y,J,W,M,A):
    # 繪製代價函數曲線
    fig1 = plt.figure(1)
    plt.plot(J)
    plt.title(u'代價函數隨迭代次數的變化')
    plt.xlabel(u'迭代次數')
    plt.ylabel(u'代價函數的值')
    # 預測值和實際值的對比
    fig2=plt.figure(2)
    plt.scatter(range(0,M),(Y.T).tolist(),c='b',marker='o')
    plt.scatter(range(0,M),np.rint(A.T).tolist(),c='r',marker='s')
    plt.title(u'預測值和實際值的對比')
    plt.legend(('實際值','預測值'))
    # 繪製最終分類圖片
    # 根據訓練樣本標記不同,分爲兩類不同的點
    xcord1=[]; ycord1=[]
    xcord2=[]; ycord2=[]
    for i in range(M):
        if int(Y[0,i])==1:
            xcord1.append(X[0,i])
            ycord1.append(X[1,i])
        else:
            xcord2.append(X[0,i])
            ycord2.append(X[1,i])
    fig3 = plt.figure(3)
    plt.scatter(xcord1,ycord1,c='b',marker='o')
    plt.scatter(xcord2,ycord2,c='r',marker='s')
    x=linspace(-3,3,100).reshape(100,1) # 生成一個數組
    print(W)
    y=(-b-W[0,0]*x)/W[0,1]
    plt.plot(x,y,c='y')
    plt.title(u'邏輯分類結果示意圖')
    plt.xlabel(u'x')
    plt.ylabel(u'y')
    plt.show()

5. 主函數

if __name__ == '__main__':
    X,Y=loadDataSet()
    Nx=X.shape[0]  # 特徵數
    M=X.shape[1] # 樣本個數
    # 權重和偏置的初始化
    W=np.random.randn(1,Nx)*0.01
    b=0
    # 學習速率
    alpha=0.01
    # 迭代次數
    Count=5000
    A,W,b,J=Logistic(X, Y, W, b, M, alpha, Count)
    plotBestFit(X, Y, J, W, M,A)

運行結果:

 

 

項目地址:

https://github.com/qmh1234567/logistic_regression.git

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