逻辑回归(LR)

来源:互联网 发布:头晕是怎么回事 知乎 编辑:程序博客网 时间:2024/04/30 11:15

背景知识:

二元的分类问题

比如“是否为乳腺癌二分类问题”,我们可以用线性回归的方法求出适合数据的一条直线: 

鉴于线性回归模型只能预测连续的值,但是分类问题,我们需要输出0或1。我们可以预测是否为恶性肿瘤hθ(x)≥.05为恶性,hθ(x)<0.5为良性。

然而线性回归的鲁棒性很差,例如在图1.b的数据集上建立回归,因最右边噪点的存在,使回归模型在训练集上表现都很差。这主要是由于线性回归在整个实数域内敏感度一致,而分类范围,需要在[0,1]。

逻辑回归就是一种减小预测范围,将预测值限定为[0,1]间的一种回归模型,其回归方程与回归曲线如图2所示。逻辑曲线在z=0时,十分敏感,在z>>0或z<<0处,都不敏感,将预测值限定为(0,1)。

其实就是在线性回归的基础上,套用了一个逻辑函数:S形函数(Sigmoid function) 。

 

对模型的理解: 
 (1)

 

hθ(x)的作用是,对于给定的输入变量,根据选择的参数计算输出变量等于1 的可能性 :

例如,如果对于给定的 x,通过已经确定的参数计算得出 hθ(x)=0.7,则表示有 70%的几率 为正向类,相应地 为负向类的几率为 1-0.7=0.3。 

LR与线性回归的不同点在于:为了将线性回归输出的很大范围的数,例如从负无穷到正无穷,压缩到0和1之间,这样的输出值表达为“可能性”才能说服广大民众。

损失函数的选择:

我们知道线性回归模型的损失函数为所有误差的平方和:

理论上说,我们也可以沿用这个定义,但是我们将公式(1) 代入之后得到的 损失函数为 非凸函数。 有很多局部最优解,这将影响梯度下降算法寻找全局最小值。

重新定义:

hθ(x)与 Cost(hθ(x),y)之间的关系如下图所示: 


将构建的 Cost(hθ(x),y)简化如下:
带入代价函数得到:
在得到这样一个代价函数以后,我们便可以用梯度下降算法来求得能使代价函数最小的参数了。算法为:
求导后得到:


多类问题 

 

最后,在我们需要做预测时,我们将所有的分类机都运行一遍,然后对每一个输入变量, 都选择最高可能性的输出变量。 


 

正则化的逻辑回归模型

 

要最小化该代价函数,通过求导,得出梯度下降算法为: 

 

注:看上去同线性回归一样,但是知道 hθ(x)=g(θTX),所以与线性回归不同。 


应用场景:

分类问题的首选吧,如果它的效果不怎么样,那么可以将它的结果作为基准来参考,在基础上与其他算法进行比较

算法优劣:

优点:

●实现简单,广泛的应用于工业问题上;

●分类时计算量非常小,速度很快,存储资源低;

●便利的观测样本概率分数;

对逻辑回归而言,多重共线性并不是问题,它可以结合L2正则化来解决该问题;(????)


缺点:

●当特征空间很大时,逻辑回归的性能不是很好;

●容易欠拟合,一般准确度不太高;

●不能很好地处理大量多类特征或变量;

●必须线性可分,对于非线性特征,需要进行转换;


算法评估:

对于LR分类模型的评估,常用AUC来评估。

实战案例:

某班级100名学生的语文和数学期末考试成绩,决定是否升学。根据打好标签的数据集,判断新的学生是否通过期末考试。

数据集:ex2data1.txt

语文数学是否通过34.6236596245169778.0246928153624060.1825993862097686.308552095468261。。。。。。

描述性分析:


代码:

Scala:

package com.dianping.www/** * Created by sun on 16/7/19. */import org.apache.spark.mllib.classification.LogisticRegressionWithLBFGSimport org.apache.spark.mllib.evaluation.MulticlassMetricsimport org.apache.spark.mllib.linalg.Vectorsimport org.apache.spark.mllib.regression.LabeledPointimport org.apache.spark.{SparkConf, SparkContext}object LR{  def main(args: Array[String]) {    val conf = new SparkConf().setAppName("LR1.0")    val sc = new SparkContext(conf)    // split args    val para = args(0).split(',')    // load data and transform to LabeledPoint format.    val data_tmp = sc.textFile(para(0))    val data = data_tmp.map( line => line.split(',')).map { r =>      val label = r(r.size - 1).toInt      val features = r.slice(0,r.size -1).map(_.toDouble)      LabeledPoint(label,Vectors.dense(features))    }    // Split data into training (60%) and test (40%).    val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L)    val training = splits(0).cache()    val test = splits(1)    // Run training algorithm to build the model    val model = new LogisticRegressionWithLBFGS()      .setNumClasses(para(1).toInt) //two class.      .run(training) // clear Threshold// model.clearThreshold()    // Compute raw scores on the test set.    val predictionAndLabels = test.map { case LabeledPoint(label, features) =>      val prediction = model.predict(features)      (prediction, label)    }    // Get evaluation metrics.    val metrics = new MulticlassMetrics(predictionAndLabels)    val precision = metrics.precision    val recall = metrics.recall    println("Precision = " + precision + ",Recall = " + recall) // Get AUCval metrics2 = new BinaryClassificationMetrics(predictionAndLabels)println("AreaUnderPR = " + metrics2.areaUnderPR() + "AUC = " + metrics2.areaUnderROC())    // Save and load model//    model.save(sc, para(2))    sc.stop()  }}


Reference:

  1. 逻辑回归模型(Logistic Regression, LR)基础
  2. 斯坦福大学2014机器学习个人笔记.pdf
  3. 常见机器学习算法比较
  4. 逻辑回归(logistic regression)
  5. Linear Methods - spark.mllib
0 0
原创粉丝点击