逻辑回归(logistics regression)

前面我们利用了线性回归模型进行了回归学习,接下来将在此基础上学习逻辑回归

1.算法概论

逻辑回归(又称对数几率回归)是一个二分类算法。逻辑回归是在线性回归的基础上,利用一个单点可微(确保可以求导进行梯度下降优化)的函数将预测值投影到一定范围(如:[0,1]),将分类任务的标签和线性回归的预测值联系起来。

  1. 使用“单位跳跃函数”:
    在这里插入图片描述

    这种方法简单粗暴直接以0为界限,Z=ωTx,Z>=0取标签1;Z<0取标签0。这是比较理想的函数,但它不连续,这意味着不可微,无法使用。

  2. 使用“sigmod函数”:
    在这里插入图片描述
    该函数具有很强的鲁棒性且可微,并且将函数的输入范围(∞,-∞)映射到了输出的(0,1)之间且具有概率意义。具有概率意义是怎么理解呢?将一个样本输入到我们学习到的函数中,输出0.95,意思就是这个样本有95%的概率是正例,5%的概率为负例。

2.目标函数

逻辑回归利用sigmod函数将预测值映射到区间[0,1]
在这里插入图片描述
其中Z=ωTx

3.损失函数

现在我们要找到一组w,使得g(z)预测正确的概率达到最大。这里使用的是交叉熵函数:
在这里插入图片描述
P(正确)表示每个样本预测正确的概率,如何理解呢?当yi=0时,我们希望g(zi)尽量的接近0;当yi=1时,g(zi)尽量接近1,从提高预测效果。一个样本真实值y是1,同样预测为1,g(z1)=0.65,g(z2)=0.95,我们更倾向于g(z2),这好比g(z1)还有35%的可能预测为0,而g(z2)有5%的可能预测为0。

所以问题转化为:将每个样本的P(正确)进行连乘是结果最大化
loss:
在这里插入图片描述

连乘过于复杂,我们进行两边取对数转化成累加的形式:
在这里插入图片描述

一般我们进行的是loss的最小化,所以在loss里加一个负号,转化成求min:
在这里插入图片描述
ko,我们的损失函数已经出来了。

4.梯度下降最小化损失函数

进行损失函数梯度公式推导
在这里插入图片描述

为了看出逻辑回归和线性回归的联系,这里在进行线性回归的方差梯度下降优化
在这里插入图片描述
结果是惊人的,两者极其相似,逻辑回归仅仅在线性回归的基础上嵌套了一个sigmod函数。

5.代码实现

这里的PimaIn dians二分类数据集来自UCI机器学习免费数据集

# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split#将数据分为测试集和训练集
from sklearn.linear_model import LogisticRegression

class LogisticsReg:
    
    def __init__(self):
        self.theta = None#参数
        self.pred = None#函数预测值
        
    def sigmod(self,x):
        return 1.0/(1+np.exp(-x))
        
        
    def fit(self,x_train,y_train,eta,theta,nlim,base):
        
        b0 = np.ones((len(x_train),1))
        x_train = np.column_stack((b0,x_train))
        y_train = y_train.reshape((-1,1))#转化为二维 便于矩阵运算
        theta = np.full((len(x_train[0]),1),theta)
        
        #梯度
        def dloss(x_train,y_train,theta):
            return (x_train.T).dot((self.sigmod(x_train.dot(theta))-y_train))
        #损失
        def loss(x_train,y_train,theta):
            pred = self.sigmod(x_train.dot(theta))
            return (y_train*np.log(pred)+(1-y_train)*(1-np.log(pred))).sum()/len(x_train)
        
        lim = 0
        while(lim<nlim):
            dtheta = dloss(x_train,y_train,theta)#梯度
            theta = theta - eta*dtheta#更新theta
            lim += 1
            print('迭代{0}次后:loss={1}'.format(lim,loss(x_train,y_train,theta)))
        self.theta = theta
        return self
    
    def pridict(self,x_test,base):
        b0 = np.ones((len(x_test),1))
        x_test = np.column_stack((b0,x_test))
        self.pred = self.sigmod(x_test.dot(self.theta))
        pre = np.zeros((len(x_test),1))
        for i in range(len(x_test)):
            if(self.pred[i]>=base):
                pre[i] = 1
        return np.array(pre)
            
