logistiic回归

 什么是回归?

  假设现在有一些数据点,我们用 一条直线对这些点进行拟合(该线称为最佳拟合直线),这个拟合过程就称作回归。

一、基于 Logistic 回归和 Sigmoid 函数的分类

  我们想要的函数应该是,能接受所有的输入然后预测出类别。例如,在两个类的情况下,函数输出0或1。Sigmoid函数能在跳跃点上从0瞬间跳跃到1,。Sigmoid函数具体的计算公式如下:

                 

  Sigmoid函数在不同坐标尺度下的两条曲线图。当x为0时,Sigmoid函数值为0.5。 随着x的增大,对应的Sigmoid值将逼近于1;而随着x的减小,Sigmoid值将逼近于0。如果横坐标 刻度足够大,Sigmoid函数看起来很像一个阶跃函数。

  

  Sigmoid函数的输入记为z,由下面公式得出:

  z = w0X0 + w1X1 +W2X2+...+WnXn

  如果采用向量的写法,上述公式可以写成z = wT x,它表示将这两个数值向量对应元素相乘然后 全部加起来即得到z值。其中的向量x是分类器的输入数据,向量w也就是我们要找到的最佳参数。

  下面首先介绍梯度上升的最优化方法,我们将学习到如何使用该方法求得数据集的最佳参数。

  梯度上升法基于的思想是:要找到某函数的最大值,梯度算法的迭代公式如下:

  w: = w + 梯度*步长*f(w)

二、代码实现算法的过程

1、程序清单一:Logistic 回归梯度上升优化算法

 1 #加载数据集
 2 def loadDataSet():
 3     #定义一个列表保存dataMat数据集
 4     dataMat = []
 5     #定义一个列表labelMat保存数据集对应的标签
 6     labelMat = []
 7     #根据文件绝对路径使用open函数得到文件操作对象fr
 8     fr = open('E:dianzishumachinelearninginaction-master\Ch05\testSet.txt')
 9     #fr.readlines():将文件内所有的数据内容都取出来
10     #使用for循环逐行地把所有的数据读取
11     for line in fr.readlines():
12         #line.strip():去除当前行这条数据记录两端的空格
13         #.split():然后再按空格分割每行的元素
14         lineArr = line.strip().split()
15         #使用dataMat保存这条数据,并最前面增加一列,这一列的值全部都是1,
16         #用来表示公式:y=kx+b中的常数b
17         #另外两个分别是属性或数据集的特征
18         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
19         #保存当前这条数据集对应的标签
20         labelMat.append(int(lineArr[2]))
21     return dataMat,labelMat
1 def sigmoid(inX):           #实现sigmoid公式的函数
2     return 1.0/(1+np.exp(-inX))
 1 #这个函数是用来训练得到数据集特征的权重的
 2 #dataMatIn:这个是训练数据集
 3 #classLabels:这个是训练数据集记录对应的标签
 4 def gradAscent(dataMatIn, classLabels):
 5     #将dataMatIn数据集类型转变成矩阵类型
 6     dataMatrix = np.mat(dataMatIn)      
 7     #将classLabels标签类型转变成矩阵类型,并通过调用transpose来把它转置(转置就是:行变列,列变行)
 8     labelMat = np.mat(classLabels).transpose() 
 9     #获取训练数据集的行数和列数
10     m,n = np.shape(dataMatrix)
11     #定义一个步长,用来控制权重的变化速度
12     alpha = 0.001
13     #设置循环迭代训练的次数
14     maxCycles = 500
15     #定义各个属性的权重,开始每个属性的权重都默认为1
16     weights = np.ones((n,1))
17     #开始迭代训练数据集
18     for k in range(maxCycles):   
19         #dataMatrix*weights计算出一次函数的y值
20         #调用sigmoid概率分类函数,得到训练数据集的预测标签
21         h = sigmoid(dataMatrix*weights)   
22         #计算真实标签与预测标签的偏差值
23         error = (labelMat - h) 
24         #然后根据上面的预测偏差和迭代来不断地修正属性的各个权重
25         weights = weights + alpha * dataMatrix.transpose()* error 
26     #最后函数返回训练得到的各个属性的权重
27     return weights

2、程序清单二、 画出数据集和Logistic回归最佳拟合直线的函数

 1 #这个函数用来看训练得到的权重的用于分类的效果
 2 #weights:训练得到的权重
 3 def plotBestFit(weights):
 4     #导入绘图的模块
 5     import matplot
 6     lib.pyplot as plt
 7     #获取数据集
 8     dataMat,labelMat=loadDataSet()
 9     #将数据集变为数组数据类型
