logistic回归

来源:互联网 发布:mac拳皇13摇杆按键设置 编辑:程序博客网 时间:2024/05/10 06:51

写这篇博文用了很多时间和精力,如果这篇博文对你有帮助,希望您可以打赏给博主相国大人。哪怕只捐1毛钱,也是一种心意。通过这样的方式,也可以培养整个行业的知识产权意识。我可以和您建立更多的联系,并且在相关领域提供给您更多的资料和技术支持。

赏金将用于拉萨儿童图书公益募捐

手机扫一扫,即可:
这里写图片描述

附:《春天里,我们的拉萨儿童图书馆,需要大家的帮助》

主要内容:
深入浅出Logistic回归
一些实验和实战

我的其他博文
softmax回归及其实现(TensorFlow)
感知机实现:python

1,logistic“回归”

本节主要内容为:线性判别模型与感知机,广义线性模型,训练算法,python实现。
下面这个是一个感知机的示意图,也可以看成是一个分类器示意图。

这里写图片描述
图1.1
SUM模块将输入数据按照各个维度进行加权求和,得到的结果送入f模块。
SUM模块可以写成:y=ωTx+b,为了后面的处理更加方便。我们将ωx进行增广,这样SUM模块可以写成:
y=ωTx

f模块是判别函数。他将SUM得到的结果进行处理,从而进行类别的判断。
这里需要说明的是:当我们说判别模型是线性时,指的就是这个f为线性的

对于f常见的有两种,一种是阶跃函数,另一种叫做sigmod函数。由于阶跃函数存在不连续点,不容易处理。因此更常用的是sigmod函数:
y=11+exp(ωTx)

函数图像为:
这里写图片描述

这个函数的输出是介于0和1之间的数。我们一般用它来模拟概率。并且当输出大于0.5时,认为是正例。反之为负例。
这里需要说明的是:sigmod函数输出的是概率,因此这也是logistic回归的优秀之处。

这个函数本身并不是线性的。因此我们考虑,能够通过某种变换,得到一个线性函数?考虑如下的变化:

lny1y=ωTx
可以看到,通过变换lny1y我们得到了一个线性函数。

一般的,我们把yx之间为线性关系的判别函数叫做(狭义/通俗/一般)线性判别函数,而把y的某种变换与输入x之间为线性关系的,叫做广义线性判别函数

因此,我们说logistic回归,是(广义)线性的。由他得到的图1.1叫做logistic分类器。sigmod函数在这里也别叫做logistic函数。现在我们有一批训练数据,我们希望通过训练得到比较好的ω,这样再给我们一个输入时,就可以据此来预测分类了。下面我们介绍训练算法。
这里需要说明的是,不同的判别函数,有各自的优化目标,因此对应的训练也是不同的
举例说明,如果我们的f函数是阶跃函数,那么我们的优化目标可以写为:
L(ω,b)=xiMyi(ωxi+b)

其中M为误分类点的集合。这是一个损失函数,我们希望它取得最小值。对于这个函数,可以采用梯度下降法。具体可以见我的另一篇博文《感知机实现python》
对于logistic回归,我们刚才说到,logistic函数给出的是一个类概率。因此这里我们采用似然函数作为优化目标。logistic函数的输出y,可以看做是P(y=1|x),因此我们的似然函数可以写为:
l(ω)=Πni=1(P(Y=1|xi)yi(1P(Y=1|xi))1yi)
这里y取值为0或1,相应的对数似然为:
L(ω)=i=1n(yiωTxiln(1+exp(ωTxi)))

对此求关于ω的偏导数。得到:
L(ω)ω=ωL(ω)=i=1n(yi11+exp(ωTxi))xi=XTErrors

其中Errors是由一些列的
yi11+exp(ωTxi)=yilogistic(ωTxi)
构成的误差向量。
我们的目标是对似然函数做极大似然估计,你可以另导数为0,然而我们发现这样得不到解析解。所以我们转而采用梯度上升法。可以看到,这里的梯度就是误差向量与输入矩阵的乘积。关于梯度上升法,我已经在《感知机实现python》中做了详细的实现和讲解。此处不再赘述。
代码实现:

#!/usr/bin/env python# -*- coding: UTF-8 -*-"""@author: XiangguoSun@contact: sunxiangguodut@qq.com@file: logistic.py@time: 2017/3/5 9:58@software: PyCharm"""import numpy as np from numpy import *import matplotlib.pyplot as plt def drawSamples(plt,Input):    m, n=shape(Input)    target = Input[:,-1]     for i in xrange(m):        if target[i]==0:            plt.scatter(Input[i,0],Input[i,1],c='blue',marker='o')        else:            plt.scatter(Input[i,0],Input[i,1],c='red',marker='s')   def buildMat(dataSet):    m, n = shape(dataSet)    dataMat = zeros((m, n))    dataMat[:, 0] = 1    dataMat[:, 1:] = dataSet[:, :-1]    return dataMat# Logistic函数def logistic(wTx):    return 1.0/(1.0+exp(-wTx))if __name__ == '__main__':    #导入数据    path = './testSet.txt'  # 数据文件路径    Input = mat(np.loadtxt(path, dtype=float))    target = Input[:,-1] #获取分类标签列表    [m,n] = shape(Input)     #构建b+x 系数矩阵:b这里默认为1    dataMat = buildMat(Input)    #定义步长和迭代次数     alpha = 0.001 # 步长    steps = 500  # 迭代次数    weights = ones((n,1))# 初始化权重向量    weightlist=[]    #主程序    for k in xrange(steps):        gradient = dataMat*mat(weights) # 梯度        output = logistic(gradient)  # logistic函数        errors = target-output # 计算误差        weights = weights + alpha*dataMat.T*errors          weightlist.append(weights)#这个作用时候为了日后分析各个参数变化    print weights#输出训练后的权重    #按分类绘制散点图    drawSamples(plt, Input)    #绘制训练后超平面    X = np.linspace(-7,7,100)    Y = -(double(weights[0])+X*(double(weights[1])))/double(weights[2])    plt.plot(X,Y)    plt.show()

实验结果
这里写图片描述

这里写图片描述

训练好之后,我们就可以用来分类了,分类器非常简单:

def classifier(testData,weights):    m,n=shape(testData)    test=zeros((m,n+1))    test[:,0]=1    test[:,1:]=testData    pro=logistic(sum(test*weights))    if pro > 0.5:        return 1.0    else:        return 0.0

需要说明的是,logistic回归是一个二分类的模型(虽然名字叫回归,其实是分类模型)。那么如果我们希望进行多分类,就可以将logistic的思想推广到多分类中,也就是我们另一篇博文将要介绍的softmax 回归。softmax回归是神经网络和深度学习的最基本的概念。关于softmax回归,请见博主的这篇博文
《softmax回归及其实现(TensorFlow)》

0 0