机器学习笔记:逻辑回归(Logistic Regression)

一、介绍
  • Logistic回归是一个广义线性回归,模型形式:Y = WX+b 。
  • Logistic回归的因变量可以是二分类也可以是多分类的,实际最常见的是二分类的Logistic回归。
  • Logistic优点:计算代价不高,易于理解和实现; 缺点:容易欠拟合,分类精度可能不高;适用数据类型:数值型和标称型数据
    logistic回归是一种分类方法,用于两分类问题。其基本思想为:
    a) 寻找合适的假设函数,即分类函数,用以预测输入数据的判断结果
    b) 构造代价函数,即损失函数,用以表示预测的输出结果与训练数据的实际类别之间的偏差;
    c) 最小化代价函数,从而获取最优的模型参数

二、原理

2.1 sigmoid函数

激活函数(Activation Function)有很多种,我们这里主要介绍sigmoid函数。
我们知道线性形式表达式:Y=WX (W>0),Y的大小是随着X各个维度的叠加和的大小线性增加的,如图2-1所示(x为了方便取1维):


图 2-1 一维线性模型形式

sigmoid函数数学表达式:g(z)=1/(1+e(-z)) 函数图像如图2-2所示

图2-2 sigmoid函数图

由图2-2和图2-1所示可知,逻辑函数Y值不再随X各维度之和的大小而呈线性变化了,而是变得更加平滑,这种变化在x=0时,Y变化非常快,然而在X各维度之和持续增大或减小时,Y值变化越来越小,逐渐接近1和0。这种因变量和自变量的变化形式就被称为Logistic变化。利用sigmoid函数做激活函数,我们就可以让线性函数变成表达0~1之间的曲线。
做二分类分类函数时,假设输入的特征是(X0,X1,X2,.....,Xn),我们将每个特征乘以一个回归系数(W0,W1,W2,.....,Wn)然后累加得到一个值Z。
Z = W0X0+W1X1+W2X2+......+WnXn,我们可以写成Z=WTX, W为回归系数,X为输入的特征集,Z为输出的值。输出的值在0~1之间,Z值如果大于0.5,输出为1;小于0.5,则输出0。
所以我们需要找出最佳回归系数,即(W0,W1,W2,......,Wn)。

2.2 凸函数(Convex Function)

优化算法之前,先介绍一下凸函数
凸集:在实数域R上的向量空间中,如果集合S中任意两点的连接上的点都在S内;凸集和凹集如图2-3所示:


图2-3 凸集和凹集

凸函数被定义为某个向量空间的凸子集C上的实值函数f。如果在其定义域C上的任意两点x1,x2,以及α∈[0,1],都有f(ax1+(1-a)X2)<= af(X1)+(1-a)f(X2) ;凸函数示意图如图2-4所示:

图2-4 凸函数示意图

注意:关于凸函数,国内外定义会有稍许差别,有的会称上凸和下凸函数,有的称上凸为凹函数,下凸为严格凸函数,以具体教材为准。
判定方法:
可利用定义法、已知结论法以及函数的二阶导数,对于实数集上的凸函数,一般的判别方法是求它的二阶导数,如果其二阶导数在区间上恒大于0,就称为凹函数(上凸) 。如果其二阶导数在区间上恒小于0,就称为严格凸函数(下凸)
凸函数性质:

  • 凸优化的任一局部极小(大)点也是全局极小(大)点,且全体极小(大)点的集合为凸集。
  • 凸优化的任一局部最优解都是它的整体最优解。
2.3 代价函数

为了找到最优解的目的函数,我们需要引入代价函数,作用是为了计算算法预测值与实际值之间的误差大小。
代价函数如图2-5所示:


图2-5 代价函数表达式

由以上式子可知:当预测准确(即y=1且预测值h接近于1,或当y=0且h接近于0)时,cost接近于0,即误差接近于0;而当预测错误(即y=1而预测值h接近于0,或当y=0而h接近于1)时,cost就为趋于无穷大,即误差趋于无穷大。
将以上式子合并,如图2-6所示:


图2-6 代价函数定义

我们将m个训练样本代价误差累加起来,得到J(w)如图2-7所示:


图2-7 m个代价误差之和

hw(x) 代表算法作出的预测值,即将训练样本的数据特征x与回归系数w进行向量乘法,并作为sigmoid函数得到的输出。过程如图2-8所示

图2-8 sigmoid做非线性拟合

我们希望这个代价函数的函数值向0趋近,所以求梯度,即J(w)对回归系数w的三项各自求偏导过程,如图2-9所示:


图2-9 代价函数求偏导过程