10     dataArr = np.array(dataMat)
11     #取得数据集的行数
12     n = np.shape(dataArr)[0] 
13     #用来保存标签为一的数据集的第2列数据,当做坐标x值
14     xcord1 = []
15     #用来保存标签为一的数据集的地3列数据,当做坐标y值
16     ycord1 = []
17     #用来保存标签为0的数据集的地2列数据,当做坐标x值
18     xcord2 = []
19     #用来保存标签为0的数据集的地3列数据,当做坐标y值
20     ycord2 = []
21     #逐行地读取数据集
22     for i in range(n):
23         #判断这一行数据集的记录标签是不是1
24         if int(labelMat[i])== 1:
25             #获取标签为1的数据集第二列数据
26             xcord1.append(dataArr[i,1])
27             #获取标签为1的数据集第三列数据
28             ycord1.append(dataArr[i,2])
29         else:
30             #获取标签为0的数据集第二列数据
31             xcord2.append(dataArr[i,1])
32             #获取标签为0的数据集第三列数据
33             ycord2.append(dataArr[i,2])
34     #取得一个绘图操作对象
35     fig = plt.figure()
36     #获得一个子图对象
37     ax = fig.add_subplot(111)
38     #描绘标签为1的散点图,颜色是红色
39     ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
40     #描绘标签为0的散点图颜色是绿色
41     ax.scatter(xcord2, ycord2, s=30, c='green')
42     #定义一些x的取值
43     x = np.arange(-3.0, 3.0, 0.1)
44     #带入公式求得上面那些x值对应的y值,系数是训练得到的权重
45     y = (-weights[0]-weights[1]*x)/weights[2]
46     y = np.array(y)
47     #描绘x,y函数直线
48     ax.plot(x, y[0])
49     #图X轴的标签
50     plt.xlabel('X1')
51     #图Y轴的标签
52     plt.ylabel('X2')
53     plt.show()
54 plotBestFit(weights) 


 3、程序清单三、 随机梯度上升算法 

 1 #这也是一个计算属性权值的函数
 2 #dataMatrix:这个是训练数据集
 3 #classLabels:这个是训练数据集记录对应的标签
 4 def stocGradAscent0(dataMatrix, classLabels):
 5     #获取数据集的行数和列数
 6     m,n = np.shape(dataMatrix)
 7     #定义一个常量用来控制weights的变化速度
 8     alpha = 0.01
 9     #定义每个属性的权重,开始默认值都是1
10     weights = np.ones(n) 
11     #逐行地读取训练数据记录
12     for i in range(m):
13         #sum(dataMatrix[i]*weights):取得当前行各个特征值与它对应的权重相乘后再累加
14         #最后将上面的累加和传递到sigmoid函数处理,得到一个当前行的预测标签h
15         h = sigmoid(sum(dataMatrix[i]*weights))
16         #求当前记录真实标签与预测标签的偏差
17         error = classLabels[i] - h
18         #然后根据上面的预测偏差和迭代来不断地修正属性的各个权重
19         weights = weights + alpha * error * dataMatrix[i]
20     #最后函数返回训练得到的各个属性的权重
21     return weights
22 
23 weights = stocGradAscent0(np.array(dataMat),labelMat)
24 print('打印换一种函数求出权值:')
25 print(weights)
26 
27 #这个函数用来看训练得到的权重的用于分类的效果
28 #weights:训练得到的权重
29 def plotBestFit(weights):
30     #导入绘图的模块
31     import matplotlib.pyplot as plt
32     #获取数据集
33     dataMat,labelMat=loadDataSet()
34     #将数据集变为数组数据类型
35     dataArr = np.array(dataMat)
36     #取得数据集的行数
37     n = np.shape(dataArr)[0] 
38     #用来保存标签为一的数据集的地2列数据,当做坐标x值
39     xcord1 = []
40     #用来保存标签为一的数据集的地3列数据,当做坐标y值
41     ycord1 = []
42     #用来保存标签为0的数据集的地2列数据,当做坐标x值
43     xcord2 = []
44     #用来保存标签为0的数据集的地3列数据,当做坐标y值
45     ycord2 = []
46     #逐行地读取数据集
47     for i in range(n):
48         #判断这一行数据集的记录标签是不是1
49         if int(labelMat[i])== 1:
50             #获取标签为1的数据集第二列数据
51             xcord1.append(dataArr[i,1])
52             #获取标签为1的数据集第三列数据
53             ycord1.append(dataArr[i,2])
54         else:
55             #获取标签为0的数据集第二列数据
56             xcord2.append(dataArr[i,1])
57             #获取标签为0的数据集第三列数据
58             ycord2.append(dataArr[i,2])
59     #取得一个绘图操作对象
60     fig = plt.figure()
61     #获得一个子图对象
62     ax = fig.add_subplot(111)
63     #描绘标签为1的散点图,颜色是红色
64     ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
65     #描绘标签为0的散点图颜色是绿色
66     ax.scatter(xcord2, ycord2, s=30, c='green')
67     #定义一些x的取值
68     x = np.arange(-3.0, 3.0, 0.1)
69     #带入公式求得上面那些x值对应的y值,系数是训练得到的权重
70     y = (-weights[0]-weights[1]*x)/weights[2]
71     y = np.array(y)
72     #描绘x,y函数直线
73     ax.plot(x, y)
74     #图X轴的标签
75     plt.xlabel('X1')
76     #图Y轴的标签
77     plt.ylabel('X2')
78     plt.show()
79 
80 #绘图观察这次处理得到权重的效果
81 plotBestFit(weights)

 4、程序清单四、改进的随机梯度上升算法

 1 import numpy as np
 2 
 3 #这是又是另一种求得数据集特征属性权值的函数
 4 #dataMatrix:这个是训练数据集
 5 #classLabels:这个是训练数据集记录对应的标签
 6 #numIter=150:循环迭代更新权重的次数,默认循环150次
 7 def stocGradAscent1(dataMatrix, classLabels, numIter=150):
 8     #获取数据集的行数和列数
 9     m,n = np.shape(dataMatrix)
