逻辑斯蒂回归与梯度下降法

看了几位大神写的博客,对逻辑回归有了更深刻的理解,因此在这里简单记录一下自己的一些看法,当作笔记


1、逻辑回归


优势:

1、逻辑回归对线性关系的拟合效果很好

2、逻辑回归计算快

3、逻辑回归返回概率,很适合于金融的信用评分,可以依据概率来给出对应的评分

4、逻辑回归抗噪能力强

缺点:

1、不适用于于非线性模型

 

详细介绍:

      逻辑回归一般用于分类问题,而且多用于二分类问题,为什么逻辑回归要是分类方法却叫回归呢?我认为主要原因是因为逻辑回归首先建立了一个线性回归模型,然后又用的sigmoid函数将其转化成了二分类问题。对于分类问题,我的理解是损失函数一般为交叉熵,交叉熵的形式是

                                                                                  -y_{i}log(p_{i})

       其中yi是实际值,pi为预测值的概率,一般在逻辑回归中我们设定的阈值为0.5,如果给定一条数据(x1,x2..xn,y),其中y=1。在用模型预测时,我们预测其为1那一类的概率为0.8,预测其为0那一类的概率为0.2,所以该数据应该划分到1那一类。虽然我们将该值划分到1那一类中了,但是我们预测概率为0.8,而实际上我们已经知道这类数据为1那一类,概率应该是100%,所以这里就有了一个概率上的损失,1-0.8=0.2。因此我们求解的模型应该是概率损失最小的,则可以进一步转化为熵最小,即不确定性最低,因此我们可以用上面的公式作为损失函数。

       这里有听起来有点晕,举个简单的例子,如果我们现在有两个模型A和B,已知一条数据m=(x1,x2,x3,...,xn,y),其中y=1(y为类别划分,包括1和0两个,这里m为1那一类),但是模型A预测m为1的概率为0.8,模型B预测m为1的概率为0.9,虽然两个模型同时把m划分到了1那一类中,但从概率上看,我们会选择模型B,因为其概率损失小。

上面是我对分类问题损失函数的简单理解,望补充。

       交叉熵是怎么回事呢?首先得说到熵这个东西,熵是混乱度、不确定性的代表,如果事件N发生的概率为p,那么N的熵为

                                                                                    Q(N)=-plog(p)

p越大,Q越小,可以理解为事件N发生的概率越大,其不确定性越小。

       已经知道在逻辑斯蒂回归中,损失函数为对数损失。这里要用到极大似然估计

                                                                 P\left (Y=1|x_{i} \right )=\pi (x) ,P\left (Y=0|x_{i} \right )=1-\pi (x)

                                                                    G=\prod \pi \left ( x \right )^{y_{i}}(1-\pi(x))^{1-y_{i}}

其中\pi (x)为sigmoid函数,我们的目的是求使得G最大时的模型参数。因为连乘不太容易求,所以对公式两边取对数转化为连加,得到如下公式

                                                L(w)=-\sum \left( y_{i}log\pi(x)+\left ( 1-y_{i} \right )log(1-\pi(x))\right)

可以发现这里和上面的交叉熵很像了,其中L(w)>0。此时我们将该公式作为逻辑回归的损失函数,该函数是一个凸函数,要求其最小值可以直接采用求导的方式。

 

2、梯度下降法


     梯度下降法是一种模型参数的求解方法,假如我们有一堆数据,然后这组数据可以拟合成一个方程,比如线性方程y=w_{0}+w_{1}x,那么要求方程中的参数w_{0},w_{1},则可以采用梯度下降法。       

     接下来举个简单的例子。由于我没有训练数据,所以在这里我首先写了一段生成一堆数据的代码,然后依据这组数去训练一个模型。如果你有训练数据,当然就不用这样生成了。

import numpy as np
import matplotlib.pyplot as plt

x=4* np.random.rand(100,1)        #生成100行1列的随机数,随机数的范围[0,1)
y=5+6*x+np.random.randn(100,1)    #生成100行1列的随机数,随机数范围[0,1),随机数符合正太分布
                                  #这里是给y=5+6x这个直线加了一些随机数,然后生成的一堆数据,作为我们的训练集,如果效果拟合的好,那么结果就应该接近这条直线
x_b=np.c_[np.ones((100)),x]

data=np.c_[y,x]                    #训练数据,要把根据这些数据,拟合出一个y=w0+w1x

