机器学习实战-【Logistc-回归】

#【Logistc-回归】

1.难点说明

1.plotBestFit(weights.getA())

getA()将weights矩阵转换为数组,getA()函数与mat()函数的功能相反 

如果是矩阵会报错:
 x and y must have same first dimension, but have shapes (60,) and (1, 60)
 
 x = arange(-3.0, 3.0, 0.1)len(x) = [3-(-3)]/0.1 = 60 
 weights是矩阵的话,y = (-weights[0]-weights[1]*x)/weights[2]len(y) = 1

2. del 修改

del那句改成del(list(dataIndex)[randIndex])

3.RuntimeWarning: overflow encountered in exp

当参数 inx 很大时,exp(inx)可能会发生溢出

????????

def sigmoid(inx):
    '''定义sigmoid函数'''
    if inx >=0:
        return 1.0/(1+np.exp(-inx))
    else:
        return np.exp(inx)/(1+np.exp(inx))

2.基于Logistic 回归和Sigmoid 函数的分类

logRegres.py and logRegres_1.py

梯度上升伪代码

所有回归系数初始化为1
重复 R 次
  计算整个数据集的梯度
  使用alpha*gradient更新回顾系数值
返回回归系数值

随机梯度上升

所有回归系数初始化为1
对数据集每个样本
  计算该样本的梯度
  使用alpha*gradient更新回顾系数值
返回回归系数值
import numpy as np
import matplotlib.pyplot as plt

def loadDataSet():
    '''读取数据
    输出:dataMat 数据集
         lalelMat 数据标签'''
    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])])  #特征 + x0=1.0
        labelMat.append(int(lineArr[2]))
    return dataMat, labelMat
        
def sigmoid(inx):
    '''定义sigmoid函数'''
    return 1.0/(1+np.exp(-inx))

def gradAscent(dataMatIn, classLabels):
    '''梯度上升法更新拟合参数
    @ dataMatIn 数据集
    @ classLabels 数据标签
    '''
    dataMatrix = np.mat(dataMatIn)  #将数据集list>>matrix
    labelMat = np.mat(classLabels).transpose()  #将标签转换,并转置
    m, n = np.shape(dataMatrix) #获取数据集的行和列
    alpha = 0.001         # 学习步长
    maxCycles = 500       # 最大迭代次数    
    weights = np.ones((n,1))  #初始化权值参数向量每个维度均为1.0
    
    for k in range(maxCycles):        
        h = sigmoid(dataMatrix*weights)  # 当前的sigmoid函数预测概率
        '''逻辑回归的更新方式'''
        error = (labelMat - h)
        weights = weights + alpha*dataMatrix.transpose()*error
        
    return weights

def plotBestFit(weights):
    '''绘制图像
    @ weights 权重'''
    dataMat, labelMat = loadDataSet()  #导入数据和标签
    dataArr = np.array(dataMat)        #转化为矩阵
    n = np.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) # 创建一个或多个子图(subplot)
    ax.scatter(xcord1,ycord1,c='red', marker='s')
    ax.scatter(xcord2,ycord2, c='green')
    
    x = np.arange(-3.0,3.0,0.1)
    y = (-weights[0]-weights[1]*x)/weights[2] # 绘制直线
    y = y.reshape((60,1))
    ax.plot(x,y)
    plt.xlabel('X1')
    plt.ylabel('X2')
    plt.show()
if __name__=='__main__':
    dataArr, labelMat = loadDataSet()
    weights = gradAscent(dataArr,labelMat)
    plotBestFit(weights.getA())
    

在这里插入图片描述

import numpy as np
import logRegres

def stocGradAscent0(dataMatrix,classLabels):
    '''随机梯度上升算法'''
    dataMat = np.array(dataMatrix)    #为便于计算,转为Numpy数组
    m,n = np.shape(dataMatrix)        #获取数据集的行数和列数
    weights = np.ones(n)            #初始化权值向量各个参数为1.0
    alpha = 0.01 #设置步长为0.01
    #循环m次,每次选取数据集一个样本更新参数
    for i in range(m):
        h = logRegres.sigmoid(np.sum(dataMatrix[i]*weights))  # 计算当前样本的sigmoid函数值
        error=classLabels[i]-h
        #更新权值参数
        weights=weights+alpha*error*dataMat[i]
    return weights

