您的位置:首页 > 编程语言 > Python开发

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

2018-02-17 17:33 1421 查看

问题的提出

现要实现一个简单的线性回归:

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

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

设X1为exam1的成绩,X2为exam2的成绩,X1、X2就是我们的两个特征,我们的目标便是求得一条曲线,能最大程度拟合我们的数据点(X1、X2轴),而曲线的Y值便是我们的预测值。其实就是个立体的曲线,图例如下:



载入数据集

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

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


结果如图:



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

之后我们可以利用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')


结果如图:



初步求解

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

θ1、θ2、θ0θ1、θ2、θ0

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

hθ(x)=(θ0θ1θ2)×⎛⎝⎜1x1x2⎞⎠⎟=θ0+θ1x1+θ2x2hθ(x)=(θ0θ1θ2)×(1x1x2)=θ0+θ1x1+θ2x2

整合之后:

hθ(x)=∑i=0n(θixi)=θTxhθ(x)=∑i=0n(θixi)=θTx

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

g(z)=11+e−zg(z)=11+e−z

我们可以先将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')


结果如图:



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

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

初步求解

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

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



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

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

何为损失函数?

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

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

关于梯度下降

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

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

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

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



由于我们有m个样本,这里求梯度的时候就用了所有m个样本的梯度数据。

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

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



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

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

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

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



逻辑回归

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

hθ(x)=g(θTx)=11+e−θTx.(其中θTx是我们前面表示的预测值)hθ(x)=g(θTx)=11+e−θTx.(其中θTx是我们前面表示的预测值)

将分类任务整合进去:

P(y|x;θ)=(hθ(x))y(1−hθ(x))1−yP(y|x;θ)=(hθ(x))y(1−hθ(x))1−y

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

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

何为似然函数?

官方解释如下:



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

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

L(θ)=∏i=1mP(yi|xi;θ)=∏i=1m(hθ(xi))yi(1−hθ(xi))1−yiL(θ)=∏i=1mP(yi|xi;θ)=∏i=1m(hθ(xi))yi(1−hθ(xi))1−yi

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

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

J(θ)=−1mL(θ)J(θ)=−1mL(θ)

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

δδθjJ(θ)=1m∑i=1m(hθ(xi)−yi)xjiδδθjJ(θ)=1m∑i=1m(hθ(xi)−yi)xij

代码编写

具体代码将再下一篇中详述
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息