机器学习实战-第五章Logistic回归

Logistic回归:

import numpy as np
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]))                                #添加标签
    fr.close()                                                          #关闭文件
    return dataMat, labelMat                                            #返回

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

#梯度上升算法
def gradAscent(dataMatIn, classLabels):       #dataMatIn 每列代表不同的特征,每行代表每个训练样本     
    dataMarix = np.mat(dataMatIn)#创造矩阵
    labelMat = np.mat(classLabels).transpose() #转置
    m,n = np.shape(dataMarix) #获得维数
    alpha = 0.001 #向目标移动的步长
    maxCycles = 500 #迭代次数
    weights = np.ones((n,1))
    for k in range(maxCycles):
        h = sigmoid(dataMarix*weights) #梯度上升矢量化公式
        error = (labelMat - h) #h是一个列向量 
        weights = weights + alpha + dataMarix.transpose()* error #权重
    return weights

画出数据集和Logistic回归最佳拟合直线的函数:

def plotBestFit(weights):
    dataMat, labelMat = loadDataSet()                                   #加载数据集
    dataArr = np.array(dataMat)                                         #转换成numpy的array数组
    n = np.shape(dataMat)[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])    #1为正样本
        else:
            xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])    #0为负样本
    fig = plt.figure()
    ax = fig.add_subplot(111)         #添加子图一行一列画在第一块
    ax.scatter(xcord1, ycord1, s = 20, c = 'red', marker = 's',alpha=.5)#绘制正样本
    ax.scatter(xcord2, ycord2, s = 20, c = 'green',alpha=.5)            #绘制负样本
    x = np.arange(-3.0, 3.0, 0.1)
    y = (-weights[0] - weights[1] * x) / weights[2]
    ax.plot(x, y)
    plt.title('BestFit')                                                #绘制title
    plt.xlabel('X1'); plt.ylabel('X2')                                  #绘制label
    plt.show()       


if __name__ == '__main__':
    dataMat, labelMat = loadDataSet()           
    weights = gradAscent(dataMat, labelMat)
    plotBestFit(weights)

随机梯度上升:

梯度上升算在每次更新回归系数时都需要遍历整个数据集,一种改进方法是一次仅用一个样本点来更新回归系数,该方法称为 随机梯度上升算法。由于可以在新样本到来时对分类器进行增量式更新,因而随机梯度上升算法是一个在线学习算法。与“在线学习”相对应,一次处理所有数据被称作是“批处理”。

def stocGradAscent1(dataMatrix, classLabels, numIter=150):
    m,n = np.shape(dataMatrix)                                       #返回dataMatrix的大小。m为行数,n为列数。
    weights = np.ones(n)                                             #参数初始化
    for j in range(numIter):
       h = sigmoid(dataMatrix[i]*weights))
       error = classLabels[i] - h
       weights = weights + alpha * error * dataMatrix[i]
    return weights

随机梯度上升算法与梯度上升算法在代码上很相似,但也有些区别:第一,后者的变量h和误差error都是向量,而前者则全是数值;第二,前者没有矩阵的转换过程,所有变量的数据类型都是Numpy数组。

# 函数说明:改进的随机梯度上升算法
#numIter为迭代次数
def stocGradAscent1(dataMatrix, classLabels, numIter=150):
    m,n = np.shape(dataMatrix)                                       #返回dataMatrix的大小。m为行数,n为列数。
    weights = np.ones(n)                                             #参数初始化
    for j in range(numIter):
        dataIndex = list(range(m))
        for i in range(m):
            alpha = 4/(1.0+j+i)+0.01    #降低alpha的大小,每次减小1/(j+i),但是alpha不会减小到0因为有常数项,当j<<max(i)时,alpha不是严格下降的
            randIndex = int(random.uniform(0,len(dataIndex)))        #随机选取样本更新回归系数
            h = sigmoid(sum(dataMatrix[randIndex]*weights))          #选择随机选取的一个样本,计算h
            error = classLabels[randIndex] - h                       #计算误差
            weights = weights + alpha * error * dataMatrix[randIndex]#更新回归系数
            del(dataIndex[randIndex])                                #删除已经使用的样本
    return weights 

实例:从疝气病症预测病马的死亡率

1.准备数据:处理数据中的缺失值
所有缺失值用一个实数值替换,这里取0恰好适用于Logistic回归
如果在测试数据集中发现了一条数据的类别标签已经缺失,那么我们的简单做法是将该条数据丢弃,采用Logistic回归进行分类时这种做法是合理的,而如果采用类似kNN的方法就可能不太行

2.测试数据:用Logistic回归进行回归

from sklearn.linear_model import LogisticRegression

函数说明:使用Sklearn构建Logistic回归分类器

#打开训练集和训练集,并对数据进行格式化处理的函数
def colicSklearn():
    frTrain = open('horseColicTraining.txt')              #打开训练集
    frTest = open('horseColicTest.txt')                   #打开测试集
    trainingSet = []; trainingLabels = []
    testSet = []; testLabels = []
    for line in frTrain.readlines():
        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]))
    for line in frTest.readlines():
        currLine = line.strip().split('\t')
        lineArr =[]
        for i in range(len(currLine)-1):
            lineArr.append(float(currLine[i]))
        testSet.append(lineArr)
        testLabels.append(float(currLine[-1]))
    classifier = LogisticRegression(solver='liblinear',max_iter=10).fit(trainingSet, trainingLabels)
    test_accurcy = classifier.score(testSet, testLabels) * 100
    print('正确率:%f%%' % test_accurcy)


if __name__ == '__main__':
    colicSklearn()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qtayu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值