其他分享
首页 > 其他分享> > Logistic回归

Logistic回归

作者:互联网

文章目录

一、Logistic概述

我们用一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称作回归。利用logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。这里的“回归” 一词源于最佳拟合,表示要找到最佳拟合参数集。
logistic回归的一般过程
(1)收集数据:采用任意方法收集数据。
(2)准备数据:由于需要进行距离计算,因此要求数据类型为数值型。另外,结构化数据格式则最佳。
(3)分析数据:采用任意方法对数据进行分析。
(4)训练算法:大部分时间将用于训练,训练的目的是为了找到最佳的分类回归系数。
(5)测试算法:一旦训练步驟完成,分类将会很快。
(6)使用算法:首先,我们需要输入一些数据,并将其转换成对应的结构化数值;接着,基于训练好的回归系数就可以对这些数值进行简单的回归计算,判定它们属于哪个类别.,在这之后,我们就可以夺输出的类别上做一些其他分析工作。

二、Logistic回归算法

1、Logistic回归和sigmoid函数的分类

假设现在有一些数据点,我们利用一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称作为回归。
Logistic回归一种二分类算法,它利用的是Sigmoid函数阈值在[0,1]这个特性。Logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。其实,Logistic本质上是一个基于条件概率的判别模型。
下面我们看一下sigmoid函数,
在这里插入图片描述
在这里插入图片描述
sigmoid值域为[0,1],为了实现logistic回归分类,在每个特征上都乘以一个回归系数,然后把所有值相加,将这个总和带入到sigmoid函数中,进而得到一个范围在0-1之间的数值。任何大于0.5的数据被分入到1类,小于0.5的数据即被分入到0类。

2、最优回归系数确定:梯度上升算法

sigmoid的输入记为z,由下面的公式得出:
在这里插入图片描述
采用向量写法z = w(T) * x,表示将这两个数值向量对应元素相乘然后全部加起来得到z值。其中x是分类器的输入数据,向量w就是我们要找的最佳参数,接下来运用梯度上升算法求得数据集的最佳参数。
梯度上升法
基本思想:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。
下面利用梯度上升算法找到最佳回归系数。数据包含两个数值型特征:X1和X2。
数据:
代码:

from numpy import *
def loaddataset():
    dataMat = [] ;  classlabel = []   #  建立数据和分类列表
    fr = open('testSet.txt').readlines()     #打开数据集,按行读取
    #  遍历数据,存放到dataMat和classlabel
    for line in fr:
        lineArr = line.strip().split()
        dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])   # 方便计算,将X0的值设为1.0
        classlabel.append(float(lineArr[2]))
    return dataMat,classlabel
#  sigmid函数
def sigmoid(x):
    y = 1.0/(1+exp(-x))
    return y
def gradAscent(dataMat,classlabel):
    dataMatrix = mat(dataMat)           #  转化为矩阵,方便后面计算
    labelMatrix = mat(classlabel).transpose()
    m,n = shape(dataMatrix)           #dataMatrix行列数
    alpha = 0.001   #设置步长
    maxCycles = 500    #  迭代次数
    weights = ones((n,1))
    for k in range(maxCycles):    #   不断更新系数weights
        h = sigmoid(dataMatrix * weights)
        error = labelMatrix - h     #计算类别数值与预测的误差
        weights = weights + alpha * dataMatrix.transpose() *error  #更新参数
    return weights

dataMat,classlabel = loaddataset()
weights = gradAscent(dataMat,classlabel)
print(weights)

系数weights结果如下:
在这里插入图片描述
上面已经解出了一组回归系数,它确立了不同类别数据之间的分割线,画出决策边界使其更加形象。
代码:

from numpy import *
import matplotlib.pyplot as plt

def loaddataset():
    dataMat = [] ;  classlabel = []   #  建立数据和分类列表
    fr = open('testSet.txt').readlines()     #打开数据集,按行读取
    #  遍历数据,存放到dataMat和classlabel
    for line in fr:
        lineArr = line.strip().split()
        dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])   # 方便计算,将X0的值设为1.0
        classlabel.append(float(lineArr[2]))
    return dataMat,classlabel
#  sigmid函数
def sigmoid(x):
    y = 1.0/(1+exp(-x))
    return y
def gradAscent(dataMat,classlabel):
    dataMatrix = mat(dataMat)           #  转化为矩阵,方便后面计算
    labelMatrix = mat(classlabel).transpose()
    m,n = shape(dataMatrix)           #dataMatrix行列数
    alpha = 0.001   #设置步长
    maxCycles = 500    #  迭代次数
    weights = ones((n,1))
    for k in range(maxCycles):    #   不断更新系数weights
        h = sigmoid(dataMatrix * weights)
        error = labelMatrix - h     #计算类别数值与预测的误差
        weights = weights + alpha * dataMatrix.transpose() *error  #更新参数
    return weights
#   决策边界绘画
def show(dataMat,classlabel,weights):
    label = array(classlabel)    #转化为数组
    data = array(dataMat)
    weights = array(weights)
    #  创建两个类别的列表1、2
    x1 = [];   y1 = []
    x2 = [];   y2 = []
    for i in range(len(label)):
        if(label[i] == 1):
            x1.append(data[i,1]);  y1.append(data[i,2])    #  x1为第一个特种类别为1的数据,y1为第二个特种类别为1的数据
        else:
            x2.append(data[i, 1]);  y2.append(data[i, 2])    #  x2为第一个特种类别为0的数据,y2为第二个特种类别为0的数据
    plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
    plt.scatter(x1,y1,s=30,c='red',marker='s',label='数据分析')
    plt.scatter(x2,y2,s=30,c='green')
    #  随机决策边界数据
    x = arange(-3.0, 3.0, 0.01)
    print(x)
    y = (-weights[0] - weights[1] * x) / weights[2]    #设置sigmoid函数为0,推出x和y的关系式
    print(y)
    plt.plot(x, y)
    plt.title('BestFit')
    plt.xlabel('x1')
    plt.ylabel('x2')
    plt.legend(loc="best")
    plt.show()
