Logistic0U 3
本章内容
□ 8丨§ 0 « ^ 函数和1 ^ 丨8此回归分类器
□ 最优化理论初步
□ 梯度下降最优化算法
口数据中的缺失项处理
这会是激动人心的一章,因为我们将首次接触到最优化算法。仔细想想就会发现,其实我们
日常生活中遇到过很多最优化问题,比如如何在最短时间内从入点到达氏点?如何投人最少工作
量却获得最大的效益?如何设计发动机使得油耗最少而功率最大?可 风 ,最优化的作用十分强
大 。接 下 来 ,我们介绍几个最优化算法,并利用它们训练出一个非线性函数用于分类。
读者不熟悉回归也没关系,第8章起会深入介绍这一主题。假设现在有一些数据点,我们用
一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称作回归。利用1 (^ 8 加
回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的
“ 回归” 一词源于最佳拟合,表示要找到最佳拟合参数集,其背后的数学分析将在下一部分介绍。
训练分类器时的做法就是寻找最佳拟合参数,使用的是最优化算法。接下来介绍这个二值型输出
分类器的数学原理。
丨
109丨3丨丨£:回归的一般过程
1
(1)收集数据:采用任意方法收集数据。
(2)准备数据:由于需要进行距离计算,因此要求数据类型为数值型。另外,结构化数据
格式则最佳。
(3)分析数据:采用任意方法对数据进行分析。
(4)训练算法:大部分时间将用于训练,训练的目的是为了找到最佳的分类回归系数。
(5)测试算法:一旦训练步驟完成,分类将会很快。
(6)使用算法:首先,我们需要输入一些数据,并将其转换成对应的结构化数值;
接着,基于训练好的回归系数就可以对这些数值进行简单的回归计算,判定它们属于
哪个类别.,在这之后,我 们 就 可 以 夺 输 出 的 类 别 上 做 一 些 其 他 分 析 工 作 。
74
第 5 章 Logistic回归
本章首先阐述1 0咖 1化回归的定义,然后介绍一些最优化算法,其中包括基本的梯度上升法
和一个改进的随机梯度上升法,这些最优化算法将用于分类器的训练。本章最后会给出一个
108丨81丨(:回归的实例,预测一匹病马是否能被治愈。
5 . 1 基 于 Logistic回 归和Sigmoid函数的分类
Logistic^E
优点:计算代价不高,易于理解和实现。
缺点:容易欠拟合,分类精度可能不高。
适用数据类型:数值型和标称型数据。
.
我们想要的函数应该是,能接受所有的输人然后预测出类别。例如 ,在两个类的情况下,上
述函数输出 0或 1。或许你之前接触过具有这种性质的函数,该 函 数 称 为 海 维 塞 德 阶 跃 函 数
(Heaviside step function) , 或者直接称为单位阶跃函数。然而,海维塞德阶跃函数的问题在于:
该函数在跳跃点上从0瞬间跳跃到1,这个瞬间跳跃过程有时很难处理。幸好,另一个函数也有类
似的性质® ,且数学上更易处理,这就是8丨8^ 0丨£1函数®。8丨80 « ^ 函数具体的计算公式如下:
图5-1给出了8;§10;4函数在不同坐标尺度下的两条曲线图。当%为0日牝Sigmoid函数值为0.5。
随着1的增大,对应的8;80 « ^ 值将逼近于1; 而随着^的减小,Sigmoid值将逼近于0。如果横坐标
刻 度 足 够 大 (图5-1下 图 ),8丨80 « ^ 函数看起来很像一个阶跃函数。
因此,为了实现匕明如化回归分类器,我们可以在每个特征上都乘以一个回归系数,然后把
所有的结果值相加,将这个总和代人8丨81110丨£1函数中,进而得到一个范围在0〜1之间的数值。任
.何大于0.5的数据被分人1类 ,小于0.5即被归人0类 。所 以 ,[0扭廿0回归也可以被看成是一种概
率估计。
确定了分类器的函数形式之后,现在的问题变成了:最佳回归系数^是多少? 如何确定它们
的大小?这些问题将在下一节解答。
© 这 里 指 的 是 可 以 输 出 0或 者 1的 这 种 性 质 。一 译 者 注
② 幻 81^ ^ 函 数 是 一 种 阶 跃 函 数 (他 ?&1«^<«0。在 数 学 中 ,如 果 实 数 域 上 的 某 个 函 数 可 以 用 半 开 区 间 上 的 指 示 函 数
的 有 限 次 线 性 组 合 来 表 示 ,那 么 这 个 函 数 就 是 阶 跃 函 数 。而 数 学 中 指 示 函 数 (丨以^ 3 ^ ^ 1 1 « 如以0 是 定 义 在 某 集 合
乂 上 的 函 数 ,表 示 其 中 有 哪 些 元 素 属 于 某 一 子 集 入 。—— 译 者 注
@ 将这里的聊丨8扮 翻 译 为 “ 回 归 系 数 ” ,_是 为 了 与 后 面 的 局 部 加 权 线 性 回 归 中 的 “权 重 ” 一 词 区 分 开 来 ,在不会引
起 混 淆 的 时 候 也 会 简 称 为 “系 数 ”。一 译 者 注
5 . 2 基于 最优 化方 法的 最佳 回 归系 数 确定
75
x)p
oE
.?
s
{
x
)
p
o
u
l
6
!
s
0.0 ---------- 1---------- L ■_^ I---------- 1---------- 1----------
-60
-40
-20
0
x
20
40
60
图5 - 1 两种坐标尺度下的3丨80«3丨(1函数图。上图的横坐标为-5 到5,这时的曲线变化较
为平滑;下图横坐标的尺度足够大,可以看到,在\ = 0点处3丨80^丨(1函数看起来
很像阶跃函数
5 . 2 基于最优化方法的最佳回归系数确定
邮 1 ^ ^ 函数的输人记为2 ,由下面公式得出:
z = w0x0 + w,x, + w2x2 + • • • + w,,x"
如果采用向量的写法,上述公式可以写成2 = WTX , 它表示将这两个数值向量对应元素相乘然后
全部加起来即得到2值 。其中的向量尤是分类器的输人数据,向量一就是我们要找到的最佳参数
( 系 数 ) , 从而使得分类器尽可能地精确。为了寻找该最佳参数,需要用到最优化理论的一些知识。
下 面 首 先 介 绍 梯 度 上 升 的 最 优 化 方 法 ,我们将学习到如何使用该方法求得数据集的最佳
参 数 。接 下 来 ,展 示 如 何 绘制梯度上升 法产生的 决 策边界图 ,该图能将梯度上升法的分类效
果 可 视 化 地 呈 现 出 来 。最后我们将学习 随 机 梯度 上 升 算法 ,以及如何对其进彳〒修改以获得更
好 的 结 果 。
5 . 2 . 1 梯度上升法
我们介绍的第一个最优化算法叫做梯度上升法。梯度上升法基于的思想是:要找到某函数的
最 大 值 ,最好的方法是沿着该函数的梯度方向探寻。如果梯度记为^ , 则函数£ 仏,¥)的梯度由
下式表示:
76
第 5 章 Logistic回归
^ f ( ^ y Y
▽ 瓜 七 df(x,y)
、 办 >
这是机器学习中最易造成混淆的一个地方,但在数学上并不难,需要做的只是牢记这些符号
的意义。这个梯度意味着要沿础方向移动^
dy
必须要在待计算的点上有定义并且可微。一个具体的函数例子见图5-2。
^ ,沿^的方向移动^ ! ^ 。其中,函 数 ^,妁
dx
梯度上升
图5 - 2 梯度上升算法到达每个点后都会重新估计移动的方向。从?0开始,计算完该点
的梯度,函数就根据梯度移动到下一点?1。在?1点,梯度再次被重新计算,并
沿新的梯度方向移动到?2。如此循环迭代,直到满足停止条件。迭代的过程中,
梯度算子总是保证我们能选取到最佳的移动方向
图5-2中的梯度上升算法沿梯度方向移动了一步。可 以看到,梯度算子总是指向函数值增长
最快的方向。这里所说的是移动方向,而未提到移动量的大小。该量值称为步长,记 做 《。用向
量来表示的话,梯度算法的迭代公式如下:
w:= w + o V 1(,/(w)
该公式将一直被迭代执行,直至达到某个停止条件为止,比如迭代次数达到某个指定值或算
法达到某个可以允许的误差范围。
5 . 2 基 于最 优化方 法的 最佳 回归系 数确 定
77
■' ; v : -
^
■梯度卞降算法' : >
' - ' . ' - ' *'
'
你最经常听到的应该是梯度下降算法,它与这里的梯度上升算法是一样的,只是公式中的
加法需要变成减法。因此,对应的公式可以写成
w:= w+oNwf{w)
梯度上升算法用来求函数的最大值,而梯度下降算法用来求函数的最小值。
基于上面的内容,我们来看一个匕0由3也回归分类器的应用例子,从图5-3可以看到我们采用
的数据集。
图5-3 — 个简单数据集,下面将采用梯度上升法找到10# 8加回归分类器在此数据集
上的最佳回归系数
5 . 2 . 2 训 练 算 法 :使用梯度上升找到最佳参数
图5-3中有100个样本点,每个点包含两个数值型特征:X _ X 2 。在此数据集上,我们将通
过使用梯度上升法找到最佳回归系数,也就是拟合出1 0由8此回归模型的最佳参数。
梯度上升法的伪代码如下:
每个回归系数初始彳匕为1
重复尺次:
计算整个数据集的梯度
使用alpha x 识8出6也更新回归系数的向量
返回回归系数
78
第 5 章 Logistic回归
下面的代码是梯度上升算法的具体实现。为了解实际效果,打开文本编辑器并创建一个名为
1 ( ^ ^ 慨 仍 的 文 件 ,输人下列代码:
程序清单5-1 LogistiC 回归梯度上升优化算法
d e f l o a d D a t a S e t ( ) :
d a t a M a t = [] ; l a b e l M a t = [ ]
f r = o p e n ( 1t e s t S e t .t x t ')
f o r l i n e in f r . r e a d l i n e s () :
l i n e A r r = l i n e .s t r i p ().s p l i t ()
d a t a M a t . a p p e n d ( [ 1 . 0 , f l o a t ( l i n e A r r [0]), f l o a t ( l i n e A r r [1])])
l a b e l M a t .a p p e n d ( i n t ( l i n e A r r [2]))
r e t u r n d a t a M a t , l a b e l M a t
d e f s i g m o i d ( i n X) :
r e t u r n 1 . 0 / ( l + e x p ( - i n X ) )
d e f g r a d A s c e n t { d a t a M a t I n , c l a s s L a b e l s ) :
d a t a M a t r i x = mat^(dataMatIn)
l a b e l M a t = m a t ( a l a s s L a b e l s ) . t r a n s p o s e { )
m , n = s h a p e {dataMatrix)
a l p h a = 0 . 0 0 1
m a x C y c l e s = 500
w e i g h t s = o n e s ( ( n , l ) )
f o r k in r a n g e { m a x C y c l e s ) :
数 据 类 型
h = s i g m o i d ( d a t a M a t r i x * w e i g h t s )
e r r o r = ( l a b e l M a t - h)
w e i g h t s = w e i g h t s + a l p h a * d a t a M a t r i x .transpose()* e r r o r
r e t u r n w e i g h t s
程序清单5-1的代码在开头提供了一个便利函数10£^ 机 沾 的 (〉,它的主要功能是打开文本
文件(^社 3社 .匕乂七并逐行读取。每行前两个值分别是乂1和乂2 ,第三个值是数据对应的类别标签。
此外,为了方便计算,该函数还将乂0的值设为1.0。接下来的函数是5.2节提到的函数31聊 0 1(1(>。
梯度上升算法的实际工作是在函数gradASCenU ) 里完成的,该函数有两个参数。第一个参
数是(^ 七碰3比 1 1 它是一个2维 他 ^ ^ 数 组 ,每列分别代表每个不同的特征,每行则代表每个
训练样本。我们现在采用的是100个样本的简单数据集,它包含了两个特征乂1和 沿 ,再加上第0
维特征乂0 ,所以办七视3比匕里存放的将是100><3的矩阵。在0 处 ,我们获得输人数据并将它们
转换成^^1«^^矩阵。这是本书首次使用N u m P y矩 阵,如果你对矩阵数学不太熟悉,那么一些运算
可能就会不易理解。比如,& ! 1 ^ 对2维数组和矩阵都提供一些操作支持,如果混淆了数据类型
和对应的操作,执行结果将与预期截然不同。对此,本书附录八给出了对灿《1^^矩阵的介绍。第
二个参数是类别标签,它是一个1><100的行向量。为了便于矩阵运算,需要将该行向量转换为列
向量,做法是将原向量转置,再将它赋值给13匕01风3 % 接下来的代码是得到矩阵大小,再设置
一些梯度上升算法所需的参数。
变量31 ! ^ 是向目标移动的步长,:1 ^ 0 ^ 1 郎是迭代次数。在 比 -循环迭代完成后,将返回
训练好的回归系数。需要强调的是,在© 处的运算是矩阵运算。变量匕不是一个数而是一个列向
量 ,列向量的兀素个数等于样本个数,这里是100。对应地,运算63七3风3七1 ^ * w e i g h t s R S
的不止一次乘积计算,事实上该运算包含了300次的乘积。
5 . 2 基于 最优 化 方法 的最 佳 回归 系 数确 定
79
最后还需说明一点,你可能对0 ¥ 公式的前两行觉得陌生。此处略去了一个简单的数学推导,
我把它留给有兴趣的读者。定性地说,这里是在计算真实类别与预测类别的差值,接下来就是按
照该差值的方向调整回归系数。
接下来看看实际效果,打开文本编辑器,添加程序清单5-1的代码。
在?丫《« ^ 提示符下,敲人下面的代码:
>>> i m p o r t l o g R e g r e s
>>> d a t a A r r , l a b e l M a t = l o g R e g r e s .l o a d D a t a S e t ()
>>> l o g R e g r e s . g r a d A s c e n t { d a t a A r r , l a b e l M a t )
m a t r i x ([[ 4 . 1 2 4 1 4 3 4 9 ] ,
t 0 . 4 8 0 0 7 3 2 9 ] ,
[ - 0 . 6 1 6 8 4 8 2 ]])
5 . 2 . 3 分 析 数 据 :画出决策边界
上面已经解出了一组回归系数,它确定了不同类别数据之间的分隔线。那么怎样画出该分隔线,
从而使得优化的过程便于理解呢?下面将解决这个问题,打开logRegres.py并添加如下代码。
程序清单5 - 2 画出数据集和^^对化回归最佳拟合直线的函数
de f p l o t B e s t F i t ( w e i ) :
i m p o r t m a t p l o t l i b . p y p l o t as p l t
w e i g h t s = w e i . g e t A ( )
d a t a M a t ,l a b e l M a t = l o a d D a t a S e t ()
d a t a A r r = a r r a y ( d a t a M a t )
n = s h a p e ( d a t a A r r ) [0]
x c o r d l = [] ; y c o r d l - [ ]
x c o r d 2 = [] ; y c o r d 2 = [ ]
f o r i in r a n g e (n) :
i f i n t {labelM at[ i ] )== 1:
x c o r d l .a p p e n d ( d a t a A r r [i, 1 ] ) ; y c o r d l .a p p e n d ( d a t a A r r [ i , 2 ] )
e l s e
x c o r d 2 . a p p e n d ( d a t a A r r [ i , 1 ] ) ; y c o r d 2 . a p p e n d ( d a t a A r r [ i , 2])
f i g = p l t .f i g u r e ()
a x = f i g . a d d _ s u b p l o t (111)
a x . s c a t t e r ( x c o r d l , y c o r d l , s=30, c = 1 r e d 1, m a r k e r = 1s 1)
a x .s c a t t e r ( x c o r d 2 , y c o r d 2 , s=30, c = ' g r e e n ' )
x = a r a n g e (-3.0, 3.0, 0.1)
y = ( - w e i g h t s [0]- w e i g h t s [1]* x ) / w e i g h t s [2]
a x . p l o t ( x , y)
p l t . x l a b e l ( 1X I 1) ; p l t . y l a b e l ( ' X 2 ')
p l t . s h o w ( )
程序清单5-2中的代码是直接用^48中101^3圃出来的。唯~ ^ 指出的是,© 处设置了sigmoid
函数为00 回忆5.2节 ,0是两个分类(类别 1和类别0 ) 的分界处。因此,我们设定0 = 零 。+ ¥ 丨+
w 2x2, 然后解出乂2和乂1的 关 系 式 (即分隔线的方程,注意乂0 = 1 )。
运行程序清单5-2的代码,在?)也00提示符下输人:
80 第 5 章 Logistic回归
>>> f r o m n u m p y i m p o r t *
>>> r e l o a d ( l o g R e g r e s )
< m o d u l e 1l o g R e g r e s 1 f r o m 1logRegres. p y 1>
>>> l o g R e g r e s . p l o t B e s t F i t ( w e i g h t s . g e t A ())
输出的结果如图5-4所示。
图5 - 4 梯度上升算法在500次迭代后得到,6犯0扣&回归最佳拟合直线
这个分类结果相当不错,从图上看只错分了两到四个点。但 是 ,尽管例子简单且数据集很小,
这个方法却需要大量的计算(300次乘法 )。因此下一节将对该算法稍作改进,从而使它可以用在
真实数据集上。
5 . 2 . 4 训 练 算 法 :随机梯度上升
梯度上升算法在每次更新回归系数时都需要遍历整个数据集, 该方法在处理100个左右的数
据集时尚可,但如果有数十亿样本和成千上万的特征,那么该方法的计算复杂度就太高了。一种
改进方法是一次仅用一个样本点来更新回归系数,该方法称为随机梯度上升算法。由于可以在新
样本到来时对分类器进行增量式更新,因而随机梯度上升算法是一个在线学习算法。与 “ 在线学
习”相对应,一次处理所有数据被称作是“批处理” 。
随机梯度上升算法可以写成如下的伪代码:
所有回归系数初始化为1
对数据集中每个样本
计算该样本的梯度
使用alpha x gradient^ .新回归系数值
返回回归系数值
以下是随机梯度上升算法的实现代码。