前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python实现逻辑logistic回归:预测病马的死亡率

python实现逻辑logistic回归:预测病马的死亡率

作者头像
机器学习AI算法工程
发布2018-03-14 15:48:30
1.6K0
发布2018-03-14 15:48:30
举报
文章被收录于专栏:机器学习AI算法工程

假设现在有一些数据点,我们用一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称为回归。训练分类器就是为了寻找最佳拟合参数,使用的是最优化算法。

这就是简单的线性回归问题,可以通过最小二乘法求解其参数,最小二乘法和最大似然估计。 但是当有一类情况如判断邮件是否为垃圾邮件或者判断患者癌细胞为恶性的还是良性的,这就属于分类问题了,是线性回归所无法解决的。这里以线性回归为基础,讲解logistic回归用于解决此类分类问题。

python代码的实现

(1) 使用梯度上升找到最佳参数

代码语言:javascript
复制
from numpy import *  
#加载数据 
def loadDataSet():  
    dataMat = []; labelMat = []  
    fr = open('testSet.txt')  
 for line in fr.readlines():  
        lineArr = line.strip().split()  
        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])  
        labelMat.append(int(lineArr[2]))  
 return dataMat, labelMat  
 
#计算sigmoid函数 
代码语言:javascript
复制
def sigmoid(inX):  
 return 1.0/(1+exp(-inX))  
 
#梯度上升算法-计算回归系数 
def gradAscent(dataMatIn, classLabels):  
    dataMatrix = mat(dataMatIn)          #转换为numpy数据类型 
    labelMat = mat(classLabels).transpose()  
    m,n = shape(dataMatrix)  
    alpha = 0.001 
    maxCycles = 500 
    weights = ones((n,1))  
 for k in range(maxCycles):  
        h = sigmoid(dataMatrix*weights)  
        error = (labelMat - h)  
        weights = weights + alpha * dataMatrix.transpose() * error  
 return weights  

(2) 画出决策边界

代码语言:javascript
复制
#画出决策边界 
def plotBestFit(wei):  
 import matplotlib.pyplot as plt  
    weights = wei.getA()  
    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()  

(3) 随机梯度上升算法

梯度上升算法在处理100个左右的数据集时尚可,但如果有数十亿样本和成千上万的特征,那么该方法的计算复杂度就太高了。改进方法为随机梯度上升算法,该方法一次仅用一个样本点来更新回归系数。它占用更少的计算资源,是一种在线算法,可以在数据到来时就完成参数的更新,而不需要重新读取整个数据集来进行批处理运算。一次处理所有的数据被称为批处理。

  1. #随机梯度上升算法
代码语言:javascript
复制
def stocGradAscent0(dataMatrix, classLabels):  
    dataMatrix = array(dataMatrix)  
    m,n = shape(dataMatrix)  
    alpha = 0.1 
    weights = ones(n)  
 for i in range(m):  
        h = sigmoid(sum(dataMatrix[i] * weights))  
        error = classLabels[i] - h  
        weights = weights + alpha * error * dataMatrix[i]  
 return weights  

(4) 改进的随机梯度上升算法

代码语言:javascript
复制
#改进的随机梯度上升算法 
def stocGradAscent1(dataMatrix, classLabels, numInter = 150):  
    dataMatrix = array(dataMatrix)  
    m,n = shape(dataMatrix)  
    weights = ones(n)  
 for j in range(numInter):  
        dataIndex = range(m)  
 for i in range(m):  
            alpha = 4 / (1.0+j+i) + 0.01 #alpha值每次迭代时都进行调整 
            randIndex = int(random.uniform(0, len(dataIndex)))            #随机选取更新 
            h = sigmoid(sum(dataMatrix[randIndex] * weights))  
            error = classLabels[randIndex] - h  
            weights = weights + alpha * error * dataMatrix[randIndex]  
 del[dataIndex[randIndex]]  
 return weights  

注意:主要做了三个方面的改进:<1>alpha在每次迭代的时候都会调整,这会缓解数据波动或者高频波动。<2>通过随机选取样本来更新回归系数,这样可以减少周期性波动<3>增加了一个迭代参数

3:案例—从疝气病症预测病马的死亡率

(1) 处理数据中缺失值方法:

但是对于类别标签丢失的数据,我们只能采用将该数据丢弃。

(2) 案例代码

代码语言:javascript
复制
#案例-从疝气病症预测病马的死亡率 
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(trainingSet, trainingLabels, 500)  
    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))  
 

4:总结

Logistic回归的目的是寻找一个非线性函数sigmoid的最佳拟合参数,求解过程可以由最优化算法来完成。在最优化算法中,最常用的就是梯度上升算法,而梯度上升算法又可以简化为随机梯度上升算法。

随机梯度上升算法和梯度上升算法的效果相当,但占用更少的计算资源。此外,随机梯度是一种在线算法,可以在数据到来时就完成参数的更新,而不需要重新读取整个数据集来进行批处理运算。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-09-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据挖掘DT数据分析 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档