PRELOADER

当前文章 : 《机器学习实战——梯度下降求解逻辑回归(理论基础)》

5/10/2019 —— 

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

逻辑回归是回归还是分类?
逻辑回归是分类,不要被名字所欺骗。因本篇文章仅讨论二分类问题,故我们将逻辑回归最终得到的预测值看作两个,即是或否(0或1)。
从线性回归开始
为什么从线性回归开始呢?因为二分类问题解的得出与线性回归有很大关系,逻辑回归之所以叫回归因为其与线性回归有着千丝万缕的关系。
有这样一个例子:
我们用numpy包生成一百个随机的x值,并且设定y值与x有一定的线性关系,最后把这样的线性关系绘制出来:

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()

绘制出来的图是这样的:

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

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

问题的提出

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

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

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

设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"
pdData = pd.read_csv(path, header=None, names=['Exam 1', 'Exam 2', 'Admitted'])
pdData.head()

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

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

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

fig, ax = plt.subplots(figsize=(10,5))
ax.scatter(positive['Exam 1'], positive['Exam 2'], s=30, c='b', marker='o', label='Admitted')
ax.scatter(negative['Exam 1'], negative['Exam 2'], s=30, c='r', marker='x', label='Not Admitted')
ax.legend()
ax.set_xlabel('Exam 1 Score')
ax.set_ylabel('Exam 2 Score')

初步求解

我们求解的线性关系一定是有参数的,因为我们有两个特征值,而我们需要通过两个特征值求得预测值,但是两个特征值对结果的影响又不尽相同,

所以我们需要两个参数来度量两个特征值对结果影响程度,以及一个参数来充当偏置项(曲线会上下浮动,且偏置项对结果作用较小):

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

整合之后:

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

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

nums = np.arange(-10, 10 ,step=1)
fig, ax = plt.subplots(figsize=(12,4))
ax.plot(nums, sigmoid(nums), 'r')

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

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

初步求解

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

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

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

何为损失函数?

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

关于梯度下降

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

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

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

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

2 随机梯度下降法(Stochastic Gradient Descent)

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

随机梯度下降法,和批量梯度下降法是两个极端,一个采用所有数据来梯度下降,一个用一个样本来梯度下降。自然各自的优缺点都非常突出。

对于训练速度来说,随机梯度下降法由于每次仅仅采用一个样本来迭代,训练速度很快,而批量梯度下降法在样本量很大的时候,

训练速度不能让人满意。对于准确度来说,随机梯度下降法用于仅仅用一个样本决定梯度方向,导致解很有可能不是最优。对于收敛速度来说,

由于随机梯度下降法一次迭代一个样本,导致迭代方向变化很大,不能很快的收敛到局部最优解。那么,有没有一个中庸的办法能够结合两种方法的优点呢?有!这就是小批量梯度下降法。

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

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

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

似然函数

常说的概率是指给定参数后,预测即将发生的事件的可能性。而似然概率正好与这个过程相反,我们关注的量不再是事件的发生概率,

而是已知发生了某些事件,我们希望知道参数应该是多少。我们的似然函数定义如下:

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

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

求偏导的过程: