LR算法

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回归优点:

  1. 实现简单;
  2. 分类时计算量非常小,速度很快,存储资源低;

缺点:

  1. 容易欠拟合,一般准确度不太高(正则化、减少feature数量)
  2. 只能处理两分类问题(在此基础上衍生出来的softmax可以用于多分类),且必须线性可分;

编辑于 2020-05-21 20:46