##将数据以图的形式展示
plt.figure(figsize=(10,5))#设置画布的尺寸
plt.xlabel(u'y',fontsize=14)#设置x轴,并设定字号大小
plt.ylabel(u'x',fontsize=14)#设置y轴,并设定字号大小
plt.scatter(data[:,1],data[:,0], s=70,c='',edgecolors='black', alpha=1,marker='o')
plt.show()

下图是上面代码生成的一组数据,可以发现这组数比较接近一条直线,接下来我们将用这组数去拟合一条直线,方法当然是采用梯度下降法。

下面列出梯度下降法的代码

#用梯度下降法进行求解

l_rate=0.1   ##学习率
cnt=500      ##迭代次数
m=100        ##这是上面生成的数据的数量,上面生成了100组数据,因为下面要迭代过程中要取均值


def train(t):
    return t0/(t+t1)
theta =np.random.randn(2,1) #初始化w0,w1

for dai in range(cnt):
    gradients=1/m*x_b.T.dot(x_b.dot(theta)-y)  #这是采用对数损失函数推出来的,下面我们将做一些解释
    theta=theta-l_rate*gradients          #沿着梯度方向对参数进行迭代更新

print('w0=',theta[0][0],'w1=',theta[1][0])  #打印参数

gradients=1/m*x_b.T.dot(x_b.dot(theta)-y)是怎么得到的呢?

这句代码可以解释为gradients=\frac{1}{m} X^{T}(\Theta X-Y),这个公式看起来云里雾里,我们说一下推导的过程

已经知道最小二乘法的公式为

                                                      J(\Theta )=\sum \frac{1}{2}(\widehat{y_{i}}-y_{i})^{2}

其中\widehat{y_{i}}为预测值,上面公式可以转换为

                                                      J(\Theta )=\sum \frac{1}{2}(\Theta x^{(i)} -y^{(i)})^{2}

\Theta x^{(1)}=\Theta _{0}x^{(1)}_{0}+\Theta _{1}x^{(1)}_{1}+\Theta _{2}x^{(1)}_{2}+...,此外我们还可以发现J(\Theta )是一个二次方程,所以该函数是一个凸函数。

这时候,我们的目的是求使得J(\Theta )最小的\Theta,所以对用J(\Theta )\Theta求导数,并令导数为0。

(这里需要注意的是上面说了\Theta x^{(1)}=\Theta _{0}x^{(1)}_{0}+\Theta _{1}x^{(1)}_{1}+\Theta _{2}x^{(1)}_{2}+...,所以\Theta是一个向量,所以应该理解的内涵是我们对\Theta求导,其实是对\Theta _{0},\Theta _{1} ,\Theta _{2}...逐个求偏导数,当然我们在公式推导时,可以忽略)

我们继续对上面的公式进行转换得到

                                                    J(\Theta ) =\frac{1}{2}(\Theta X -Y)^{T}(\Theta X -Y)

如此\frac{\partial J(\Theta )}{\partial \Theta }=\frac{1}{2}X^{T}(\Theta X -Y)+\frac{1}{2}(\Theta X -Y)^{T}X\rightarrow \frac{\partial J(\Theta )}{\partial \Theta }=X^{T}(\Theta X -Y),这就是梯度下降法里的核心函数的来源。加上\frac{1}{m}是为了去除样本数量多少对函数造成的影响。

上面解释了梯度下降法的核心函数的由来,下面我们接着说代码运算得到的结果,我们上面预测的结果是w0=5,w1=6,结果有偏差,和我设置的迭代次数有关,如果多迭代几次可能就更接近了

下面我们再画一张图,来展示我们求出来的结果所代表的直线,画图的代码如下

#汇出直线图
y_=np.array([[1,0],[1,4]]).dot(theta)       #这里是选择x=0和x=4的两个点取画直线的
plt.figure(figsize=(10,5))#设置画布的尺寸
plt.xlabel(u'x',fontsize=14)#设置x轴,并设定字号大小
plt.ylabel(u'y',fontsize=14)#设置y轴,并设定字号大小
plt.scatter(data[:,1],data[:,0], s=70,c='',edgecolors='black', alpha=1,marker='o')
plt.plot([0,4],y_)
plt.show()

画出的图如下,其中蓝色的线就是我们拟合得到的结果

把上面的所有代码复制下来放在一起可以直接运行~~~

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值