邏輯回歸那些事兒(附模板代碼)

邏輯回歸(logistic regression)被廣泛用于分類預(yù)測,例如:銀行通過客戶的用戶行為判斷客戶是否會流失,醫(yī)院通過病人腫瘤的形態(tài)特征判斷腫瘤是否為良性,電子郵箱通過對郵件信息的識別判斷是否為垃圾郵件等等。作為目前最流行使用的一種學(xué)習(xí)算法,邏輯回歸能非常有效地對數(shù)據(jù)進行分類。

1. 回歸假設(shè)

h_θ (x)=g(θ^T X),其中: X代表特征向量(即影響因子向量),θ^T代表參數(shù)的轉(zhuǎn)置矩陣,g 代表一個常用的邏輯函數(shù),為S形函數(shù)(Sigmoid function),公式為:g(z)=1/(1+e^{(-z)} )。合起來,我們可以得到邏輯回歸的假設(shè)函數(shù)為:
h_θ (x)=1/(1+e^{(-θ^T X)} )
其中,θ^T X是參數(shù)θ和特征X的向量運算,展開就是:
θ^T X=θ_0+θ_1 x_1+θ_2 x_2+...+θ_n x_n(n代表特征的數(shù)量)

1)S形函數(shù)

  • 實際上,我們套用了S形函數(shù)進行邏輯回歸的計算。這是個非常經(jīng)典的分類函數(shù),是機器學(xué)習(xí)入門必須掌握的基礎(chǔ)知識。
  • 函數(shù)是一個分數(shù),取值在0-1之間。
  • z<0時,g(z)<0.5;當z=0時,g(z)=0.5;當z>0時,g(z)>0.5
    image.png
  • S函數(shù)用python代碼實現(xiàn)為:
import numpy as np
def sigmoid(z):
   return 1 / (1 + np.exp(-z))

2)假設(shè)判斷

  • h_θ (x)表示的是:根據(jù)參數(shù)得出因變量y為1的概率/可能性(estimated probablity),即h_θ (x)=P(y=1|x;θ)
  • 一般地,我們判斷:
    • h_θ (x)<=0.5,則分類為y=0h_θ (x)>0.5,則分類為y=1。

=舉個栗子=
假設(shè)病人患惡性腫瘤為y=1,未患惡性腫瘤為y=0?,F(xiàn)根據(jù)腫瘤大?。?img class="math-inline" src="https://math.jianshu.com/math?formula=x_1" alt="x_1" mathimg="1">)和腫瘤顏色(x_2)兩個特征可以得到邏輯回歸模型為:h_θ (x)=g(θ^T X)=g(θ_0+θ_1 x_1+θ_2 x_2)=1/(1+e^{-(θ_0+θ_1 x_1+θ_2 x_2)})
其中,參數(shù)θ_0=-0.8,θ_1=0.01,θ_2=-0.05,則模型為:
h_θ (x)=1/(1+e^{-(-0.8+0.01 x_1-0.05 x_2)})
已知一名病人的腫瘤大小為1cm,腫瘤顏色分類為5,則代入模型計算得到h_θ (x)=0.26,說明病人患惡性腫瘤的概率為0.26,概率低于0.5,由此我們將病人分類為“未患腫瘤(y=0)”。

3)決策邊界

  • 決策邊界是對分類預(yù)測的可視化。如上文所說,一般以h_θ (x)=0.5進行分類,而此時z=θ^T X=0
    image.png
  • 當特征變量X只有1-3個時,我們可以通過散點圖畫出θ^T X=0的決策邊界,幫助我們更好地理解分類正確率,但畫出決策邊界不是必須的。因為大部分時候,特征變量都會多于3個,這時,我們就很難畫出決策邊界,一般通過混淆矩陣判斷預(yù)測的準確度。

2.特征縮放

  • 特征縮放(feature scaling)其實就是將所有的特征變量縮放到相近的尺度,以便減少計算量,更快地構(gòu)建模型,最常用的方法是通過均值歸一化(mean normalization)將所有特征的尺度都盡量縮放到-1到1之間。即:
    x_n=(x_n-μ_n)/s_n ,(μ_n是平均值,s_n為標準差)
  • 這是模型構(gòu)建前必做的數(shù)據(jù)預(yù)處理動作,能有效減少計算量。
  • 特征縮放用Python代碼實現(xiàn)為:
import numpy as np
def featurescaling(X):
  X=(X-np.average(X))/np.std(X)
  return X

