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

    xiaoxiao2022-07-12  188

    #【Logistc-回归】

    文章目录

    1.难点说明1.plotBestFit(weights.getA())2. del 修改3.RuntimeWarning: overflow encountered in exp 2.基于Logistic 回归和Sigmoid 函数的分类3.示例:从疝气病预测病马的死亡率(logRegres_2.py)4.参考

    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回归

    最新回复(0)