邏輯回歸原理,推導,sklearn應用


邏輯回歸原理,推導,及sklearn中的使用


1 從線性回歸過渡到邏輯回歸

對於線性回歸而言,標簽是連續值,線性回歸的任務就是構造一個預測函數來映射輸入的特征矩陣 x 和標簽值 y 的關系,要構造出這個預測函數的核心就是找到參數矩陣 θ^T^,通過預測函數,可以通過輸入的特征矩陣 x ,來得到連續型的預測值。

線性回歸的標簽是連續值,那如果標簽是離散值的呢?具體點就是那種只有 0,1 兩種值的呢?這個時候如果有一個函數,可以使得我們輸入了一個連續值(線性回歸預測出來的結果),把這個值歸一化到 (0, 1) 之間,那么就可以從概率的角度來看,如果這個值大於 0.5,就把其歸類到 1,如果這個值小於 0.5,就把其歸類到 0。此時 Sigmoid 函數就出現了。

Sigmoid 函數:

\[g(x) = \frac{1}{1 + e^{-z}} \]

對於 Sigmoid 函數,在 z > 0 時,0.5 < y < 1,z -> inf ,y -> 1。

線性回歸預測函數 \(z=θ^Tx\) 預測得到的連續值代入Sigmoid函數,便得到了邏輯回歸模型的預測函數 \(y(x)=\frac{1}{1 + e^-z}\)

關於決策邊界的一些解惑:

  • 邏輯回歸要做的事情就是找出決策邊界,來划分出兩種不同的分類。對於二維的特征矩陣 x,決策邊界就是一條曲線,對於三維的特征矩陣 x,決策邊界就是一個平面,對於 n 維的特征矩陣 x,決策邊界就是 n-1 維的超平面,決策邊界的構造,是對於特征向量 x~i~ 來說的。
  • 決策邊界就是 令 \(y(x)\) = 0,得到的超平面
  • 令 $ y(x) > 0$ ,得到的就是 標簽為 1 的樣本,即在決策邊界某一邊的樣本,$ y(x) < 0$ 就是標簽為 0 的樣本,通過決策邊界划分。

建模過程:找出最佳的 θ vector,來使得數據和模型的擬合程度最高,用這個θ vector來構建預測函數y(x),然后將特征矩陣輸入到預測函數來輸出預測結果y。

2 邏輯回歸的損失函數

2.1 邏輯回歸損失函數的推導

要得到參數向量 \(θ^T=[ θ_0,θ_1,θ_2,θ_3...θ_n]\),來最好的擬合出一個模型,就要找出這個模型的損失函數,最小化這個損失函數,來得到對應的 \(θ^T\),那么應該如何得到這個損失函數呢?

首先要理解的一個地方是,經過 Sigmoid 函數進行歸一化的數值是介於 0 到 1 之間的,那么這個值就可以看成是一個概率值,這個概率值的含義是,對於給定的一個樣本 \(x_i\) 和 參數向量 \(θ^T\),該 \(x_i\) 能被預測為 標簽1 的概率,我們把這個概率用 \(y_θ(x_i)\)來表示如下:

樣本 i 由特征向量 \(x_i\) 和 參數向量 θ 組成的預測函數中,樣本被預測為 標簽1 的概率:

\[P_1 = P(\hat{y}|x_i,θ) = y_θ(x_i) \]

樣本 i 由特征向量 \(x_i\) 和 參數向量 θ 組成的預測函數中,樣本被預測為 標簽0 的概率(由於服從0-1分布):

\[P_0 = P(\hat{y}|x_i,θ) = 1 -y_θ(x_i) \]

那么把這兩個概率整合得到聯合概率公式,可以得如下形式:

\[P(\hat{y}|x_i,θ) = P_1^{y_i} * P_0^{1-y_i} \]

對於一個樣本 i ,當 \(y_i = 0\) 時,\(P(\hat{y}|x_i,θ) = P_0\),此時,我們希望 \(P_0\) 越接近於 1 越好,因為這樣取到 標簽 0 的概率越大。當 \(y_i = 1\) 時,\(P(\hat{y}|x_i,θ) = P_1\),此時,我們希望 \(P_1\) 越接近於 1 越好,因為這樣取到 標簽 1 的概率越大。所以不管怎樣,我們都希望\(P(\hat{y}|x_i,θ)\) 的 取值越大越好,越接近於 1 越好,這樣得到的結果更接近於預期值,即損失更小。所以我們要獲取它的最大值,現在的問題,就由將模型擬合中的“最小化損失”問題,轉換成了對函數求解極值的問題。