dataMat,classlabel = loaddataset()
weights = gradAscent(dataMat,classlabel)
show(dataMat,classlabel,weights)

分类决策边界如下:
在这里插入图片描述
改进的随机梯度上升算法
随机梯度上升算法和梯度上升算法代码相似,但有些区别1、后者的变量h和误差error都是向量;2、前者没有矩阵的转换过程,所有都是numpy数组;3、alpha在每次迭代的时候都会调整;4、随机选取样本来更新回归系数。
改进的随机梯度上升算法有效地减少了计算量,收敛速度快,并保证了回归效果。

from numpy import *

def loaddataset():
    dataMat = [] ;  classlabel = []   #  建立数据和分类列表
    fr = open('testSet.txt').readlines()     #打开数据集,按行读取
    #  遍历数据,存放到dataMat和classlabel
    for line in fr:
        lineArr = line.strip().split()
        dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])   # 方便计算,将X0的值设为1.0
        classlabel.append(float(lineArr[2]))
    return dataMat,classlabel
#  sigmid函数
def sigmoid(x):
    y = 1.0/(1+exp(-x))
    return y
 #改进的随机梯度算法
def gradAscent(dataMat,classlabel,numIter):
    dataMat = array(dataMat)            # 数组
    m,n = shape(dataMat)
    weights = ones(n)
    for j in range(numIter):
        dataIndex = range(m)
        for i in range(m):
            alpha = 4/(j+i+1.0) +0.01
            randIndex = int(random.uniform(0,len(dataIndex)))     #  选取随机数
            h = sigmoid(sum(dataMat[randIndex]*weights))
            error = classlabel[randIndex] - h           #计算误差
            weights = weights + alpha * error * dataMat[randIndex]
            del(list(dataIndex)[randIndex])    #  删除迭代后的数据
    return weights
dataMat,classlabel = loaddataset()
weights = gradAscent(dataMat,classlabel,150)
print(weights)

weights系数如下:
在这里插入图片描述

3、实战:疝气病症预测病马的死亡率

使用logstic回归来预测患有疝气病的马的存活问题,编程思想:把测试集上每个特征向量乘以最优化方法得来的回归系数,再将乘积结果求和,最后输入到sigmoid函数中即可。如果对应的sigmoid值大于0.5就预测类别标签为1,否则为0。
函数classifyVector作为判别函数,函数colicTest()打开测试集合训练集,并对数据进行处理。
代码:
数据:

from numpy import *

def sigmoid(x):
    y = 1.0/(1+exp(-x))
    return y
 #改进的随机梯度算法
def gradAscent(dataMat,classlabel,numIter):
    dataMat = array(dataMat)            # 数组
    m,n = shape(dataMat)
    weights = ones(n)
    for j in range(numIter):
        dataIndex = range(m)
        for i in range(m):
            alpha = 4/(j+i+1.0) +0.01
            randIndex = int(random.uniform(0,len(dataIndex)))     #  选取随机数
            h = sigmoid(sum(dataMat[randIndex]*weights))
            error = classlabel[randIndex] - h           #计算误差
            weights = weights + alpha * error * dataMat[randIndex]
            del(list(dataIndex)[randIndex])    #  删除迭代后的数据
    return weights
#  判断函数
def classifyVector(x,weights):
    prob = sigmoid(sum(x*weights))
    if prob >0.5:     #  >0.5类别为1
        return 1.0
    else:             #   <0.5类别为0
        return 0.0
def colicTest():
    frTrain = open('horseColicTraining.txt').readlines()   #打开训练集,按行读取
    frTest = open('horseColicTest.txt').readlines()
    trainingSet = [];   trainingLabels = []
    for line in frTrain:
        currline = line.strip().split('\t')
        lineArr = []
        for i in range(len(currline)-1):
            lineArr.append(float(currline[i]))
        trainingSet.append(lineArr)               #  存储训练数据
        trainingLabels.append(float(currline[-1]))    #存储训练数据类别
    trainweights = gradAscent(array(trainingSet),trainingLabels,500)   #  求最佳系数
    errorcount = 0;  numTestVec = 0.0
    #  遍历测试数据
    for line in frTest:
        numTestVec += 1.0
        currline = line.strip().split('\t')
        lineArr = []
        for i in range(len(currline) - 1):
            lineArr.append(float(currline[i]))
        #  判断当前数据的类别,如果预测类别不等于真实类别,错误errorcount加1
        if int(classifyVector(array(lineArr),trainweights))!=int(currline[21]):
            errorcount += 1
    errorRate = (float(errorcount)/numTestVec)   #  计算错误率
    print("the error rate of this test is:%f"%errorRate)
    return errorRate

#  调用colicTest()10次,取平均误差
def mutiTest():
    numTests =10;  errorSum =0.0
    for k in range(numTests):
        errorSum += colicTest()
    print('after %d iterations the average error rate is:%f'%(numTests,errorSum/float(numTests)))
colicTest()
mutiTest()

结果如下所示:
在这里插入图片描述

标签:sigmoid,回归,weights,Logistic,classlabel,dataMat,数据,def
来源: https://blog.csdn.net/weixin_45422335/article/details/104914654