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

機器學習算法Python實現

(github地址:https://github.com/lawlite19/MachineLearning_Python

由於公式使用的是LaTex,解析使用的google的Chart API,所以顯示有問題,可以移步github)

二、邏輯迴歸

1、代價函數

  • \left{ \begin{gathered}
  J(\theta ) = \frac{1}{m}\sum\limits_{i = 1}^m {\cos t({h_\theta }({x^{(i)}}),{y^{(i)}})}  \hfill \\
  \cos t({h_\theta }(x),y) = \left\{ {\begin{array}{c}    { - \log ({h_\theta }(x))} \\    { - \log (1 - {h_\theta }(x))}  \end{array} \begin{array}{c}    {y = 1} \\    {y = 0}  \end{array} } \right. \hfill \\ 
\end{gathered}  \right.
  • 可以綜合起來爲:
    J(\theta ) =  - \frac{1}{m}\sum\limits_{i = 1}^m {[{y^{(i)}}\log ({h_\theta }({x^{(i)}}) + (1 - } {y^{(i)}})\log (1 - {h_\theta }({x^{(i)}})]
    其中:
    {h_\theta }(x) = \frac{1}{{1 + {e^{ - x}}}}
  • 爲什麼不用線性迴歸的代價函數表示,因爲線性迴歸的代價函數可能是非凸的,對於分類問題,使用梯度下降很難得到最小值,上面的代價函數是凸函數
  • { - \log ({h_\theta }(x))}的圖像如下,即y=1時:
    ![enter description here][2]

可以看出,當{{h_\theta }(x)}趨於1y=1,與預測值一致,此時付出的代價cost趨於0,若{{h_\theta }(x)}趨於0y=1,此時的代價cost值非常大,我們最終的目的是最小化代價值
- 同理{ - \log (1 - {h_\theta }(x))}的圖像如下(y=0):
![enter description here][3]

2、梯度

  • 同樣對代價函數求偏導:
    \frac{{\partial J(\theta )}}{{\partial {\theta _j}}} = \frac{1}{m}\sum\limits_{i = 1}^m {[({h_\theta }({x^{(i)}}) - {y^{(i)}})x_j^{(i)}]}
    可以看出與線性迴歸的偏導數一致
  • 推到過程
    ![enter description here][4]

3、正則化

  • 目的是爲了防止過擬合
  • 在代價函數中加上一項\frac{\lambda }{{2m}}\sum\limits_{j = 1}^m {\theta _j^2} ,所以最終的代價函數爲:
    J(\theta ) =  - \frac{1}{m}\sum\limits_{i = 1}^m {[{y^{(i)}}\log ({h_\theta }({x^{(i)}}) + (1 - } {y^{(i)}})\log (1 - {h_\theta }({x^{(i)}})] + \frac{\lambda }{{2m}}\sum\limits_{j = 1}^m {\theta _j^2}
  • 注意j是重1開始的,因爲theta(0)爲一個常數項,X中最前面一列會加上1列1,所以乘積還是theta(0),feature沒有關係,沒有必要正則化
  • 正則化後的代價:
# 代價函數
def costFunction(initial_theta,X,y,inital_lambda):
    m = len(y)
    J = 0

    h = sigmoid(np.dot(X,initial_theta))    # 計算h(z)
    theta1 = initial_theta.copy()           # 因爲正則化j=1從1開始,不包含0,所以複製一份,前theta(0)值爲0 
    theta1[0] = 0   

    temp = np.dot(np.transpose(theta1),theta1)
    J = (-np.dot(np.transpose(y),np.log(h))-np.dot(np.transpose(1-y),np.log(1-h))+temp*inital_lambda/2)/m   # 正則化的代價方程
    return J
  • 正則化後的代價的梯度
# 計算梯度
def gradient(initial_theta,X,y,inital_lambda):
    m = len(y)
    grad = np.zeros((initial_theta.shape[0]))

    h = sigmoid(np.dot(X,initial_theta))# 計算h(z)
    theta1 = initial_theta.copy()
    theta1[0] = 0

    grad = np.dot(np.transpose(X),h-y)/m+inital_lambda/m*theta1 #正則化的梯度
    return grad  

4、S型函數(即{{h_\theta }(x)}

  • 實現代碼:
# S型函數    
def sigmoid(z):
    h = np.zeros((len(z),1))    # 初始化,與z的長度一置

    h = 1.0/(1.0+np.exp(-z))
    return h

5、映射爲多項式

  • 因爲數據的feture可能很少,導致偏差大,所以創造出一些feture結合
  • eg:映射爲2次方的形式:1 + {x_1} + {x_2} + x_1^2 + {x_1}{x_2} + x_2^2
  • 實現代碼:
# 映射爲多項式 
def mapFeature(X1,X2):
    degree = 3;                     # 映射的最高次方
    out = np.ones((X1.shape[0],1))  # 映射後的結果數組(取代X)
    '''
    這裏以degree=2爲例,映射爲1,x1,x2,x1^2,x1,x2,x2^2
    '''
    for i in np.arange(1,degree+1): 
        for j in range(i+1):
            temp = X1**(i-j)*(X2**j)    #矩陣直接乘相當於matlab中的點乘.*
            out = np.hstack((out, temp.reshape(-1,1)))
    return out

6、使用scipy的優化方法

  • 梯度下降使用scipyoptimize中的fmin_bfgs函數
  • 調用scipy中的優化算法fmin_bfgs(擬牛頓法Broyden-Fletcher-Goldfarb-Shanno
    • costFunction是自己實現的一個求代價的函數,
    • initial_theta表示初始化的值,
    • fprime指定costFunction的梯度
    • args是其餘測參數,以元組的形式傳入,最後會將最小化costFunction的theta返回
    result = optimize.fmin_bfgs(costFunction, initial_theta, fprime=gradient, args=(X,y,initial_lambda))    

7、運行結果

  • data1決策邊界和準確度
    ![enter description here][5]
    ![enter description here][6]
  • data2決策邊界和準確度
    ![enter description here][7]
    ![enter description here][8]

8、使用scikit-learn庫中的邏輯迴歸模型實現

  • 導入包
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.cross_validation import train_test_split
import numpy as np
  • 劃分訓練集和測試集
    # 劃分爲訓練集和測試集
    x_train,x_test,y_train,y_test = train_test_split(X,y,test_size=0.2)
  • 歸一化
    # 歸一化
    scaler = StandardScaler()
    scaler.fit(x_train)
    x_train = scaler.fit_transform(x_train)
    x_test = scaler.fit_transform(x_test)
  • 邏輯迴歸
    #邏輯迴歸
    model = LogisticRegression()
    model.fit(x_train,y_train)
  • 預測
    # 預測
    predict = model.predict(x_test)
    right = sum(predict == y_test)

    predict = np.hstack((predict.reshape(-1,1),y_test.reshape(-1,1)))   # 將預測值和真實值放在一塊,好觀察
    print predict
    print ('測試集準確率:%f%%'%(right*100.0/predict.shape[0]))          #計算在測試集上的準確度
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章