那么對數據集中的m個樣本,得到的聯合概率公式:

\[\begin{align} J(\theta) &= \prod_{i=0}^nP(\hat{y}|x_i,θ) \\ &= \prod_{i=0}^nP(P_1^{y_i} * P_0^{1-y_i}) \\ \end{align} \]

對聯合概率公式 \(J(θ)\) 兩邊同時取對數,在根據對數運算的公式:

\[\begin{align} logJ(\theta) &= log\prod_{i=0}^nP(P_1^{y_i} * P_0^{1-y_i}) \\ &= \displaystyle \sum^{m}_{i=1}logP(y_\theta(x_i)^{y_i} * (1-y_\theta(x_i))^{1-y_i}) \\ &= \displaystyle \sum^{m}_{i=1}( log(y_\theta(x_i)^{y_i} + log(1-y_\theta(x_i)^{1-y_i})\\ &= \displaystyle \sum^{m}_{i=1}( y_i*log(y_\theta(x_i) + (1-y_i)*log(1-y_\theta(x_i))\\ \end{align} \]

因為此處時求解聯合概率函數的最大值,要轉化為求其最小值,只須求 \(-logJ(\theta)\) 即可,如此,便得到了邏輯回歸的損失函數\(J(\theta)\)

\[J(θ) = -\displaystyle \sum^{m}_{i=1}(y_i * log(y_θ(x_{i}))) + (1 - y_i) * log(1 - y_θ(x_i)) \]

這個推導過程實際上就是"極大似然估計 MLE"的過程。

概率與似然:

  • 對於聯合概率函數 \(P(\hat{y}|x_i,θ)\) 而言。
  • 概率探究的是自變量與因變量之間的關系,即 \(\theta\) 已知,在不同的特征向量 \(x_i\) 下,得到 \(\hat{y}\) 的可能性。
  • 似然**探究的是參數向量與因變量之間的關系,即 \(x_i\) 已知,在不同的參數向量 \(\theta\) 下,得到 \(\hat{y}\) 的可能性。
  • 對於邏輯回歸的建模過程,\(\theta\) 是未知的,\(x_i\) 是已知的,所以這里求解的聯合概率函數(似然函數)的結果是 "似然",而因為要最大化似然函數,這個過程稱為 "極大似然"。

求最大似然函數估計的一般步驟:

  1. 寫出似然函數
  2. 對似然函數取對數,得到對數似然函數
  3. 如果對數似然函數可導,就對似然函數求導,解方程組,得到駐點
  4. 分析駐點為極大值的點

對於邏輯回歸的最大似然函數,要求解對數似然函數可導=0,是一個NP難問題,所以步驟3,4不可行,又因為對數似然函數是一個凸函數,只會存在一個最小值,對於梯度下降法沒有收斂到局部最小值煩惱,所以使用梯度下降法

2.2 梯度下降法

邏輯回歸的建模過程,就是要求解參數向量 \(\theta\) ,使得模型最好的擬合數據。而求解 \(\theta\) 的值是通過最小化損失函數得到的,這個過程使用梯度下降法。

梯度下降法,是一個基於搜索的最優化算法,用來最優化一個損失函數

姑且來拆解這個方法中的詞:

  • 梯度:梯度就是函數值增加得最快的方向,梯度的反方向就是函數值減小得最快的方向
  • 下降:沿着梯度下降最快的方向一直走,直到到達函數的最小值,或附近。

梯度下降法的求解過程:

  1. 損失函數 \(J(\theta)\) 上隨機選擇一個點,初始化 \(\theta\) 向量的取值,給定一個步長 \(\eta\)
  2. 求當前位置的梯度 \(gard\) (對自變量求偏導),用參數向量 \(\theta\) 減去 \(gard * \eta\)
  3. 重復步驟 2 ,直到 \(\theta - gard * \eta\) 的值小於某一個閾值,或者達到最大的迭代次數 max_iter
  4. 此時對應的參數向量就是損失函數取得最小值的參數向量

根據上面求解梯度下降法的過程,可以得知一個重要的參數 max_iter ,控制着迭代的次數,在 sklearn 里面的 Logistic Regression 是沒有步長這個參數的,這個迭代的過程僅由參數 max_iter 來控制,max_iter 過小,算法可能沒收斂到最小值,max_iter 過大,算法收斂緩慢。

有一個疑問是:max_iter 過大,不會跳過了最小值點嗎?

其實迭代次數多了是沒問題的,因為迭代次數多了后,在到達極值點時,函數對自變量的導數已近乎為0,即使過了極值點,導數就變為正數了,此時,參數向量的值減去步長與梯度的乘積反倒變小了。所以即使步數多了,結果也基本上就在極值點處左右徘徊,幾乎等於極值點。

2.3 正則化

雖然邏輯回歸和線性回歸是天生欠擬合的模型,但我們還是需要控制過擬合來調整模型,對邏輯回歸中過擬合的控制,通過正則化來實現。

常用的正則化有 \(L_1\)正則化\(L_2\)正則化,分別通過在損失函數后 θ 加上參數向量的L1范式和L2范式的倍數來實現。這個增加的范式成為 "正則項" 或 "懲罰項",利用正則項來約束J(θ) 中θ的取值不至於過大,來防止過擬合。

\[J(\theta)_{L_1} = C*J(\theta) + \displaystyle \sum^{n}_{j=1}|\theta_j|\\ J(\theta)_{L_2} = C*J(\theta) + \sqrt {\displaystyle \sum^{n}_{j=1}(\theta_j)^2}\\ \]

對應於 Lasso Regression 和 Ridge Regression 的 \(L_1\)\(L_2\) 正則化

\(L_1\) 正則化 很容易把某個參數 \(\theta\) 變為 0,因為這種特性,\(L_1\) 正則化 會篩掉一些特征,可能時有用的特征也可能時沒用的特征。而 \(L_2\) 正則化 只會把 \(\theta\) 變為一個很小的值而不會變為 0。一般都使用,\(L_2\) 正則化,當數據量很大的時候就使用 \(L_1\) 正則化,來篩掉一些特征。

3 用邏輯回歸進行多分類

OvO (One vs One):用不同標簽的數據,兩兩類別之間使用邏輯回歸得到一個分類器(這個分類器用來區分這兩種類別中的某一個),把要預測的樣本傳入到這些分類器當中,得到對應的概率,取在所有分類器對比中概率最高的作為分類結果。

OvR (One vs Rest):取出某一類樣本,和剩下的樣本之間構建分類器(這個分類器是用來區分是這個樣本和不是這個樣本的數據),把要預測的樣本傳入到這些分類器當中,得到對應的概率,取在所有分類器對比中概率最高的作為分類結果。

OvO的分類時間更長,但是結果更加精准。

4 sklearn中的 LogisticRegression

  • linear_model.LogisticRegression

4.1 max_iter

控制梯度下降的迭代次數

  • 邏輯回歸的運行受到最大迭代次數的強烈影響

  • max_iter 過小,可能沒有收斂到最小值。

  • max_iter 過大,梯度下降迭代次數過多,模型運行時間緩慢。

4.2 penalty & C

選擇正則項,和正則化強度的系數

參數 說明
penalty 可以輸入"l1"或"l2"來指定使用哪一種正則化方式,不填寫默認"l2"。注意,若選擇"l1"正則化,參數solver僅能夠使用求解方式”liblinear"和"saga“,若使用“l2”正則化,參數solver中所有的求解方式都可以使用。
C C正則化強度的倒數,必須是一個大於0的浮點數,不填寫默認1.0,即默認正則項與損失函數的比值是1:1。C越小,損失函數會越小,模型對損失函數的懲罰越重,正則化的效力越強,參數會逐漸被壓縮得越來越小。

4.3 multi_class

multi_class 表示我們要預測的分類是多分類,還是二分類的

默認值是 'ovr',表示當前處理的是二分類,或以"一對多"的形式處理多分類問題。

'multinomial':表示處理多分類問題。

'auto':表示自動選擇

4.4 solver

求解損失函數的方式

默認是 'liblinear' ,坐標下降法

還有'sag' 隨機平均梯度下降法,其實就是Mini Batch gradient descent,小批量的梯度下降,介於梯度下降法和隨機梯度下降法的擇優方法。

還有 'newton-cg','saga'等方法可選

4.5 class_weight

現實當中正負樣本的比例往往很不平衡,比如100個瀏覽此商品的人中,只有一個人購買了此商品,剩下99個人沒有購買,class_weight就是平衡不同標簽數據樣本的比重,通過給少量的標簽增加權重

參數為'balanced' 和 None,默認為None

因為'balanced'參數比較難用,我們要對不平衡的樣本進行采樣處理,由如下方法

# 使用上采樣(增加樣本量少的樣本的數量)的方法平衡樣本
import imblearn
from imblearn.over_sampling import SMOTE

sm = SMOTE(random_state=42) #實例化 X,y = sm.fit_sample(X,y)
 
n_sample_ = X.shape[0]
 
pd.Series(y).value_counts()
 
n_1_sample = pd.Series(y).value_counts()[1] n_0_sample = pd.Series(y).value_counts()[0]
 
print('樣本個數:{}; 1占{:.2%}; 0占 {:.2%}'.format(n_sample_,n_1_sample/n_sample_,n_0_sample/n_sample_))

5 邏輯回歸的優點與應用

邏輯回歸的優點

​ 1.LR能以概率的形式輸出結果,而非只是0,1判定

​ 2.對線性關系的擬合效果好,LR的可解釋性強,可控度高

​ 3.訓練快,特征工程(featureengineering)之后效果贊

​ 4.因為結果是概率,可以做排序模型

​ 5.添加特征方便

​ 6.在小型數據上 抗噪不錯

出現的應用場景

1.CTR預估/推薦系統的learningtorank/各種分類場景

2.很多搜索引擎廠的廣告CTR預估基線版是LR

3.電商搜索排序/廣告CTR預估基線版是LR

4.新聞app的推薦和排序基線也是LR

6 本人的一些思考

Sigmoid函數:把線性回歸得到的直線或者曲線變成決策邊界

為什么把線性回歸的值帶入Sigmoid函數就可以變成決策邊界?

​ 假設Sigmoid(z) ,z就是線性回歸的表達式,在sigmoid函數中自變量是z,z分為>0和<0。z=0就是指決策邊界,z>0就是二元分類中的某一類,z<0就是二元分類中的另一類。

關於坐標系:

​ 使用梯度下降獲取損失函數的最小值的時候,縱坐標是J(θ),所有橫坐標是[x1, x2, x3···]

​ 進行分類時,即觀看分類結果,觀看決策邊界時,所有的維度都是x1, x2, x3···xn

對於 n 維的數據,決策邊界就是 n-1 維的超平面

決策邊界就是令Sigmoid函數等於0的那個地方,決策邊界的呈現是對於特征向量來呈現的,即如果有兩個特征x1, x2,那么橫坐標和縱坐標分別為x1, x2,然后畫出決策邊界就是,令Sigmoid(x1)=0畫出x2的值。

7 常用代碼

# 畫出決策邊界
def plotData(data, label_x, label_y, label_pos, label_neg, axes=None):
    # 獲得正負樣本的下標(即哪些是正樣本,哪些是負樣本)
    neg = data[:,2] == 0
    pos = data[:,2] == 1
    
    if axes == None:
        axes = plt.gca()
    axes.scatter(data[pos][:,0], data[pos][:,1], marker='+', c='k', s=60, linewidth=2, label=label_pos)
    axes.scatter(data[neg][:,0], data[neg][:,1], c='y', s=60, label=label_neg)
    axes.set_xlabel(label_x)
    axes.set_ylabel(label_y)
    axes.legend(frameon= True, fancybox = True)
    
# 畫出決策邊界 二維
plt.scatter(45, 85, s=60, c='r', marker='v', label='(45, 85)')
plotData(data, 'Exam 1 score', 'Exam 2 score', 'Admitted', 'Not admitted')
x1_min, x1_max = X[:,1].min(), X[:,1].max(),
x2_min, x2_max = X[:,2].min(), X[:,2].max(),
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max), np.linspace(x2_min, x2_max))
h = sigmoid(np.c_[np.ones((xx1.ravel().shape[0],1)), xx1.ravel(), xx2.ravel()].dot(res.x))
h = h.reshape(xx1.shape)
plt.contour(xx1, xx2, h, [0.5], linewidths=1, colors='b')

陸續補充~~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM