逻辑回归(LR)

背景知识:

二元的分类问题

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

鉴于线性回归模型只能预测连续的值,但是分类问题,我们需要输出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.62365962451697 78.0246928153624 0
60.18259938620976 86.30855209546826 1
。。 。。 。。

描述性分析:


代码:

Scala:

package com.dianping.www

/**
 * Created by sun on 16/7/19.
 */

import org.apache.spark.mllib.classification.LogisticRegressionWithLBFGS
import org.apache.spark.mllib.evaluation.MulticlassMetrics
import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.mllib.regression.LabeledPoint
import 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 AUC
	val 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值