def stocGradAscent1(dataMatrix,classLabels,numIter=150):
    '''改进的随机梯度上升算法'''
    dataMat = np.array(dataMatrix)  #将数据集列表转为Numpy数组
    m,n = np.shape(dataMat) #获取数据集的行数和列数
    weights = np.ones(n) #初始化权值参数向量每个维度均为1
    for j in range(numIter):    #循环每次迭代次数
        dataIndex = range(m)   #获取数据集行下标列表
        for i in range(m):   #遍历行列表
            #每次更新参数时设置动态的步长,且为保证多次迭代后对新数据仍然具有一定影响
            #添加了固定步长0.1
            alpha = 4/(1.0+j+i)+0.1
            randomIndex = int(np.random.uniform(0,len(dataIndex)))  #随机获取样本 
            h = logRegres.sigmoid(np.sum(dataMat[randomIndex]*weights))  #计算当前sigmoid函数值
            error = classLabels[randomIndex]-h
            weights=weights + alpha*error*dataMat[randomIndex]
            '''选取该样本后,将该样本下标删除,确保每次迭代时只使用一次'''
            del(list(dataIndex)[randomIndex])
    return weights


if __name__=='__main__':
    dataArr, labelMat = logRegres.loadDataSet()
    weights = stocGradAscent0(dataArr,labelMat)
    logRegres.plotBestFit(weights)

在这里插入图片描述

3.示例:从疝气病预测病马的死亡率(logRegres_2.py)

import logRegres
import logRegres_1

def clasifyVector(inX,weights):
    '''分类决策函数'''
    prob = logRegres.sigmoid(np.sum(inX*weights))  #计算logistic回归预测概率
    # 判断
    if prob > 0.5:              
        return 1.0
    else:
        return 0.0
    
def colicTest():
    '''logistic回归预测算法'''
    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])) # 将该样本的特征存入lineArr列表
        trainingSet.append(lineArr)   #将该样本的特征向量添加到数据集列表
        trainingLabels.append(float(currLine[21])) #将该样本标签存入标签列表
    '''调用随机梯度上升法更新logistic回归的权值参数'''
    trainWeights = logRegres_1.stocGradAscent1(trainingSet,trainingLabels,500)
    '''测试'''
    errorCount=0;numTestVec=0.0
    for line in frTest.readlines():
        numTestVec += 1.0  #样本总数加1
        currLine=line.strip().split('\t')   #对当前行进行处理,分割出各个特征及样本标签
        lineArr=[]   #新建特征向量
        for i in range(21):  #将各个特征构成特征向量
            lineArr.append(float(currLine[i]))
        #利用分类预测函数对该样本进行预测,并与样本标签进行比较
        if(clasifyVector(lineArr,trainWeights) != int(currLine[21])):
            errorCount += 1  #如果预测错误,错误数加1
   
    errorRate=(float(errorCount)/numTestVec)  #计算测试集总的预测错误率
    print('测试集的错误率为: %f' %(errorRate))    
    return errorRate

def multTest():
    '''多次测试算法求取预测误差平均值'''
    #设置测试次数为10次,并统计错误率总和
    numTests=10;errorRateSum=0.0
    #每一次测试算法并统计错误率
    for k in range(numTests):
        errorRateSum+=colicTest()
    print('经过 %d 次迭代后,错误率的平均值: %f' %(numTests,errorRateSum/float(numTests)))

if __name__=='__main__':
    multTest()
测试集的错误率为: 0.388060
测试集的错误率为: 0.358209
测试集的错误率为: 0.253731
测试集的错误率为: 0.328358
测试集的错误率为: 0.462687
测试集的错误率为: 0.298507
测试集的错误率为: 0.253731
测试集的错误率为: 0.283582
测试集的错误率为: 0.507463
测试集的错误率为: 0.283582
经过 10 次迭代后,错误率的平均值: 0.341791

4.参考

1.机器学习实战之logistic回归

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值