天天看点

机器学习实战——梯度下降求解逻辑回归(1理论基础)

概念问题

  • 逻辑回归是回归还是分类?

    逻辑回归是分类,不要被名字所欺骗。因本篇文章仅讨论二分类问题,故我们将逻辑回归最终得到的预测值看作两个,即是或否(0或1)。

从线性回归开始

为什么从线性回归开始呢?因为二分类问题解的得出与线性回归有很大关系,逻辑回归之所以叫回归因为其与线性回归有着千丝万缕的关系。

有这样一个例子:

我们用numpy包生成一百个随机的x值,并且设定y值与x有一定的线性关系,最后把这样的线性关系绘制出来:

import tensorflow as tf
import numpy as np

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
%matplotlib inline

# 使用numpy生成100个随机点   样本

x_data = np.random.rand(100)

y_data = x_data * 0.1 + 0.2

fig, ax = plt.subplots()

ax.scatter(x_data, y_data)

ax.set_xlabel('x')

ax.set_ylabel('y')

plt.show()
           

绘制出来的图是这样的:

机器学习实战——梯度下降求解逻辑回归(1理论基础)

之后我们用tensorflow(一个深度学习框架)的内置api直接构造一个线性回归的模型,进行预测,设置迭代次数为201次,每当20的倍数时便将学习结果输出、绘制出来,会发现我们最终得到的图与原图相似(即斜率基本一致,偏置值基本一致)。

# 构造一个线性模型
b = tf.Variable(1.1)
k = tf.Variable(0.5)
y = k * x_data + b

# 二次代价函数
loss = tf.reduce_mean( tf.square(y_data - y) )

# 定义一个梯度下降法来进行训练的优化器
optimizer = tf.train.GradientDescentOptimizer(0.2) # 梯度下降 学习率是0.2

# 定义一个最小化代价函数
train = optimizer.minimize(loss)
# 初始化变量
init = tf.global_variables_initializer()
with tf.Session() as sess:    
    sess.run(init)    
    for step in range(201):      
        sess.run(train)             
        if step % 20 == 0:           
            data1 = np.random.rand(100)
            data2 = data1 * sess.run(k) + sess.run(b)
            fig, ax = plt.subplots()
            ax.scatter(data1,data2)
            ax.set_xlabel('x')
            ax.set_ylabel('y')
            plt.show()                      
            print(step, sess.run([k, b]))
            
           

关于线性回归更具体的内容(如损失函数等)在另一篇博客里。

最终的图如下:

机器学习实战——梯度下降求解逻辑回归(1理论基础)

且斜率值和偏置值分别问:[0.099538416, 0.20024595]。与初始的基本一致。

(代码看不懂或不了解 tensorflow 没关系,只要明白线性回归就好了)

线性回归的目标便是求得一条曲线,能最大程度拟合我们的数据点(X1、X2轴),而曲线的Y值便是我们的预测值。其实就是个立体的曲线,图例如下:

机器学习实战——梯度下降求解逻辑回归(1理论基础)

即线性回归得出的是连续的结果,如果我们仅仅需要得到离散的结果,即是或否,由此便引出了二分类问题,也就是本文要讨论的逻辑回归方法。

问题的提出

现要实现一个简单的逻辑回归:

我们将建立一个逻辑回归模型来预测一个学生是否被大学录取。假设你是一个大学系的管理员,你想根据两次考试的结果来决定每个申请人的录取机会。你有以前的申请人的历史数据,你可以用它作为逻辑回归的训练集。对于每一个培训例子,你有两个考试的申请人的分数和录取决定。为了做到这一点,我们将建立一个分类模型,根据考试成绩估计入学概率。

即要求我们通过一些数据集来训练电脑,能实现输入两门考试成绩从而得到是否录取的结果。

设X1为exam1的成绩,X2为exam2的成绩,X1、X2就是我们的两个特征。

载入数据集

我们首先载入数据集看看数据特征与数据项:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

import os
path = 'data' + os.sep + 'LogiReg_data.txt'
pdDate = pd.read_csv(path, header=None, names=['Exam1', 'Exam2', 'Admitted'])
pdDate.head()
           

结果如图:

机器学习实战——梯度下降求解逻辑回归(1理论基础)

可以看到学生有两门成绩,学校是通过两门成绩来决定是否录取。

之后我们可以利用python的绘图包通过散点图的绘制来将数据更直接的表现出来。

positive = pdDate[pdDate['Admitted'] == 1]
negative = pdDate[pdDate['Admitted'] == 0]

