LR算法
一、认识Logistic回归(LR)分类器
首先,Logistic回归虽然名字里带“回归”,但是它实际上是一种分类方法,主要用于两分类问题,利用Logistic函数(或称为Sigmoid函数),自变量取值范围为(-INF, INF),自变量的取值范围为(0,1),函数形式为:
为什么使用sigmoid函数?
- sigmoid函数的定义域是(-INF, +INF),而值域为(0, 1)。
- sigmoid函数是可导的。
- sigmoid函数对于给定的输入变量,会根据选择的参数计算输出变量=1的可能性,也就是说它的输出表示概率,都是0到1之间。
因此最基本的LR分类器适合于对两分类(类0,类1)目标进行分类。Sigmoid 函数是个很漂亮的“S”形,如下图所示:
LR分类器(Logistic Regression Classifier)目的就是从训练数据特征学习出一个0/1分类模型--这个模型以样本特征的线性组合作为自变量,使用logistic函数将自变量映射到(0,1)上。因此LR分类器的求解就是求解一组权值w0,w1,......wn,并带入到sigmoid函数中构造出一个预测函数:
函数的值表示结果为1的概率,就是特征属于y=1的概率。因此对于输入x分类结果为类别1和类别0的概率分别为:
当我们要判别一个新来的特征属于哪个类时,按照下式求出一个z值:
进而求出(1)式---若大于0.5就是y=1的类,反之属于y=0类。(注意:这里依然假设统计样本是均匀分布的,所以设阈值为0.5)。LR分类器的这一组权值如何求得的呢?这就需要涉及到极大似然估计MLE和优化算法的概念了,数学中最优化算法常用的就是梯度上升(下降)算法。
Logistic回归可以也可以用于多分类的,但是二分类的更为常用也更容易解释。所以实际中最常用的就是二分类的Logistic回归。
- LR分类器适用数据类型:数值型和标称型数据。
- 其优点是计算代价不高,易于理解和实现;
- 其缺点是容易欠拟合,分类精度可能不高。
二、Logistic回归数学推导
由上式整理得:
因为各项观测独立,所以它们的联合分布可以表示为各边际分布的乘积:
(m表统计样本数目)
上式称为n个观测的似然函数。我们的目标是能够求出使这一似然函数的值最大的参数估计。于是,最大似然估计的关键就是求出参数θ使上式取得最大值。对上式求对数
最大似然估计就是求使上式取最大值时的θ,这里可以使用梯度上升法求解,求得的θ就是要求的最佳参数。在Andrew Ng的课程中将损失函数J(θ)取为下式,即:J(θ)=-(1/m)l(θ)。
即为LR的对数损失函数。
代码实现:
def costFunction(theta, X, y):
m = X.shape[0]
h = sigmoid(X.dot(theta))
J = (-1.0/m)*(np.log(h).T.dot(y) + np.log(1 - h).T.dot(1-y))
return J
三、批量梯度下降算法BGD(Batch gradient descent)
Gradient descent,是利用一阶的梯度信息找到函数局部最优解的一种方法,也是机器学习里面最简单最常用的一种优化方法。它的思想很简单,要找最小值,我只需要每一步都往下走(也就是每一步都可以让代价函数小一点),而方向则是梯度方向,因为梯度方向下降最快。
(j表样本第j个属性,共n个;a表示步长--每次移动量大小,可自由指定)
损失函数J(θ)最小值时的θ则为要求的最佳参数。通过梯度降法求最小值。θ的初始值可以全部为1.0,更新过程为:
所以θ的递推公式为:
代码实现:
def gradAscent(dataMatIn, classLabels):
dataMatrix = mat(dataMatIn) #convert to NumPy matrix
labelMat = mat(classLabels).transpose() #convert to NumPy matrix
m,n = shape(dataMatrix)
alpha = 0.001 #步长
maxCycles = 2000 #迭代次数
weights = ones((n,1)) #初始化权值
iters = [] #记录迭代次数
cost = [] #记录损失
for k in range(maxCycles):
h = sigmoid(dataMatrix*weights)
error = (h - labelMat)
iters.append(k)
cost.append(costFunction(weights, dataMatrix, labelMat))
weights = weights - alpha *(1.0/m)* dataMatrix.transpose()* error
fig = plt.figure()#生成损失和迭代次数之间的关系图
ax = fig.add_subplot(111)
ax.scatter(iters, cost)
plt.show()
return weights
损失和迭代次数之间的关系图:
优点:可以实现全局最优
缺点:每迭代一步,都要用到训练集所有的数据
四、随机梯度下降算法SGD(Stochastic gradientdescent)
梯度下降算法在每次更新回归系数时都需要遍历整个数据集,该方法在处理100个左右的数据集尚可,但如果有十亿个样本和成千上万的特征,那么该方法的计算复杂度就太高了。一种改进方法是一次禁用一个样本点来更新回归系数,该方法称为随机梯度下降算法。由于可以在新样本到来时对分类 器进行增量式更新,因而随机梯度下降算法是一个在线学习算法。与“在线学习”相对应,一次处理酥油的数据被称为“批处理”。
随机梯度下降算法:
def stocGradAscent0(dataMatIn, classLabels):
dataMatrix = mat(dataMatIn) #convert to NumPy matrix
labelMat = mat(classLabels).transpose() #convert to NumPy matrix
m,n = shape(dataMatrix)
alpha = 0.01
weights = ones((1,3)) #initialize to all ones
iters = []
cost = []
for i in range(m):
h = sigmoid(weights*dataMatrix[i].transpose())
error = h - classLabels[i]
iters.append(i)
cost.append(costFunction(weights, dataMatrix, labelMat))
weights = weights - (1.0/m)*alpha * error * dataMatrix[i]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(iters, cost)
plt.show()
return weights
损失和迭代次数的关系:
优点:随机梯度下降是通过每个样本来迭代更新一次,如果样本量很大的情况(例如几十万),那么可能只用其中几万条或者几千条的样本,就已经将theta迭代到最优解了,对比上面的批量梯度下降,迭代一次需要用到十几万训练样本,一次迭代不可能最优,如果迭代10次的话就需要遍历训练样本10次。
缺点:但是,SGD伴随的一个问题是噪音较BGD要多,使得SGD并不是每次迭代都向着整体最优化方向。
与批量梯度下降对比,随机梯度下降求解的会是最优解吗?
(1)批量梯度下降---最小化所有训练样本的损失函数,使得最终求解的是全局的最优解,即求解的参数是使得风险函数最小。
(2)随机梯度下降---最小化每条样本的损失函数,虽然不是每次迭代得到的损失函数都向着全局最优方向, 但是大的整体的方向是向全局最优解的,最终的结果往往是在全局最优解附近。
五、LR的正则化形式
六、总结
Logistic回归优点:
- 实现简单;
- 分类时计算量非常小,速度很快,存储资源低;
缺点:
- 容易欠拟合,一般准确度不太高(正则化、减少feature数量)
- 只能处理两分类问题(在此基础上衍生出来的softmax可以用于多分类),且必须线性可分;