本文聊聊逻辑回归(logistic regression)。
逻辑回归虽然名字中带有回归二字,但是它并不是一种回归算法,而是一种分类算法,并且它是在工业界十分常用的一种分类算法。跟回归问题不同,logistic回归中的因变量是分类型变量(比如0,1这种二分类或者0,1,2,3这种多分类问题)。logistic回归的自变量和因变量之间不一定是呈线性关系的。logistic回归最终得到的是因变量取某个值的概率与所有自变量之间的关系。
逻辑回归其实是一种广义线性模型(generalized linear model)。逻辑回归既可以用于二分类,又可以用于多分类,比较常用的是二分类,这种情形比较容易解释。
逻辑回归首先通过一个线性函数对自变量进行变换,然后利用sigmoid函数进行变换,可以得到取值为1的概率,然后将此概率与给定的阈值相比较即可预测某个样本属于0这一类还是属于1这一类。线性函数即为所有特征乘以相应的权重然后累加再加上偏置。sigmoid函数形式如下:
f(x) = 1/(1+e^-x)
逻辑回归中的参数一般使用极大似然法(maximum likelihood estimation)来估计。对于第i个样本,它的因变量y_i = 1的概率是p_i,则y_i = 0的概率就是1-p_i,那么针对第i个样本,它的似然概率为
p(y_i)= p_i^y_i * (1-p_i)^(1-y_i) 。
所有样本的似然概率相乘就得到整个样本集的似然概率。通常都是对这个似然函数取对数,然后再估计它的极大值就可以得到逻辑回归中所有参数的估计值。
求解逻辑回归,其实是一个最优化问题,一般可以利用随机梯度下降法(stocastic gradient decsent)和拟牛顿迭代法(quasi-newton method)来优化。
梯度下降法存在一个问题,即容易陷入局部最优,并且每次对当前样本计算损失函数时,都需要遍历全部样本才能得到损失函数的值,因此会造成计算速度比较慢。
而对于随机梯度下降法,它在计算损失函数的时候只计算当前的代价,最终损失函数是在全部样本迭代一遍然后再求和。更新参数的时候并不是依次遍历样本,而是从样本集中随机选择一个样本进行计算,这种方法收敛速度快,并且可以避免局部最优,并且可以借助参数服务器加以并行。
还有一些其他优化算法,比如拟牛顿法,BFGS,L-BFGS等。
如果在训练集上拟合得很好,但是在预测集上却达不到这种效果,这就称为过拟合现象。为了避免过拟合,可以采取以下措施:
减少特征个数,既可以人工选择保留多少特征,也可以利用算法来选取特征
正则化,其中包含l1正则化(这种方法使得部分特征的权重为0)和l2正则化(这种方法会迫使特征的权重比较小)。
逻辑回归借助softmax函数可以用于多分类问题。它可以输出某个样本属于哪一类的概率,并且满足条件全部概率加起来=1。那么对于多分类问题,如何在softmax和多个LR之间选择呢?
如果所有类别之间互斥(比如苹果,梨,橘子,桃),利用softmax。如果类别之前有联系(比如多个歌手的歌手混在一起时区分哪种歌声来自哪个歌手),这个时候使用多个逻辑回归更为合适。
优缺点:
Logistic回归优点:
实现简单;
分类时计算量非常小;
速度很快,存储资源低;
缺点:
容易欠拟合;
一般准确度不太高;
必须线性可分
基于spark的逻辑回归示例如下:
下面的例子是利用二项和多项逻辑回归模型进行二分类的示例,其中加入了约束项。
首先是利用多项逻辑回归来训练二分类问题,这是因为二分类问题是多分类问题的一种特例。
import org.apache.spark.ml.classification.{
LogisticRegression}
// Load training data
val training = spark.read.format("libsvm")
.load("data/mllib/sample_libsvm_data.txt")
val lr =