其中有j项特征w求偏导

图2-10 wj求偏导

那么当j=0时,也就是对w0求导,等于 xi0
所以我们的代价函数就是:
图2-11 当j=0时,代价函数

2.4 梯度上升与梯度下降

梯度上升与梯度下降都是优化算法的一种。本身具有良好的通用性,多数算法都可以使用,

2.4.1 梯度上升

对梯度上升来说,要找到某个函数的最大值,最好最快的方法就是沿着函数的梯度方向探寻,。如果梯度记为▽,那么函数f(x,y)的梯度表示:

图2-12 梯度表达式

,如果实值函数F(x)在点a处可微且有定义,那么函数F(x)在a点沿着梯度方向∇F(a) 上升最快
它求的是函数关于各个变量的偏导数,所以它总是代表函数值增长最快的方向,移动方向确定了,我们只需要确定步长α(学习率),梯度上升公式为:W:=W+a∇wf(W) ,其中f(W)为代价函数。f(W)= (y - hw(x))xj

2.4.2 梯度下降

梯度下降与梯度上升区别在于沿梯度方向不同。
如果实值函数F(x)在点a处可微且有定义,那么函数F(x)在a点沿着梯度相反的方向−∇F(a) 下降最快。
梯度下降公式为:W:=W-a∇wf(W) ,其中f(W)为代价函数。f(w)= f(W)= (hw(x) - y)xj
我们只需要不断迭代更新我们的W,直到迭代次数完毕或误差达到允许范围,以此找出最佳回归系数W。

2.4.3 随机梯度上升(下降)

之前的方式是将所有的训练样本代入,最终所求得的解也是全局最优解,求解出来的参数将使损失函数最小。如果将所有样本矩阵带入进行计算,这就是所谓的批量梯度上升(下降)。
但在实际应用场景中,最大的问题就是样本矩阵可能非常大。比如大到放不进内存,比如大到进行一轮迭代需要的运算时间非常长,这个时候,批量梯度上升(下降)就不是那么好用了。这个时候,我们可以采用考虑随机梯度上升(下降)。
批量梯度上升是一次训练带入所有样本,随机梯度上升则是每来一次样本进行一次计算:


图2-13 随机梯度上升

i表示是第i个样本,j表示样本第j个维度。
随机梯度上升(下降)是通过每个样本来迭代更新。如果样本的数量很多,有可能才迭代了一小部分样本,就已经得到了W的解。所以随机梯度上升(下降)的收敛速度可能比批量梯度上升(下降)要快,而且运算量小。但是随机梯度上升(下降)的问题是每次迭代并不是全局最优解的方向,尤其是遇到噪声数据,影响会比较大。

三、代码实现

参考《机器学习实战》第五章Logistic回归样例
训练集如图3-1所示:


图3-1 训练集

导入训练样本代码,如下所示:

#加载训练集
def loadDateSet():
    dataMat =[];labelMat =[]    #训练数据集,标签List
    fr = open('testSet.txt')
    for line in fr.readlines():
        lineArr = line.strip().split()
        dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])]) # 属性值x0,x1,x2
        labelMat.append(int(lineArr[2])) #标签   
    return dataMat,labelMat

loadDataSet用来从文本里面获取样本数据集和样本标签。要注意的是dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])]) ,人为地给每个样本多加了一个特征X0,且设置值为1.0
梯度上升计算最佳回归系数代码,如下所示:

def gradAscent(dataMatIn,classLables):
   dataMatrix = np.mat(dataMatIn)  #转换成二维数组 100X3的矩阵
   labelMat = np.mat(classLables).transpose()#transpose转置   100X1的矩阵
   m,n = np.shape(dataMatrix) #(样本数:100)列数(特征:3)
   alpha = 0.001 #设置梯度上升或下降的步长
   maxCycles =500#迭代次数
   weight = np.ones((n,1))#初始回归系数 3X1的矩阵
   for k in range(maxCycles):
       h = sigmoid(dataMatrix*weight) #通过激活函数转换成非线性函数
       error = (labelMat-h)    #代价函数
       weight = weight + alpha * dataMatrix.transpose()*error #得到每一梯度的W值
   return weight

sigmoid函数计算sigmoid值,sigmoid(z)=1/(1+e-z)
gradAscent函数就是梯度上升法训练过程的函数。
样本数据集是DataMatIn;标签List经过转置(transpose)后变成了列向量;weights是列向量,包含了3个回归系数,初始化为1.0,如图3-2所示:

图3-2 数据集初始矩阵

