再讀線性迴歸 Linear Regression (邏輯迴歸)

1. 邏輯迴歸

線性迴歸算法旨在通過訓練一定量的樣本來預測 連續型數值(Continuous Value)(即迴歸問題)。當然了,聰明的科學家們早就想好如何將線性迴歸運用到 離散型數值(Discrate value) 的預測上了(即分類問題)。我們將這種運用在分類問題上的線性迴歸模型稱之爲 邏輯迴歸(Logistic Regression)

簡單的來說,邏輯迴歸僅僅是將線性迴歸的輸出值做了一定的處理,並設置一個閾值。當預測的輸出值大於或等於這個閾值時,將樣本分爲一類;當預測的輸出與之小於這個閾值時,將樣本分爲另一類。一個常見的例子就是給線性迴歸結果上加上 Sigmoid 函數(或稱 Logisitc 函數),如此一來,線性迴歸的輸出值就固定在 0 到 1 之間了。我們設置閾值爲 0.5,當預測值大於 0.5 時,認爲樣本爲正類;反之則爲負類。
在這裏插入圖片描述
上圖左邊展示了標準的 Sigmoid 函數,它將整個 x 軸平均分爲 2 部分,即 x0x \geq 0 時樣本爲正,當 x<0x < 0 時樣本爲負,我們記這個函數爲 g(z)g(z)。因此,邏輯迴歸的函數可以寫爲,

hθ(x)=g(θTx)g(z)=11+ez h_{\theta}(x) = g(\theta^Tx),其中 g(z)=\frac{1}{1+e^{z}}

其中,θ\theta 是 n+1 維參數向量(θR(n+1)×1\theta \in \mathbb{R}^{(n+1)\times1})。xx 表示單個樣本,也是 n+1 維向量(xR(n+1)×1x \in \mathbb{R}^{(n+1)\times1})。對於每個樣本 xx,我們通過計算其 hθ(x)h_{\theta}(x) 的值來判斷它到底術語正類還是負類,其預測類別爲,

={1hθ(x)0.50hθ(x)<0.5 類別 = \begin{cases} 1,h_{\theta}(x) \geq 0.5 \\ 0,h_{\theta}(x) < 0.5 \end{cases}

2. 決策邊界 Decision Boundary

線性迴歸和邏輯迴歸最大的不同在於預測值 hθ(x)h_{\theta}(x) 的計算。即在線性迴歸中,hθ(x)=θTxh_{\theta}(x)=\theta^Tx。而在邏輯迴歸中,hθ(x)=g(θTx)h_{\theta}(x)=g(\theta^Tx)。若設置分類的閾值爲 0.5,那麼判斷 hθ(x)h_{\theta}(x) 與 0 的關係,等價於判斷 θTx\theta^Tx 與 0 的關係。換句話說,如果 θTx\theta^Tx 大於等於 0,則 xx 爲正類樣本,反之則爲負類樣本。因此,θTx=0\theta^Tx=0 構成了邏輯迴歸的決策邊界,具體的,

θTx=θ0x0+θ1x1+...+θnxn=0. \theta^Tx = \theta_0x_0+\theta_1x_1 + ...+\theta_nx_n = 0.

2.1 線性決策邊界

舉個例子,現需要針對下圖中的正類和負類樣本進行分類。每個樣本 x=(x1;x2)x=(x_1;x_2) 都是一個二維向量。現在,假設我們訓練好的參數 θ=(3;1;1)\theta=(-3;1;1),那麼我們根據邏輯迴歸生成的決策邊界爲 ,

3+x1+x2=0 決策邊界:-3+x_1+x_2=0

由於這個決策邊界是關於 x1,x2x1,x2 的線性表達式,故這個決策邊界也成爲線性決策邊界。線性決策邊界是分類問題中最簡單最基礎的。
在這裏插入圖片描述

2.2 非線性決策邊界

另一個例子,假設正類和負類樣本的分佈如下圖所示,我們很難通過一條直線將它們分割開。這個時候我們需要一個非線性的決策邊界。這個時候簡單的 x1,x2x1,x2 2 項不能很好的分類,我們需要增加到 2 次方的多項式,如 x12x_1^2x22x_2^2。那麼假設學習到的參數 θ=(2;0;0;1;0;1)\theta=(-2;0;0;1;0;1),那麼對應的決策邊界爲,

2+x12+x22=0 決策邊界:-2 + x_1^2 + x_2^2 = 0

因此,只要將回歸方程中的項的次數升高,邏輯迴歸還是具有很強的非線性分類能力的。

在這裏插入圖片描述

3. 代價函數

邏輯迴歸的代價函數 J(θ)J(\theta) 比較特別,它與線性迴歸的代價函數不同,它更多的是一個分段函數形式呈現。也就是說,當樣本 x(i)x^{(i)} 是正類(y(i)=1y^{(i)}=1)或負類(y(i)=0y^{(i)}=0)時,計算代價的公式是不同的。【這麼做的原因是保持代價函數是凸函數,也即保持只有一個全局優點】

x(i)={log(hθ(x(i)))y(i)=1log(1hθ(x(i)))y(i)=0 x^{(i)} 的代價 = \begin{cases} -log(h_{\theta}(x^{(i)})),y^{(i)}=1 \\ -log(1-h_{\theta}(x^{(i)})),y^{(i)}=0 \end{cases}

首先,當樣本本來是正類時,根據 log(x)-log(x) 可知:預測值越是接近 1,代價越小;當預測值越是接近 0,代價變得非常大(無窮大)。與之相反,當樣本本來是負類時,根據 log(1x)-log(1-x) 可知:預測值越是接近 1,代價變得大(無窮大);當預測值越是接近 0,代價越小。這個設計不得不說十分巧妙。
在這裏插入圖片描述
通常,爲了簡化代價函數(將多行寫成一行的形式),我們在前面添加參數 yy(1y)(1-y),這樣代價函數 x^{(i)} 的代價也可以寫成,

x(i)=y(i)[(1)×log(hθ(x(i)))]+(1y(i))[(1)×log(1hθ(x(i)))] x^{(i)} 的代價 =y^{(i)}[(-1)\times log(h_{\theta}(x^{(i)}))]+(1-y^{(i)})[(-1)\times -log(1-h_{\theta}(x^{(i)}))]

因此總的代價函數 J(θ)J(\theta) 可看做是所有樣本 x(i)x^{(i)} 的代價之和(mm 表示樣本個數),記爲,

J(θ)=1mi=1m{y(i)[(1)×log(hθ(x(i)))]+(1y(i))[(1)×log(1hθ(x(i)))]} J(\theta)= \frac{1}{m}\sum_{i=1}^{m} \{y^{(i)}[(-1)\times log(h_{\theta}(x^{(i)}))]+(1-y^{(i)})[(-1)\times -log(1-h_{\theta}(x^{(i)}))]\}

4. 參數優化

在邏輯迴歸中,我們沿用之前介紹的梯度下降算法(Gradient Descent)。通過每次迭代中對參數的調整來實現代價函數最小化,邏輯迴歸同樣是求解出使得代價函數最小的參數集合 θ\theta

θ=argminθJ(θ) \theta = \mathop{\arg\min}_{\theta} J(\theta)

同樣的,我們對代價函數求導,發現其梯度與線性迴歸的梯度一模一樣,

Jθj=1mi=1m(hθ(x(i))y(i))xj(i)j=0,2,...,n \frac{\partial J}{\partial \theta_j} = \frac{1}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})x^{(i)}_j,j=0,2,...,n

