机器学习实战3:逻辑logistic回归:病马实例

  本文介绍logistic回归,和改进算法随机logistic回归,及一个病马是否可以治愈的案例。例子中涉及了数据清洗工作,缺失值的处理。

  一 引言

  1 sigmoid函数,这个非线性函数十分重要,f(z) = 1 / (1 + e^(-z) ), 画图如下:

      

  这个函数可以很好的把数轴上的值映射到0,1区间,所以很好的解决了分类问题。下面是代码:

def sigmoid(inX):
    return 1.0/(1+exp(-inX))

  2 梯度上升法是我们常用的最优化方法,公式。就是说沿这梯度方向迭代,alpha是步长,控制收敛速度;delta是对各个变量的偏微分;

def gradAscent(dataMatIn, classLabels):
    dataMatrix = mat(dataMatIn)             #convert to NumPy matrix
    labelMat = mat(classLabels).transpose() #convert to NumPy matrix
    m,n = shape(dataMatrix)
    alpha = 0.001
    maxCycles = 500
    weights = ones((n,1))
    for k in range(maxCycles):              #heavy on matrix operations
        h = sigmoid(dataMatrix*weights)     #matrix mult
        error = (labelMat - h)              #vector subtraction
        weights = weights + alpha * dataMatrix.transpose()* error #matrix mult
    return weights

  所有的数据集迭代500次,步长是0.001,目的是确认参数weights,weights会在500次左右收敛,误差较小。

  

  二 逻辑回归算法

  思路:根据梯度上升发,求出了最优化的参数weights,带入logistics分类器,y = (-weights[0]-weights[1]*x)/weights[2],预测测试样本即可;

  inX*weights大于0.5,则分类到1,否则分类到0;主意,inX和weights都是向量;

def classifyVector(inX, weights):
    prob = sigmoid(sum(inX*weights))
    if prob > 0.5: return 1.0
    else: return 0.0

  下面python代码主要利用了matplotlib这个包,模仿matlab画出了图;

def plotBestFit(weights):
    import matplotlib.pyplot as plt
    dataMat,labelMat=loadDataSet()
    dataArr = array(dataMat)
    n = shape(dataArr)[0]
    xcord1 = []; ycord1 = []
    xcord2 = []; ycord2 = []
    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 = 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()

  效果还不错,只有两个实例分错了;

  三 logistics改进:随机梯度上升

  改进算法1:

  上面的logistics缺陷:每次迭代都要遍历所有的数据集样本,这样迭代500次1000000个样本的数据集,压力很大;

  提出增量的方法,每遍历一个样本就修改一次weighs;

def stocGradAscent0(dataMatrix, classLabels):
    m,n = shape(dataMatrix)
    alpha = 0.01
    weights = ones(n)   #initialize to all ones
    for i in range(m):
        h = sigmoid(sum(dataMatrix[i]*weights))
        error = classLabels[i] - h
        weights = weights + alpha * error * dataMatrix[i]
    return weights

  可以看出效果不如非增量的,这是可以接受的,因为增量的只遍历了一遍所有样本,时间上快了很多。

  改进算法2:

  上面的改进算法1,虽然在迭代15000次后三个参数均趋于收敛,但很明显x1 x2参数存在波动(原因是有些样本点不能正确分类,数据集也不是全线性不可分的所以误差很大),为了避免这种波动,提出了改进算法2;

    

  改进点:

    1迭代150次改进的增量算法1,这样还是比迭代200次全集时间要约简不少,并且准确率不低;

    2步长alpha不是固定的,这样可以开始收敛速度大,后来越来越准确的时候收敛速度慢点,后面加0.0001是防止alpha为0。步长为0原地不动迭代就没有意义;

    3为了避免上图的波动情况,随机选取样本点训练,然后再原数据集中删除,避免重复使用;下图可以看出,选用随机点可以避免周期性波动,波动确实可以变小;