梯度上升伪代码如下:

  • 每个回归系数初始化为1
  • 重复R次:
  • 计算整个数据集梯度
  • 使用alpha x gradient更新回归系数的向量
  • 返回回归系数
    我们从gradAscent函数定义中可以看到error= (labelMat-h); h=sigmoid(dataMatrix * weights), h是每个特征Xj与系数Wj乘积累加,后通过sigmoid函数得到的输出,是一个100X1列的向量。

我们将之前写的梯度公式和那行代码对照来看,如图3-3所示:


图3-3 代码实现梯度过程

W:=W+a∇wf(W)可知,dataMatrix.transpose()* error就是我们之前求解的代价函数(yi-hw(xi))xij
经过500次迭代后,我们得出最佳回归系数结果代码如下:

dataArr,labelMat = loadDateSet()
weight = gradAscent(dataArr,labelMat)
print(weight)
plotBestFit(weight.getA())

输出如图3-4所示:


图3-4 输出结果

通过matplotlib中的pyplot画出所有数据点和分类界线。代码如下所示:

def plotBestFit(weights):
    dataMat,labelMat = loadDateSet()#导出数据
    dataArr = np.array(dataMat) #矩阵对象
    n = np.shape(dataArr)[0]
    xcord1= []; ycord1=[]
    xcord2 = []; ycord2=[]
    #根据类别分别将数据导入x1、x2、y1、y2中
    for i in range(n):
        if int(labelMat[i])==1:
            xcord1.append(dataArr[i,1]);ycord1.append(dataArr[i,2])
        else:
            xcord2.append(dataArr[i,1]);ycord2.append(dataArr[i,2])
    fig = plt.figure()
    ax=fig.add_subplot(111) #建立新画板对象
    #设置颜色大小,区分分类对象
    ax.scatter(xcord1,ycord1,s=30,c='red',marker='s')
    ax.scatter(xcord2,ycord2,s=30,c='green')
    x=np.arange(-3.0,3.0,0.1)#设置间距,方便直观展示
    y=(-weights[0]-weights[1]*x)/weights[2]
    ax.plot(x,y)
    plt.xlabel('X1');plt.ylabel('X2')
    plt.show()

y=(-weights[0]-weights[1]*x)/weights[2],我们根据之前所说的sigmoid函数性质,在横坐标为0的时候,分成两个类别(0和1),所以我们令函数 输入为0,得到:W0X0+W1X1+W2X2=0
其中x0为1,所以 x2=(-w0-w1x1) / w2。我们令x1为横坐标,令x2为纵坐标得出如图3-5所示图像:

图3-5 Logistic回归分类图像

四、Logistic的拓展-多分类问题

上面介绍了Logistic回归解决二分类问题,实际上Logistic回归也是可以解决多分类问题,原理很简单,举例我们要将一个集合,分成三类。我们只需要进行三次二分类操作
(1)将class1看作一类,class2和class3看作另一类,如图4-1所示:

图4-1 class1与class2、class3

(2)将class2看作一类,class1和class3看作另一类,如图4-2所示:


图4-2 class2一类,class1、class3一类

(3)将class3看作一类,class1和class2看作另一类,如图4-3所示:


图4-3 class3一类,class1、class2一类

这时我们有三个分类函数,由Logistic回归我们可以算出每一类的概率,哪一类的概率越大,便分为哪一类。这样就可以根据二分类的原理来解决多分类问题。

五、总结

综上,我们了解了Logistic回归的原理和实现步骤

  1. 首先,我们知道用线性函数y=WX+b来划分类别,但是为了更好的用函数来进行分类表示,所以我们引入了sigmoid函数,将WX+b作为sigmoid输入,输出0~1的值,我们以大于或小于0.5为界来划分类别。
  2. 为了找到最合适的划分函数,我们需要找到合适的最佳回归系数W与b。这里我们将b常数项也放入在W矩阵中一起求解。
  3. 然后我们找到合适的代价函数来描述预测值与真实值之间的误差,当然代价函数也可以由自己来定义。
  4. 根据凸函数定义,我们使用梯度上升(下降)等优化函数沿着梯度方向寻找最佳回归系数时,找到的局部极大值或极小值就是我们要找的最佳回归系数。

六、参考资料

  1. 《机器学习实战》第五章Logistic回归
  2. https://blog.csdn.net/louishao/article/details/54813073
  3. https://blog.csdn.net/CharlieLincy/article/details/70767791?locationNum=11&fps=1
如果您喜欢我的文章,请关注或点击喜欢,您的支持是我最大的动力 ^ ^~!
欢迎指出问题,一起讨论,共同进步
转载请注明作者及其出处

黑羊的皇冠 简书主页

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容