fig, ax = plt.subplots(figsize=(10, 6))
ax.scatter(positive['Exam1'], positive['Exam2'], s=30, c='b', marker='o', label='Admitted')
ax.scatter(negative['Exam1'], negative['Exam2'], s=30, c='r', marker='x', label='Not Admitted')

ax.legend()
ax.set_xlabel('Exam 1')
ax.set_ylabel('Exam 2')
           

结果如图:

机器学习实战——梯度下降求解逻辑回归(1理论基础)

初步求解

我们求解的线性关系一定是有参数的,因为我们有两个特征值,而我们需要通过两个特征值求得预测值,但是两个特征值对结果的影响又不尽相同,所以我们需要两个参数来度量两个特征值对结果影响程度,以及一个参数来充当偏置项(曲线会上下浮动,且偏置项对结果作用较小):

θ 1 、 θ 2 、 θ 0 \theta_1、\theta_2、\theta_0 θ1​、θ2​、θ0​

所以我们的预测结果可以表示为:

h θ ( x ) = ( θ 0 θ 1 θ 2 ) × ( 1 x 1 x 2 ) = θ 0 + θ 1 x 1 + θ 2 x 2 h_{\theta}(x)=\begin{array}{ccc} \begin{pmatrix}\theta_{0} & \theta_{1} & \theta_{2}\end{pmatrix} & \times & \begin{pmatrix}1\\ x_{1}\\ x_{2} \end{pmatrix}\end{array}=\theta_{0}+\theta_{1}x_{1}+\theta_{2}x_{2} hθ​(x)=(θ0​​θ1​​θ2​​)​×​⎝⎛​1x1​x2​​⎠⎞​​=θ0​+θ1​x1​+θ2​x2​

整合之后:

h θ ( x ) = ∑ i = 0 n ( θ i x i ) = θ T x h_{\theta}(x)=\sum_{i=0}^n (\theta_i x_i)=\theta^Tx hθ​(x)=i=0∑n​(θi​xi​)=θTx

这便是我们构造的预测结果值,但是仅仅有结果值还是不够的,我们需要将预测结果值转化为录取的概率,我们规定:当概率大于0.5则Y可以取1表示录用,小于0.5不录用Y取0,所以我们又需要一个函数来转化预测值为概率,称为sigmoid函数,定义如下:

g ( z ) = 1 1 + e − z g(z) = \frac{1}{1+e^{-z}} g(z)=1+e−z1​

我们可以先将sigmoid函数画出来瞧瞧,为什么要用它,代码如下:

def sigmoid(x):
    z = 1/(1 + np.exp(-x))
    return z

nums = np.linspace(-10, 10, 50)
fig, ax = plt.subplots(figsize=(12,4))
ax.plot(nums, sigmoid(nums), 'b')
           

结果如图:

机器学习实战——梯度下降求解逻辑回归(1理论基础)

可以看到该函数符合我们的需求,其取值位于0到1,定义域为实数集R,可以将我们的预测结果转化为概率!

而所谓的逻辑回归便是将任意的输入值映射到[0,1]区间上,将我们通过线性回归得到的预测值转化为概率,完成分类任务。

初步求解

我们载入数据,大体明白了预测结果长什么样,以及值概率的转化,但我们的模型还完全没有建立起来!

我们知道所谓机器学习便是我们交给机器一堆数据,然后告诉它什么样的学习方式是对的(目标函数),叫它朝着这个方向走,然后还要规定每次走的步长(学习率),一口吃不了大胖子,要一步一步来(每次的迭代)。

机器学习实战——梯度下降求解逻辑回归(1理论基础)

如同这样一个山谷,我们要达到山谷的最低点,利用梯度下降的方法,每经过一个数据点,便运行更新函数更新下一步的方向(梯度,求偏导)。

所以我们还要做损失函数(目标函数)、更新函数。

何为损失函数?

我们通过X来估计Y的值,预测值可能符合真实值,也可能不符合真实值,所以我们引入损失函数来度量拟合的程度,损失函数越小代表拟合的越好。

在此处我们暂时将损失函数视为目标函数。

关于梯度下降

梯度下降便是在凸函数中沿着梯度下降的方向不断更新参数,一般情况下我们通过加负号实现。