def stocGradAscent1(dataMatrix, classLabels, numIter=150):
    m,n = shape(dataMatrix)
    weights = ones(n)   #initialize to all ones
    for j in range(numIter):
        dataIndex = range(m)
        for i in range(m):
            alpha = 4/(1.0+j+i)+0.0001    #apha decreases with iteration, does not
            randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant
            h = sigmoid(sum(dataMatrix[randIndex]*weights))
            error = classLabels[randIndex] - h
            weights = weights + alpha * error * dataMatrix[randIndex]
            del(dataIndex[randIndex])
    return weights

  分类结果:

  四 实例: 病马治愈问题

  先说明下,数据清洗是必要的工作,确实值是我们经常需要处理的;

  缺失值的解决方案:

    1使用特征的均值;

    2使用-1等特殊值填充;

    3删除有缺失值的样本;不推荐,有的数据的获得是不可恢复的

    4使用相似样本的值来填充;

    5使用其它算法计算确实值,比如kmeans等;

    若样本的类属性缺失,监督学习中一般采用直接删除的方法;

  主函数是multiTest(),原理和上面一样,整体过程如下:

    训练分类器,获得线性分类器的参数weighs;

    对测试样本应用分类器,classifyVector方法返回0或1;

    统计错误率;

def classifyVector(inX, weights):
    prob = sigmoid(sum(inX*weights))
    if prob > 0.5: return 1.0
    else: return 0.0

def colicTest():
    frTrain = open(‘horseColicTraining.txt‘); frTest = open(‘horseColicTest.txt‘)
    trainingSet = []; trainingLabels = []
    for line in frTrain.readlines():
        currLine = line.strip().split(‘\t‘)
        lineArr =[]
        for i in range(21):
            lineArr.append(float(currLine[i]))
        trainingSet.append(lineArr)
        trainingLabels.append(float(currLine[21]))
    trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 1000)
    errorCount = 0; numTestVec = 0.0
    for line in frTest.readlines():
        numTestVec += 1.0
        currLine = line.strip().split(‘\t‘)
        lineArr =[]
        for i in range(21):
            lineArr.append(float(currLine[i]))
        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

def multiTest():
    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))

  五 总结

  1 logistic分类器只适用于数值属性,不能处理非数值型数据集;

  2 logistic分类器的目的是寻找一个非线性函数sigmoid的最佳拟合参数;求解过程用到了最优化方法梯度上升法;

时间: 2024-10-11 23:40:01

机器学习实战3:逻辑logistic回归:病马实例的相关文章

机器学习实战笔记5(logistic回归)

1:简单概念描述 假设现在有一些数据点,我们用一条直线对这些点进行拟合(改线称为最佳拟合直线),这个拟合过程就称为回归.训练分类器就是为了寻找最佳拟合参数,使用的是最优化算法. 基于sigmoid函数分类:logistic回归想要的函数能够接受所有的输入然后预测出类别.这个函数就是sigmoid函数,它也像一个阶跃函数.其公式如下: 其中: z = w0x0+w1x1+-.+wnxn,w为参数, x为特征 为了实现logistic回归分类器,我们可以在每个特征上乘以一个回归系数,然后把所有的结果

《机器学习实战》中Logistic回归几个算法的解析

<机器学习实战>第五章<Logistic回归>中讲到了梯度上升法,随机梯度上升法和改进的随机梯度上升法,下面把这几个算法思想总结一下. 首先,梯度上升法比较简单,根据梯度上升的迭代公式计算出了回归系数. 书中并没有采取最小二乘法之类的规则来作为迭代终止的条件,而是直接指定maxCycles最大循环次数来作为迭代终止条件. 假设回归系数初始值为全1,与数据矩阵做乘法并带入sigmoid函数得到介于0~1之间的估计值,这个估计值并不是一个数值,而是一个列向量 估计值与实际值相减求误差

机器学习实战四(Logistic Regression)

机器学习实战四(Logistic Regression) 这一章会初次接触最优化算法,在日常生活中应用很广泛.这里我们会用到基本的梯度上升法,以及改进的随机梯度上升法. Logistic回归 优点:计算代价不高,易于理解和实现 缺点:容易欠拟合,分裂精度可能不高 原理:根据现有数据堆分类边界线建立回归公式,依次进行分类. 这里的回归其实就是最佳拟合的意思. 1.基于Logistic回归和Sigmoid函数的分类. 我们需要一个这样的函数:接受所有的输入,然后预测出类别.例如,如果只有两类,则输出