path = r"demo02_PimaIndians.csv"
df = np.array(pd.read_csv(path))
X = df[:,:df.shape[1]-1]
y = df[:,df.shape[1]-1:]


#***逻辑回归采用  正态化  中位数0 方差1  效果更好!!!!!!!!!!!
from sklearn.preprocessing import StandardScaler
transformer = StandardScaler().fit(X)
X = transformer.transform(X)

#归一化效果低于正态化
#from sklearn.preprocessing import MinMaxScaler
#transformer = MinMaxScaler(feature_range=(0,1))#[min,max]
#X = transformer.fit_transform(X)

x_train, x_test, y_train, y_test = train_test_split(X,y)#调用自己写的逻辑回归
model = LogisticsReg()
model.fit(x_train,y_train,eta=0.01,theta=0.0,nlim=50,base=0.5)
pred = model.pridict(x_test,0.5)
print(np.sum(pred==y_test)/len(y_test))


lr_model = LogisticRegression() #调用sklearn中的逻辑回归
lr_model.fit(x_train,y_train) #训练模型
print(lr_model.score(x_test,y_test))#获取测试集的评分       
  1. 在进行数据标准化时,进行了正态化和0,1归一化,前者的效果明显高于后者。
  2. 多次分别运行了自己写的和sklearn里的逻辑回归,发现准确率十分相近
迭代1次后:loss=1.6485242970168636
迭代2次后:loss=1.4759330326827378
迭代3次后:loss=1.4821138138600423
迭代4次后:loss=1.4441732981936897
迭代5次后:loss=1.4584545402659652
迭代6次后:loss=1.4459081613089284
迭代7次后:loss=1.452739982881904
迭代8次后:loss=1.4477218317530676
迭代9次后:loss=1.4508268647017737
迭代10次后:loss=1.44865529787048
迭代11次后:loss=1.4501124147837856
迭代12次后:loss=1.4491008791992024
迭代13次后:loss=1.4498213628733325
迭代14次后:loss=1.449313361783221
迭代15次后:loss=1.4496911350001405
迭代16次后:loss=1.4494177102552666
迭代17次后:loss=1.449627086675577
迭代18次后:loss=1.449471348317303
迭代19次后:loss=1.4495928490782275
迭代20次后:loss=1.449500362745007
迭代21次后:loss=1.44957333004759
迭代22次后:loss=1.4495168208810791
迭代23次后:loss=1.4495616930798658
迭代24次后:loss=1.449526525359131
迭代25次后:loss=1.4495545523390225
迭代26次后:loss=1.4495324138422463
迭代27次后:loss=1.4495500923150568
迭代28次后:loss=1.4495360580790384
迭代29次后:loss=1.4495472770545916
迭代30次后:loss=1.4495383428269015
迭代31次后:loss=1.4495454889602162
迭代32次后:loss=1.449539787102931
迭代33次后:loss=1.4495443491702866
迭代34次后:loss=1.4495407047878748
迭代35次后:loss=1.44954362112007
迭代36次后:loss=1.4495412897264153
迭代37次后:loss=1.4495431555160732
迭代38次后:loss=1.449541663290697
迭代39次后:loss=1.4495428575481115
迭代40次后:loss=1.4495419021433151
迭代41次后:loss=1.4495426667858065
迭代42次后:loss=1.4495420549715061
迭代43次后:loss=1.4495425446304386
迭代44次后:loss=1.4495421527996464
迭代45次后:loss=1.4495424663978531
迭代46次后:loss=1.449542215437533
迭代47次后:loss=1.4495424162913566
迭代48次后:loss=1.4495422555499364
迭代49次后:loss=1.4495423841977888
迭代50次后:loss=1.449542281239785
0.8333333333333334
0.8333333333333334
  1. 在调试模型时,发现迭代7次的正确率就已经与sklearn的模型一样了;而且在迭代一定次数后loss变化很小,所以我们可以考虑添加一个loss变化很小就停止迭代的条件。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值