3. 損失函數(shù)

  • 構(gòu)建預(yù)測模型就需要定義損失函數(shù)。損失函數(shù)也叫代價函數(shù)(loss function),簡單理解,就是計算預(yù)測值與實際值之間的誤差。通過計算損失(loss),我們才能判斷模型的準確度。通用公式如下:

J(θ)=1/m ∑_{(i=1)}^mCost(h_θ (x^{(i)} ),y^{(i)})(m表示樣本數(shù)量)
對于邏輯回歸,我們采用對數(shù)計算損失,其中:

image.png

簡化可以得到:

最終可以得到邏輯回歸的代價函數(shù)為:

  • 損失函數(shù)用Python代碼實現(xiàn)為:
import numpy as np
def costfunction(theta, X, y):
  theta = np.matrix(theta)
  X = np.matrix(X)
  y = np.matrix(y)
  part_1 = np.multiply(-y, np.log(sigmoid(X @ theta.T)))# 引用了sigmoid函數(shù)
  part_2 = np.multiply((1 - y), np.log(1 - sigmoid(X @ theta.T)))
  return np.sum(part_1 - part_2) / (len(X))

4.優(yōu)化算法:梯度下降

  • 既然我們通過損失函數(shù)計算了損失,那么為了減少損失,我們就需要對參數(shù)進行不斷的優(yōu)化。
  • 梯度下降(gradient descent)是一個用來求函數(shù)最小值的算法,非常強大可靠,主要是通過代價函數(shù)的導(dǎo)數(shù)更新優(yōu)化參數(shù),直至達到代價函數(shù)的局部最小值,通用公式為:
    Repeat { θ_j:=θ_j-α ?/?θ_j J(θ) (同時更新所有的θ_j ) }
    根據(jù)微積分知識,簡化后可以得到θ_j:=θ_j-α /m ∑_{(i=1)}^m[(h_θ (x^{(i)})-y^{(i)})x_j^{(i)} ], (α為學(xué)習(xí)速度(learning rate),m為樣本數(shù)量)
  • α控制我們按多大的幅度去更新參數(shù)。如果a太小,梯度下降計算慢;如果a太大,那么梯度下降可能會越過最低點,導(dǎo)致無法收斂,甚至發(fā)散。
  • 梯度下降用Python代碼實現(xiàn)為:
def gradientDescent(X, y, theta, alpha, iters):#iters表示更新迭代次數(shù)
    theta = np.matrix(theta)
    X = np.matrix(X)
    y = np.matrix(y)
    
    temp = np.matrix(np.zeros(theta.shape))# 設(shè)置temp作為theta的轉(zhuǎn)換
    parameters = int(theta.ravel().shape[1]) # 計算參數(shù)的數(shù)量
    cost = np.zeros(iters)
    
    # 設(shè)置迭代循環(huán)
    for i in range(iters): 
        error = sigmoid(X @ theta.T) - y # 引用sigmoid函數(shù)
        
        for j in range(parameters):
            term = np.multiply(error, X[:,j])
            temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
            
        theta = temp
        cost[i] = costfunction(theta, X, y) # 引用costfunction函數(shù)
        
    return theta, cost
  • 除了梯度下降算法以外,還有很多其他更高級的優(yōu)化算法,本文就不多贅述了。

4. 模板代碼

  • 了解了邏輯回歸的數(shù)學(xué)知識之后,實際工作中,我們不需要自己定義損失函數(shù)和優(yōu)化算法,有成熟的機器學(xué)習(xí)庫可供我們直接調(diào)用。比如,sklearn中邏輯回歸函數(shù)可調(diào)用的優(yōu)化算法就有:liblinear, newton-cg, lbfgs, sag 和 saga,默認使用lbfgs。
  • 下面是調(diào)用sklearn庫的模板代碼:
# 1.創(chuàng)建X和y
X = df.iloc[:,:-1].values # 需根據(jù)實際情況更改
y = df.iloc[:,-1].values # 需根據(jù)實際情況更改

# 2.將數(shù)據(jù)分成訓(xùn)練集和測試集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)

# 3.特征縮放(Feature Scaling)
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)#轉(zhuǎn)換變量
X_test = sc_X.fit_transform(X_test)#轉(zhuǎn)換變量

# 4.利用邏輯回歸進行分類
from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(random_state=0)
classifier.fit(X_train,y_train)

# 5.預(yù)測測試集中的y值
y_pred = classifier.predict(X_test)

# 6.用混淆矩陣檢測準確率
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test,y_pred)

如有錯誤,請指正。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容