zoukankan      html  css  js  c++  java
  • Machine Learning in action --LogisticRegession 逻辑回归

    本系列主要参考《机器学习实战》,使用python3编译环境,实现书中的相关代码。

    1.基本算法

      关于梯度上升算法和随机梯度上升算法的选择:

        当数据集较小时,使用梯度上升算法;

        当数据集较大时,使用改进的随机梯度上升算法。

      1 """
      2     使用梯度上升和随机梯度上升,解决逻辑回归
      3     数据的显示
      4 """
      5 
      6 import numpy as np
      7 import matplotlib.pyplot as plt
      8 import random
      9 """
     10     加载数据
     11 """
     12 def loadDataSet():
     13     dataMat = [] #数据列表
     14     labelMat = [] #标签列表
     15     fr = open('testSet.txt') 
     16     for line in fr.readlines():
     17         #print(line)
     18         lineArr = line.strip().split() #去回车,放入列表
     19         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #添加数据
     20         labelMat.append(int(lineArr[2])) #添加标签
     21     fr.close()
     22     return dataMat,labelMat
     23 
     24 """
     25     绘制数据
     26 """
     27 def plotDataSet():
     28     dataMat,labelMat=loadDataSet()
     29     dataArr = np.array(dataMat) #将list或tuple变量转换成numpy的array数组
     30     n = np.shape(dataMat)[0] #numpy.shape返回数组每一维的大小
     31     xcord1 = []; ycord1 = [] #正样本
     32     xcord2 = []; ycord2 = [] #负样本
     33     for i in range(n):       #将样本集分类
     34         if int(labelMat[i]) == 1:
     35             xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
     36         else:
     37             xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])
     38     
     39     fig = plt.figure()
     40     ax = fig.add_subplot(111)  #添加subplot
     41     ax.scatter(xcord1,ycord1,s = 20 , c='red', marker = 's',alpha=0.5) #绘制正样本
     42     ax.scatter(xcord2,ycord2,s = 20 , c='green', alpha=0.5) #绘制负样本
     43     plt.title("DataSet") #绘制title
     44     plt.xlabel('x1'); plt.ylabel('x2') #绘制label
     45     plt.show() #显示
     46 
     47 """
     48     sigmoid函数
     49 """
     50 def sigmoid(inX):
     51     return 1.0/(1 + np.exp(-inX))
     52 
     53 """
     54     梯度上升算法
     55 """
     56 def gradientAscent(dataMatIn,classLabels):
     57     dataMatrix = np.mat(dataMatIn) #转换为numpy矩阵
     58     labelMat = np.mat(classLabels).transpose() #转换为numpy矩阵,并进行转置
     59     m,n = np.shape(dataMatrix) #返回数组每一维的大小,m为行数,n为列数
     60     alpha = 0.001 #步长即学习速率
     61     maxCycles = 500 #最大迭代次数
     62     weights = np.ones((n,1)) #构造n*1的元素全为1的矩阵
     63     for k in range(maxCycles):  #梯度上升公式
     64         h = sigmoid(dataMatrix * weights)
     65         error = labelMat - h
     66         weights = weights + alpha * dataMatrix.transpose() * error
     67     return weights
     68 
     69 """
     70     随机梯度上升算法
     71     相比于梯度上升算法,有两处改进的地方:
     72     1.alpha在每次迭代更新是都会调整,这会缓解数据波动或者高频运动。此外,alpha还有一个常数项,目的是为了保证在多次迭代后仍然对新数据具有一定的影响,如果要处理的问题是动态变化的,可以适当加大该常数项,从而确保新的值获得更大的回归系数。
     73     2.更新回归系数(最优参数)时,只使用一个样本点,并且选择的样本点是随机的,每次迭代不使用已经用过的样本点。这样的方法,就有效地减少了计算量,并保证了回归效果。
     74 """
     75 def randomGradientAscent(dataMat,classLabels,numIter=150): #numIter为迭代次数默认为150
     76     dataMatrix = np.array(dataMat) #将list或tuple变量转换成numpy的array数组
     77     m,n = np.shape(dataMatrix) #返回数组每一维的大小,m为行数,n为列数
     78     weights = np.ones(n) #构造1*n的元素全为1的矩阵
     79     for j in range(numIter):
     80         dataIndex = list(range(m)) #获取数据集行下标列表
     81         for i in range(m):
     82             alpha = 4/(1.0+i+j)+0.01 #每次更新参数时设置动态的步长,且为保证多次迭代后对新数据仍然具有一定影响
     83             randIndex = int(random.uniform(0,len(dataIndex)))#随机选取样本
     84             h = sigmoid(sum(dataMatrix[randIndex]*weights)) #选择随机选取的一个样本,计算h
     85             error = classLabels[randIndex] - h #计算误差
     86             weights= weights + alpha* error * dataMatrix[randIndex] #更新回归系数
     87             del(dataIndex[randIndex]) #删除已经使用的样本
     88     return weights
     89 
     90 """
     91     梯度上升算法,绘制数据集和拟合直线
     92 """
     93 def plotBestFit(weights):
     94     dataMat,labelMat=loadDataSet()
     95     dataArr = np.array(dataMat) #将list或tuple变量转换成numpy的array数组
     96     n = np.shape(dataMat)[0] #numpy.shape返回数组每一维的大小
     97     xcord1 = []; ycord1 = [] #正样本
     98     xcord2 = []; ycord2 = [] #负样本
     99     for i in range(n):       #将样本集分类
    100         if int(labelMat[i]) == 1:
    101             xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
    102         else:
    103             xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2])
    104     
    105     fig = plt.figure()
    106     ax = fig.add_subplot(111)  #添加subplot
    107     ax.scatter(xcord1,ycord1,s = 20 , c='red', marker = 's',alpha=0.5) #绘制正样本
    108     ax.scatter(xcord2,ycord2,s = 20 , c='green', alpha=0.5) #绘制负样本
    109     
    110     x = np.arange(-3.0,3.0,0.1)
    111     y = (-weights[0] -weights[1] * x) / weights[2]
    112     ax.plot(x,y)
    113     plt.title("DataSet") #绘制title
    114     plt.xlabel('x1'); plt.ylabel('x2') #绘制label
    115     plt.show() #显示
    116 
    117 if __name__ == '__main__':
    118     #plotDataSet()
    119     dataMat,labelMat=loadDataSet()
    120     #weights = gradientAscent(dataMat,labelMat).getA() #(梯度上升算法)将矩阵转换为数组,返回权重数组,不转化会报错
    121     weights = randomGradientAscent(dataMat,labelMat) #(随机梯度上升算法)
    122     plotBestFit(weights)

    2.从疝气病症预测病马的死亡率

     1 """
     2     使用随机梯度上升算法,解决病马死亡率问题
     3 """
     4 import numpy as np
     5 import random
     6 
     7 def sigmoid(inX):
     8     return 1.0/(1+np.exp(-inX))
     9 
    10 """
    11     随机梯度上升算法
    12     相比于梯度上升算法,有两处改进的地方:
    13     1.alpha在每次迭代更新是都会调整,这会缓解数据波动或者高频运动。此外,alpha还有一个常数项,目的是为了保证在多次迭代后仍然对新数据具有一定的影响,如果要处理的问题是动态变化的,可以适当加大该常数项,从而确保新的值获得更大的回归系数。
    14     2.更新回归系数(最优参数)时,只使用一个样本点,并且选择的样本点是随机的,每次迭代不使用已经用过的样本点。这样的方法,就有效地减少了计算量,并保证了回归效果。
    15 """
    16 def randomGradientAscent(dataMat,classLabels,numIter=150): #numIter为迭代次数默认为150
    17     dataMatrix = np.array(dataMat) #将list或tuple变量转换成numpy的array数组
    18     m,n = np.shape(dataMatrix) #返回数组每一维的大小,m为行数,n为列数
    19     #print(m,n)
    20     #print(len(classLabels))
    21     weights = np.ones(n) #构造1*n的元素全为1的矩阵
    22     for j in range(numIter):
    23         dataIndex = list(range(m)) #获取数据集行下标列表
    24         for i in range(m):
    25             alpha = 4/(1.0+i+j)+0.01 #每次更新参数时设置动态的步长,且为保证多次迭代后对新数据仍然具有一定影响
    26             randIndex = int(random.uniform(0,len(dataIndex)))#随机选取样本
    27             #print(i ,randIndex)
    28             h = sigmoid(sum(dataMatrix[randIndex]*weights)) #选择随机选取的一个样本,计算h
    29             error = classLabels[randIndex] - h #计算误差
    30             weights= weights + alpha* error * dataMatrix[randIndex] #更新回归系数
    31             del(dataIndex[randIndex]) #删除已经使用的样本
    32     return weights
    33 
    34 """
    35     分类函数,判断分类
    36 """
    37 def classifyVector(inX , weights):
    38     prob = sigmoid(sum(inX*weights))
    39     if prob>0.5:
    40         return 1.0
    41     else:
    42         return 0.0
    43 
    44 """
    45     测试分类器
    46 """
    47 def colicTest():
    48     dataMat,labelMat = loadDataSet()
    49     trainWeigths = randomGradientAscent(dataMat,labelMat,500)
    50     frTest = open('horseColicTest.txt')
    51     numTestVec =0.0 #测试样例总数
    52     errorCount =0 #错误样例数
    53     for line in frTest.readlines():
    54         numTestVec += 1.0
    55         currArr = line.strip().split('	')
    56         lineArr = []
    57         for i in range(len(currArr)-1):
    58             lineArr.append(float(currArr[i]))
    59         if int(classifyVector(np.array(lineArr),trainWeigths)) != int(currArr[-1]):
    60             errorCount += 1
    61     errorRate = (float(errorCount)/numTestVec)*100
    62     print("测试集错误率为:%.2f%%" %errorRate)
    63 
    64 """
    65     加载数据
    66 """
    67 def loadDataSet():
    68     dataSet = [] #数据列表
    69     labelMat = [] #标签列表
    70     frTrain = open('horseColicTraining.txt') 
    71     for line in frTrain.readlines():
    72         #print(line)
    73         currArr = line.strip().split('	') 
    74         lineArr = []
    75         for i in range(len(currArr)-1):
    76             lineArr.append(float(currArr[i]))
    77         dataSet.append(lineArr) 
    78         labelMat.append(float(currArr[-1])) #添加标签
    79     frTrain.close()
    80     return dataSet, labelMat
    81 
    82 if __name__ == '__main__':
    83     colicTest()

    3.使用sklearn预测病马的死亡率

     1 """
     2     使用sklearn构建逻辑回归分类器
     3 """
     4 from sklearn.linear_model import LogisticRegression
     5 """
     6     加载数据
     7 """
     8 def loadDataSet():
     9     dataSet = [] #数据列表
    10     labelMat = [] #标签列表
    11     frTrain = open('horseColicTraining.txt') 
    12     for line in frTrain.readlines():
    13         #print(line)
    14         currArr = line.strip().split('	') 
    15         lineArr = []
    16         for i in range(len(currArr)-1):
    17             lineArr.append(float(currArr[i]))
    18         dataSet.append(lineArr) 
    19         labelMat.append(float(currArr[-1])) #添加标签
    20     frTrain.close()
    21     return dataSet, labelMat
    22 
    23     
    24 """
    25     加载测试数据
    26 """
    27 def loadTestDataSet():
    28     dataSet = [] #数据列表
    29     labelMat = [] #标签列表
    30     frTrain = open('horseColicTest.txt') 
    31     for line in frTrain.readlines():
    32         #print(line)
    33         currArr = line.strip().split('	') 
    34         lineArr = []
    35         for i in range(len(currArr)-1):
    36             lineArr.append(float(currArr[i]))
    37         dataSet.append(lineArr) 
    38         labelMat.append(float(currArr[-1])) #添加标签
    39     frTrain.close()
    40     return dataSet, labelMat
    41 
    42 """
    43     测试分类器
    44 """
    45 def colicTest():
    46     dataMat,labelMat = loadDataSet()
    47     testMat,testLabelMat = loadTestDataSet()
    48     classifier = LogisticRegression(solver ='liblinear',max_iter =10).fit(dataMat,labelMat)
    49     accurcyRate = classifier.score(testMat,testLabelMat)*100
    50     print("测试集正确率为:%.2f%%" %accurcyRate)
    51 
    52 
    53 if __name__ == '__main__':
    54     colicTest()
  • 相关阅读:
    Spring源码解读 推荐流程
    Spring源码解读 推荐流程
    验证数据归属
    验证数据归属
    maven用途、核心概念、用法、常用参数和命令、扩展
    Reverse Linked List II
    Insertion Sort List
    Palindrome Partitioning
    Construct Binary Tree from Preorder and Inorder Traversal
    Valid Parentheses
  • 原文地址:https://www.cnblogs.com/zhacai/p/8524778.html
Copyright © 2011-2022 走看看