每一輪迭代,調整的參數也是類似,令 α\alpha 爲學習率,則參數項 θj\theta_j 調整過程爲,

θj=θjαmi=1m(hθ(x(i))y(i))x(i) \theta_j = \theta_j - \frac{\alpha}{m}\sum_{i=1}^{m}(h_{\theta}(x^{(i)})-y^{(i)})x^{(i)}

我們將 j 推廣到一般情況,即每次對待看做是對 θ\theta 上的矩陣操作,令 XXYY 分別表示特徵集合和標籤集合,我們得到每次迭代的新的 θ\theta 應該等於(等式同樣適用於線性迴歸),

θ=θαmXT(XθY) \theta = \theta - \frac{\alpha}{m} X^T(X\theta-Y)

可以說,參數調優過程跟線性迴歸一模一樣。但是注意,邏輯迴歸的 hθ(x)h_{\theta}(x) 與線性迴歸的不同。


5. Sklearn 實現

Sklearn 同樣提供了邏輯迴歸算法的現成品,即 sklearn.linear_model.LogisticRegression1 。實例代碼如下,函數logistic_regression_example() 建立了一個邏輯迴歸模型的框架,函數 set_arguments() 列出了邏輯迴歸中比較重要的參數。

from  sklearn.linear_model import LogisticRegression

def logistic_regression_example(args, train_x, train_y):
    # fit the train_x, train_y
    clf = LogisticRegression()
    clf.set_params(**args)
    clf.fit(train_x,train_y)
	return clf
    
def set_arguments():
    args = dict()
    args['penalty']='elasticnet' # 正則化方法, {'l1','l2','elasticnet',none'}
    args['l1_ratio']=0.5 # elasticnet 正則化情況下的 L1 正則化的比例
    args['class_weight']='balanced' # 類權值, {'balanced',dict={0:0.5,1:0.5}}
    args['max_iter']=800 # 迭代次數, default=100
    args['tol']=1e-4
    args['solver'] = 'saga' # 優化算法, {‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’}
    args['random_state']=0 # 隨機種子
    return args

值得一提的是優化算法的參數 solver ,它對邏輯迴歸的預測結果影響重大。默認的選擇有 ‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’, ‘saga’(具體見博文2)。不同的優化算法對應着不同的正則化的懲罰項 ,即penalty 參數。‘liblinear’ 在小數據集上效果不錯,此時 penalty 不能等於 ‘none’。其他的 ‘newton-cg’, ‘lbfgs’, ‘sag’ and ‘saga’ 算法,此時 penalty 必須等於 ‘l2’ 或者 ‘none’。支持 penalty=‘slasticnet’ 的只有 ‘saga’ 算法。這個在設置參數時應該留意。

另外,這個 class_weight 表示類權重,也就是說分類器分錯不同類的樣本的代價是不同的,這個參數可以取 ‘balanced’,也可以取一個字典,裏面標記不同權重的比例,如 ‘{0:0.5,0:0.5}’。不同的權重會導致決策邊界向正類或負類的方向偏移,這個參數也是處理類不平衡問題的一個好辦法。

最後,不同的參數調節出來的分類效果也是不一樣的,如下面 4 個子圖所示。由此看來,機器學習的調參確實是很玄學。
在這裏插入圖片描述


  1. LogisticRegression 官方文檔. Link ↩︎

  2. logistic 迴歸的sklearn實踐. Link ↩︎

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