zoukankan      html  css  js  c++  java
  • 机器学习——Logistic回归

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

    2.基于最优化方法的最佳回归系数确定

    2.1 梯度上升法

    参考:机器学习——梯度下降算法

    2.2 训练算法:使用梯度上升找到最佳参数

    Logistic回归梯度上升优化算法

    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])])	#加上第0维特征值
            labelMat.append(int(lineArr[2]))
        return dataMat,labelMat	#返回数据矩阵和标签向量
    
    def sigmoid(inX):
        return 1.0/(1+exp(-inX))
    
    def gradAscent(dataMatIn, classLabels):		#Logistic回归梯度上升优化算法
        dataMatrix = mat(dataMatIn)             	#由列表转换成NumPy矩阵数据类型,dataMatrix是一个100×3的矩阵
        labelMat = mat(classLabels).transpose() 	#由列表转换成NumPy矩阵数据类型,labelMat是一个100×1的矩阵
        m,n = shape(dataMatrix)		    	#shape函数取得矩阵的行数和列数,m=100,n=3
        alpha = 0.001				#向目标移动的步长
        maxCycles = 500				#迭代次数
        weights = ones((n,1))			#3行1列的矩阵,这个矩阵为最佳的回归系数,和原来的100×3相乘,可以得到100×1的结果
        for k in range(maxCycles):              
            h = sigmoid(dataMatrix*weights)     	#矩阵相乘,得到100×1的矩阵,即把dataMat的每一行的所有元素相加
            error = (labelMat - h)              	#求出和目标向量之间的误差
    	#梯度下降算法
            weights = weights + alpha * dataMatrix.transpose()* error #3×100的矩阵乘以100×1的矩阵,weights是梯度算子,总是指向函数值增长最快的方向
        return weights				#返回一组回归系数,确定了不同类别数据之间的分割线
    
        dataMat,labelMat = loadDataSet()
        print gradAscent(dataMat,labelMat)	#输出回归系数
    
    [[ 4.12414349]
     [ 0.48007329]
     [-0.6168482 ]]
    

    2.3 分析数据:画出决策边界

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

    def plotBestFit(wei):			#画出数据集和Logistic回归最佳拟合直线的函数
        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)
        #最佳拟合曲线,这里设w0x0+w1x1+w2x2=0,因为0是两个分类(0和1)的分界处(Sigmoid函数),且此时x0=1
        #图中y表示x2,x表示x1
        y = (-weights[0]-weights[1]*x)/weights[2]	
        ax.plot(x, y)
        plt.xlabel('X1'); plt.ylabel('X2');
        plt.show()
    

     

        dataMat,labelMat = loadDataSet()
        #print dataMat
        #print labelMat
        #print gradAscent(dataMat,labelMat)	#输出回归系数
        plotBestFit(gradAscent(dataMat,labelMat))
    

     

    2.4 训练算法:随梯度上升

    def stocGradAscent0(dataMatrix, classLabels):	#随机梯度上升算法
        m,n = shape(dataMatrix)
        alpha = 0.01
        weights = ones(n)   			#3行1列的矩阵,初始最佳回归系数都为1,
        for i in range(m):
            h = sigmoid(sum(dataMatrix[i]*weights))	#计算出是数值,而不是向量,dataMatrix[100×3]中取得[1×3],乘以[3×1],得到数值
            error = classLabels[i] - h
            weights = weights + alpha * error * dataMatrix[i]
        return weights
    
    def plotBestFit(weights):			#画出数据集和Logistic回归最佳拟合直线的函数
        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)
        #最佳拟合曲线,这里设w0x0+w1x1+w2x2=0,因为0是两个分类(0和1)的分界处(Sigmoid函数),且此时x0=1
        #图中y表示x2,x表示x1
        y = (-weights[0]-weights[1]*x)/weights[2]	
        ax.plot(x, y)
        plt.xlabel('X1'); plt.ylabel('X2');
        plt.show()
    
        dataMat,labelMat = loadDataSet()
        #print dataMat
        #print labelMat
        #print gradAscent(dataMat,labelMat)	#输出回归系数
        #plotBestFit(gradAscent(dataMat,labelMat))
        plotBestFit(stocGradAscent0(array(dataMat),labelMat))
    

     

     

    改进的随机梯度上升算法

    def stocGradAscent1(dataMatrix, classLabels, numIter=150):
        m,n = shape(dataMatrix)
        weights = ones(n)   		#初始化回归系数
        for j in range(numIter):		#从0到149开始循环
            dataIndex = range(m)
            for i in range(m):		#从0到99开始循环
                alpha = 4/(1.0+j+i)+0.0001    			#步进alpha的值逐渐减小,j=0-150,i=1-100,使得收敛的速度加快
                randIndex = int(random.uniform(0,len(dataIndex)))	#样本随机选择0-99中的一个数计算回归系数,减小周期性波动的现象
                h = sigmoid(sum(dataMatrix[randIndex]*weights))
                error = classLabels[randIndex] - h
                weights = weights + alpha * error * dataMatrix[randIndex]
                del(dataIndex[randIndex])
        return weights
    

     

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

     1.准备数据:处理数据中的缺失值

    2.测试算法:使用Logistic回归进行分类

    def classifyVector(inX, weights):	#输入回归系数和特征向量,计算出Sigmoid值,如果大于0.5则返回1,否则返回0
        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('	')
            lineArr =[]
            for i in range(21):			#把0-20个病症加到列表中
                lineArr.append(float(currLine[i]))
            trainingSet.append(lineArr)			#把得到的每个列表加到训练集合中
            trainingLabels.append(float(currLine[21]))	#把标签加到训练标签中
        trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 1000)	#使用改进的随机梯度上升算法,递归1000次,计算回归系数
        errorCount = 0; numTestVec = 0.0
        for line in frTest.readlines():		#导入测试数据
            numTestVec += 1.0			#测试数据的总数
            currLine = line.strip().split('	')
            lineArr =[]
            for i in range(21):			#把0-20个病症加到列表中,作为分类器的输入
                lineArr.append(float(currLine[i]))
            if int(classifyVector(array(lineArr), trainWeights))!= int(currLine[21]):	#计算分类错误的次数,currLine[21]表示真正死亡与否
                errorCount += 1
        errorRate = (float(errorCount)/numTestVec)						#计算错误率
        print "the error rate of this test is: %f" % errorRate
        return errorRate
    
    def multiTest():	#调用colicTest()十次并求结果的平均值
        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))
    

     

  • 相关阅读:
    swift-教你如何实现导航上的UISearchController动画效果。
    swift-自动计算字符串的宽高
    值得收藏--GitHub Top 20 开源项目
    swift-通知的基本使用
    swift-UITableView的基本使用
    绝对好用的浏览器json解析网址
    swift-正则验证手机号码
    swift-计算字符串长度
    swift-导航栏添加自定义返回按钮
    swift-UITextfield控件的基本属性设置
  • 原文地址:https://www.cnblogs.com/tonglin0325/p/6064730.html
Copyright © 2011-2022 走看看