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}]$,这样就可以更好拟合二次曲线形成的边界,以此类推等。

而精度问题则可能是由于数据特征有缺失或数据空间太大等,遇到这种情况可以加入正则化的一项使模型缩减系数,有利于提高模型的泛化能力。

posted @ 2022-03-27 16:50  lleozhang  Views(421)  Comments(0Edit  收藏  举报
levels of contents