python機器學習——邏輯迴歸方法

理論背景:

線性迴歸可以實現對連續結果的預測,但是現實生活中我們常見的另一種問題是分類問題,尤其是二分類問題,在這種情況下使用線性迴歸就不太合適了,我們實際上需要計算出的是一個在$[0,1]$之間的概率來告訴我們某樣本屬於某一類的概率,因此邏輯迴歸應運而生。

一般的邏輯迴歸就是在線性迴歸的基礎上嵌套一個邏輯函數,把線性迴歸的結果轉換成概率。

即我們定義$h_{\theta}(X)=P(y=1|X,\theta),1-h_{\theta}(X)=P(y=0|X,\theta)$,那麼我們希望最大化預測正確的概率,即我們要最大化:

$\prod_{i=1}^{m}P(y=y_{i}|X_{i},\theta)$

那麼也就是:

$\prod_{i=1}^{m}(h_{\theta}(X_{i})^{y_{i}}(1-h_{\theta}(X_{i}))^{1-y_{i}}$

這不好計算,兩側取對數再去取相反數就得到:

$J(\theta)=-\dfrac{1}{m}\sum_{i=1}^{m}y_{i}\log h_{\theta}(X_{i})+(1-y_{i})\log (1-h_{\theta}(X_{i}))$

這樣我們只需最小化這個損失函數就可以了,仍然使用梯度下降法確定參數,我們有:

$\hat{\theta_{j}}=\theta_{j}-\alpha \dfrac{\partial J(\theta)}{\partial \theta_{j}}$

對上式求偏導,最後我們得到:

$\hat{\theta_{j}}=\theta_{j}-\alpha \dfrac{1}{m}\sum_{i=1}^{m}(h_{\theta}(X_{i})-y_{i})x_{ij}$

而我們的操作是在線性模型的基礎上套上一個邏輯模型,也即我們的參數仍然是線性模型的參數$\theta$:

$z=\theta^{T}X$

在這個基礎上套上一個邏輯函數,這裏我們選擇的是sigmoid函數,即:

$g(z)=\dfrac{1}{1+e^{-z}}$

於是我們最後的函數即爲:

$h_{\theta}=\dfrac{1}{1+e^{-\theta^{T}X}}$

代碼實現:

 

import numpy as np
import math
from scipy import stats
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression

def sigmoid(z):
    return 1/(1+math.exp(-z))

def logical_regression(X,Y,theta,siz,alpha,eps):
    delt=1

    while delt>eps:
        new_theta=np.zeros(3)
        for i in range(0,3):
            r=theta[i]
            for j in range(0,siz):
                d=alpha/siz*(sigmoid(theta[0]*X[0][j]+theta[1]*X[1][j]+theta[2]*X[2][j])-Y[j])*X[i][j]
                r-=d
            new_theta[i]=r
            print(new_theta[i])
        delta=new_theta-theta
        delt=delta[0]**2+delta[1]**2+delta[2]**2
        theta=new_theta
    return theta

x=np.arange(0.,10.,0.02)
y=5-2*x/3+np.random.randn(500)
now=0
dataset=[]
for i in range(0,500):
    typ = 0
    if 2*x[i]+3*y[i] <= 15:
        if abs(np.random.randn(1)[0])<2:
            typ = 1
        else:
            typ = 0
    else:
        if abs(np.random.randn(1)[0]) < 2:
            typ = 0
        else:
            typ = 1

    dataset.append([x[i],y[i],typ])

X=(np.array(dataset)[:,0:2]).T
x0=np.ones(500)
X=np.vstack([x0,X])
Y=(np.array(dataset)[:,2])
theta=np.array([1,1,1])


my_theta=logical_regression(X,Y,theta,500,1e-2,1e-7)

print(my_theta)

for i in range(0,500):
    if Y[i]==1:
        plt.scatter(X[1,i],X[2,i],c='r')
    else:
        plt.scatter(X[1,i],X[2,i],c='b')
plt.plot(x,-my_theta[1]/my_theta[2]*x-my_theta[0]/my_theta[2],c='g',linewidth=3)
plt.show()

這個代碼生成了一組以直線$2x+3y-15=0$爲分界的數據,並且加入了一定的隨機化,最後通過邏輯迴歸能夠找出這條直線,當然這裏的參數選取同樣也很重要

小結與優化:

邏輯迴歸中在一定程度上存在欠擬合的問題,因爲很多時候分界線並不是直線而是曲線,此時單純的線性函數已經無法擬合邊界了,一個解決方案是引入更多維度,比如把$[x_{1},x_{2}]$擴展成$[x_{1},x_{2},x_{1}^{2},x_{2}^{2}]$,這樣就可以更好擬合二次曲線形成的邊界,以此類推等。

而精度問題則可能是由於數據特徵有缺失或數據空間太大等,遇到這種情況可以加入正則化的一項使模型縮減係數,有利於提高模型的泛化能力。

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