机器学习(六)— logistic回归

最近一直在看机器学习相关的算法,今天学习logistic回归,在对算法进行了简单分析编程实现之后,通过实例进行验证. 一 logistic概述 个人理解的回归就是发现变量之间的关系,也就是求回归系数,经常用回归来预测目标值.回归和分类同属于监督学习,所不同的是回归的目标变量必须是连续数值型. 今天要学习的logistic回归的主要思想是根据现有的数据对分类边界线建立回归公式,以此进行分类.主要在流行病学中应用较多,比较常用的情形是探索某疾病的危险因素,根据危险因素预测某疾病发生的概率等等.log

【机器学习算法实现】logistic回归__基于Python和Numpy函数库

[机器学习算法实现]系列文章将记录个人阅读机器学习论文.书籍过程中所碰到的算法,每篇文章描述一个具体的算法.算法的编程实现.算法的具体应用实例.争取每个算法都用多种语言编程实现.所有代码共享至github:https://github.com/wepe/MachineLearning-Demo     欢迎交流指正! (2)logistic回归__基于Python和Numpy函数库 1.算法简介 本文的重点放在算法的工程实现上,关于算法的原理不具体展开,logistic回归算法很简单,可以看看A

机器学习之线性回归以及Logistic回归

1.线性回归 回归的目的是预测数值型数据的目标值.目标值的计算是通过一个线性方程得到的,这个方程称为回归方程,各未知量(特征)前的系数为回归系数,求这些系数的过程就是回归. 对于普通线性回归使用的损失函数一般为平方误差.把其用最小二乘法进行优化得到的关于系数w求导所得到的矩阵形式的表达式求得的w便为最优解了. 线性回归可以参考:https://www.cnblogs.com/pinard/p/6004041.html 2.Logistic回归 逻辑回归假设数据服从伯努利分布,以最大化条件概率为学

机器学习&mdash;&mdash;Logistic回归

参考<机器学习实战> 利用Logistic回归进行分类的主要思想: 根据现有数据对分类边界线建立回归公式,以此进行分类. 分类借助的Sigmoid函数: Sigmoid函数图: Sigmoid函数的作用: 将所有特征都乘上一个回归系数,然后将所有结果值相加,将这个总和代入Sigmoid函数中,进而得到一个0-1之间的数值.任何大于0.5的数据被分1类,小于0.5分入0类. 综上,Sigmoid的输入可以记为z: 所以向量w即是我们要通过最优化方法找的系数. w向量的求解: 1).梯度上升法(思

机器学习实战 [Machine learning in action]

内容简介 机器学习是人工智能研究领域中一个极其重要的研究方向,在现今的大数据时代背景下,捕获数据并从中萃取有价值的信息或模式,成为各行业求生存.谋发展的决定性手段,这使得这一过去为分析师和数学家所专属的研究领域越来越为人们所瞩目. <机器学习实战>主要介绍机器学习基础,以及如何利用算法进行分类,并逐步介绍了多种经典的监督学习算法,如k近邻算法.朴素贝叶斯算法.Logistic回归算法.支持向量机.AdaBoost集成方法.基于树的回归算法和分类回归树(CART)算法等.第三部分则重点介绍无监督

第五章:Logistic回归

本章内容 □sigmod函数和logistic回归分类器 □最优化理论初步□梯度下降最优化算法□数据中的缺失项处理 这会是激动人心的一章,因为我们将首次接触到最优化算法.仔细想想就会发现,其实我们日常生活中遇到过很多最优化问题,比如如何在最短时间内从入点到达氏点?如何投人最少工作量却获得最大的效益?如何设计发动机使得油耗最少而功率最大?可风,最优化的作用十分强大.接下来,我们介绍几个最优化算法,并利用它们训练出一个非线性函数用于分类.读者不熟悉回归也没关系,第8章起会深入介绍这一主题.假设现在有