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()
原文地址:https://www.cnblogs.com/zhacai/p/8524778.html