Logistic回归是统计学习中的经典分类方法,属于对数线性模型,所以也被称为对数几率回归。该模型是一种分类算法,Logistic回归是一种线性分类器,针对的是线性可分问题。我们要了解Logistic回归进行分类的主要思想是:根据现有的数据对分类边界线建立回归方程,然后以此进行分类。这里回归一词源于最佳拟合参数,表示要找到最佳拟合参数集。
Logistic回归的优点在于计算代价不高,易于理解和实现。缺点是容易发生欠拟合现象,分类的精度不高。适合于数值型和标称型数据进行分类。
1.基于Logistic回归和Sigmoid函数的分类
我们想要的函数应该是: 能接受所有的输入然后预测出类别。例如,在两个类的情况下,上述函数输出 0 或 1。有一个函数具有类似的性质(可以输出 0 或者 1 的性质),且数学上更易处理,这就是 Sigmoid 函数。 Sigmoid 函数具体的计算公式如下:
我们可以在每个特征上都乘以一个回归系数,然后将所有值累加,将中国总和带入Sigmoid 函数中,得到一个范围在[0,1]的数值,小于0.5归为0类,导游0.5归为1类。所以Logistic回归可以看出是一种概率估计。
Sigmoid 函数的函数输入记为z,由下面公式得出:
采用向量的写法可以写成,它表示 将两个数值向量对于元素相乘然后相加得到z值。x为分类器输入数值,w为我们要找的最佳参数。
Sigmoid函数的曲线图:
图1-1 两种坐标尺度下的sigmoid函数图。上图为-8到8,曲线变化较为平滑;下图坐标尺度较大-60到60,在(0,0.5)处看起来像阶跃函数
为了实现logistic回归分类器,可以在每个特征上乘以一个回归系数,然后把所有的结果值相加,带入到sigmoid函数中,进而得到0-1之间的数值。任意大于0.5的数值被分入1类,小于0.5的被分入0类。
2.基于最优化方法的最佳回归系数确定
def loadDataSet():
dataMat=[];labelMat=[] #创建数据列表和标签列表
fr=open('D:1.txt')
for line in fr.readlines():
lineArr=line.strip().split()
dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])
labelMat.append(int (lineArr[2]))
return dataMat,labelMat
def sigmid(inx):#sigimod函数
return 1.0/(1+exp(-inx))
def gradAscent(dataMatIn,classLabels):#梯度上升算法
dataMatrix=mat(dataMatIn)
labelMat=mat(classLabels).transpose()
m,n=shape(dataMatrix)
alpha=0.001
maxCycles=500
weights=ones((n,1))
for k in range(maxCycles):
h=sigmoid(dataMatrix*weights)
error=(labelMat-h)
weights=weights+alpha*dataMatrix.transpose()*error
return weights
第一个函数的主要功能是打开文本文档并逐行读取,每行前两个值分别为x1和x2,第三个值是标签对于的类别标签。在梯度上升算法中变量alpha是目标移动的步长,maxCycle是迭代的次数。变量h不是一个数而是一个列向量,列向量的元素格式等于样本个数。
4.分析数据:画出决策边界
已经解出一组回归系数,它确定了不同类别数据之间的分割线。下面是画出数据集和logistic回归最佳拟合直线的函数:
##画出数据集和logistic回归最佳拟合直线
def plotBestFit(weights):
import matplotlib.pyplot as plt ##画图工具
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标签值为1
xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2])
else:
xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) ##xcord2标签值为0
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)
y = (-weights[0]-weights[1]*x)/weights[2]##0为两类的分界处,故假定0=w0x0+w1x1+w2x2,x0=1
y = y.transpose()
ax.plot(x, y)
plt.xlabel('X1'); plt.ylabel('X2')
plt.show()
输出结果
这个分类结果从图上看之分错了2到4个点。尽管数据集很小,但是却需要大量的计算(300次乘法),接下来对算法进行稍微改进。
5.训练算法:随机梯度上升
梯度上升算法每次关系回归系数的时候都需要遍历整个数据集,当数据集数目较少时是可以接受的,但当数据集的样本数目非常多,那么该算法的计算复杂度就非常的高了。因此我们采用了一种改进算法,就是一次仅用一个样本点来更新回归系数,该算法称为随机梯度上升算法。由于可以在新样本到了时对分类器进行增量式更新,因此随机梯度算法是一个在线学习算法。代码如下:
def stoGradAscent0(dataMatrix,classLabels):
m,n=shape(dataMatrix)
alpha=0.01
weights=ones(n)
for i in range(m):
h=sigmid(sum(dataMatrix[i]*weights))
error=classLabels[i]-h
weights=weights+alpha*error*dataMatrix[i]
return weights
Logistic回归的目的·是寻找一个非线性函数Sigmoid的最佳拟合参数,求解过程可以由最优化算法完成。其中最常用的就是梯度上升算法。这里也简单介绍另外一种方法:极大似然法
极大似然法的一般流程为:
1.确定待求解的未知参数θ1 , θ2 , . . . .,如均值、方差或特定 分布函数的参数等
2.计算每个样本X1 , X2 , . . . , Xn的概率密度 f(Xi; 1 , . . . , m).
3.假定样本i.i.d,则可根据样本的概率密度累乘构造似然函数:
4.通过似然函数最大化(求导为零),求解未知参数θ,(为降低计算难度,通常可采用对数加法替换概率乘法,通 过导数为零/极大值来求解未知参数)