10     #定义每个属性的权重,开始默认值都是1
11     weights = np.ones(n)   
12     #最外层循环是控制里面的for循环重复运行多少次
13     for j in range(numIter):
14         #数据集的行号
15         dataIndex = list(range(m))
16         #每一行地读取数据集
17         for i in range(m):
18             #定义一个alpha用来控制属性权重的变化速度
19             alpha = 4/(1.0+j+i)+0.0001 
20             #随机获取数据集一行的行号
21             randIndex = int(np.random.uniform(0,len(dataIndex)))
22             #dataMatrix[randIndex]:根据上面获取的行号,取得对应那一行的数据记录
23             #sum(dataMatrix[randIndex]*weights):取得当前行各个特征值与它对应的权重相乘后再累加
24             #最后将上面的累加和传递到sigmoid函数处理,得到一个当前行的预测标签h
25             h = sigmoid(sum(dataMatrix[randIndex]*weights))
26             #求当前记录真实标签与预测标签的偏差
27             error = classLabels[randIndex] - h
28             #然后根据上面的预测偏差和迭代来不断地修正属性的各个权重
29             weights = weights + alpha * error * dataMatrix[randIndex]
30             #删除已经取到了的行号,避免下次重复取到重复行
31             del(dataIndex[randIndex])
32     #最后函数返回训练得到的各个属性的权重
33     return weights
34 
35 weights = stocGradAscent1(np.array(dataMat),labelMat)
36 print('打印stocGradAscent1函数求出权值:')
37 print(weights)
38 
39 #这个函数用来看训练得到的权重的用于分类的效果
40 #weights:训练得到的权重
41 def plotBestFit(weights):
42     #导入绘图的模块
43     import matplotlib.pyplot as plt
44     #获取数据集
45     dataMat,labelMat=loadDataSet()
46     #将数据集变为数组数据类型
47     dataArr = np.array(dataMat)
48     #取得数据集的行数
49     n = np.shape(dataArr)[0] 
50     #用来保存标签为一的数据集的地2列数据,当做坐标x值
51     xcord1 = []
52     #用来保存标签为一的数据集的地3列数据,当做坐标y值
53     ycord1 = []
54     #用来保存标签为0的数据集的地2列数据,当做坐标x值
55     xcord2 = []
56     #用来保存标签为0的数据集的地3列数据,当做坐标y值
57     ycord2 = []
58     #逐行地读取数据集
59     for i in range(n):
60         #判断这一行数据集的记录标签是不是1
61         if int(labelMat[i])== 1:
62             #获取标签为1的数据集第二列数据
63             xcord1.append(dataArr[i,1])
64             #获取标签为1的数据集第三列数据
65             ycord1.append(dataArr[i,2])
66         else:
67             #获取标签为0的数据集第二列数据
68             xcord2.append(dataArr[i,1])
69             #获取标签为0的数据集第三列数据
70             ycord2.append(dataArr[i,2])
71     #取得一个绘图操作对象
72     fig = plt.figure()
73     #获得一个子图对象
74     ax = fig.add_subplot(111)
75     #描绘标签为1的散点图,颜色是红色
76     ax.scatter(xcord1, ycord1, s=30, c='red', marker='s')
77     #描绘标签为0的散点图颜色是绿色
78     ax.scatter(xcord2, ycord2, s=30, c='green')
79     #定义一些x的取值
80     x = np.arange(-3.0, 3.0, 0.1)
81     #带入公式求得上面那些x值对应的y值,系数是训练得到的权重
82     y = (-weights[0]-weights[1]*x)/weights[2]
83     y = np.array(y)
84     #描绘x,y函数直线
85     ax.plot(x, y)
86     #图X轴的标签
87     plt.xlabel('X1')
88     #图Y轴的标签
89     plt.ylabel('X2')
90     plt.show()
91 
92 #绘图观察这次处理得到权重的效果
93 plotBestFit(weights)

如有问题请留言,谢谢!
原文地址:https://www.cnblogs.com/yunsi/p/11070866.html