梯度下降有三种方式实现:

  • 1 批量梯度下降法(Batch Gradient Descent)

    批量梯度下降法,是梯度下降法最常用的形式,具体做法也就是在更新参数时使用所有的样本来进行更新:

    机器学习实战——梯度下降求解逻辑回归(1理论基础)
    由于我们有m个样本,这里求梯度的时候就用了所有m个样本的梯度数据。
  • 2 随机梯度下降法(Stochastic Gradient Descent)

    随机梯度下降法,其实和批量梯度下降法原理类似,区别在与求梯度时没有用所有的m个样本的数据,而是仅仅选取一个样本j来求梯度。对应的更新公式是:

    机器学习实战——梯度下降求解逻辑回归(1理论基础)

    随机梯度下降法,和批量梯度下降法是两个极端,一个采用所有数据来梯度下降,一个用一个样本来梯度下降。自然各自的优缺点都非常突出。对于训练速度来说,随机梯度下降法由于每次仅仅采用一个样本来迭代,训练速度很快,而批量梯度下降法在样本量很大的时候,训练速度不能让人满意。对于准确度来说,随机梯度下降法用于仅仅用一个样本决定梯度方向,导致解很有可能不是最优。对于收敛速度来说,由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快的收敛到局部最优解。

    那么,有没有一个中庸的办法能够结合两种方法的优点呢?有!这就是小批量梯度下降法。

  • 3 小批量梯度下降法(Mini-batch Gradient Descent)

    小批量梯度下降法是批量梯度下降法和随机梯度下降法的折衷,也就是对于m个样本,我们采用x个样子来迭代。一般可以取x=10,当然根据样本的数据,可以调整这个x的值。对应的更新公式是:

    机器学习实战——梯度下降求解逻辑回归(1理论基础)

##逻辑回归

预测函数(完成值到概率的转化):

h θ ( x ) = g ( θ T x ) = 1 1 + e − θ T x . ( 其 中 θ T x 是 我 们 前 面 表 示 的 预 测 值 ) h_{\theta}(x)=g(\theta^Tx)=\frac{1}{1+e^{-\theta^Tx}}.(其中\theta^Tx是我们前面表示的预测值) hθ​(x)=g(θTx)=1+e−θTx1​.(其中θTx是我们前面表示的预测值)

将分类任务整合进去:

P ( y ∣ x ; θ ) = ( h θ ( x ) ) y ( 1 − h θ ( x ) ) 1 − y P(y|x;\theta)=(h_\theta(x))^y(1-h_{\theta}(x))^{1-y} P(y∣x;θ)=(hθ​(x))y(1−hθ​(x))1−y

即当我们的y取值为0或1时,可以得到较为精简的式子。

有了概率,我们便可以求似然函数了。

何为似然函数?

官方解释如下:

机器学习实战——梯度下降求解逻辑回归(1理论基础)

常说的概率是指给定参数后,预测即将发生的事件的可能性。而似然概率正好与这个过程相反,我们关注的量不再是事件的发生概率,而是已知发生了某些事件,我们希望知道参数应该是多少。

我们的似然函数定义如下:

L ( θ ) = ∏ i = 1 m P ( y i ∣ x i ; θ ) = ∏ i = 1 m ( h θ ( x i ) ) y i ( 1 − h θ ( x i ) ) 1 − y i L(\theta)=\prod_{i=1}^{m}P(y_i|x_i;\theta)=\prod_{i=1}^{m}(h_\theta(x_i))^{y_{i}}(1-h_{\theta}(x_i))^{1-y_i} L(θ)=i=1∏m​P(yi​∣xi​;θ)=i=1∏m​(hθ​(xi​))yi​(1−hθ​(xi​))1−yi​

即表示我们预测的参数满足所有样本值这一事件的概率,接下来要做的就是极大似然估计,即令参数的取值无限拟合我们的真实数据。

我们取对数似然,此时应用梯度上升求最大值,再引入目标函数转换为梯度下降求最小值(加负号,除以样本总数,考虑整体样本),求偏导,令其等于零。目标函数如下:

J ( θ ) = − 1 m L ( θ ) J(\theta)=-\frac{1}{m}L(\theta) J(θ)=−m1​L(θ)

求偏导过程不再给出,结果如下:

δ δ θ j J ( θ ) = 1 m ∑ i = 1 m ( h θ ( x i ) − y i ) x i j \frac{\delta}{\delta_{\theta_j}}J(\theta)=\frac{1}{m}\sum_{i=1}^m(h_\theta(x_i)-y_i)x_i^j δθj​​δ​J(θ)=m1​i=1∑m​(hθ​(xi​)−yi​)xij​

##代码编写

具体代码将再下一篇中详述

继续阅读