Spark LogisticRegression 线性回归总结

LogisticRegression 是机器学习中最常用的算法,这里根据使用情况总结了Spark LR的使用demo:

Tip: 本文使用数据格式为Libsvm

 

一.Lr线性回归推导与python实现在之前的博文已经介绍过 ,本文着重介绍spark使用

https://blog.csdn.net/BIT_666/article/details/80415692

 

二.数据样式:

带tag 的libsvm

0 29:1 30:76 74:1 77:1 78:0 79:33
0 9:1 10:16 75:1 76:1 78:0 79:41
0 21:1 22:16 74:1 76:1 78:0 79:27
0 63:1 64:33 75:1 77:1 78:0 79:26
0 31:1 32:84 75:1 76:1 78:0 79:31
0 31:1 32:36 75:1 76:1 78:0 79:11
0 31:1 32:37 75:1 76:1 78:0 79:25
1 31:1 32:61 75:1 77:1 78:3 79:34

这里也可以写小数,不过要保证libsvm的index是升序

 

三.spark 执行

1.导入所需要的包

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.mllib.classification.{LogisticRegressionModel, LogisticRegressionWithLBFGS, LogisticRegressionWithSGD}
import org.apache.spark.mllib.evaluation.MulticlassMetrics
import org.apache.spark.mllib.util.MLUtils

2.初始化spark conf 与 输入数据

    val input = "input"
    val output = "output"
    val conf = if (!local) new SparkConf().setAppName("LR") else new SparkConf().setMaster("local").setAppName("LR")
    val sc = new SparkContext(conf)

3.加载libsvm数据,划分训练测试集

    val examples = MLUtils.loadLibSVMFile(sc, input).cache()
    // 划分训练集 测试集
    val splits = examples.randomSplit(Array(0.8, 0.2), seed = 11L)
    val training = splits(0).cache()
    val test = splits(1)

0.8 0.2是划分训练,测试的比例,也可以自己调整,只要和为1即可,seed是随机种子。

4.选择LR模型训练,这里有两个选择,对应两种优化方式

1) SGD 随机梯度下降

 // 新建逻辑回归模型
    val numIterations = 1000
    val stepSize = 1
    val miniBatchFraction = 1.0
    //选择LR模型
     val model = LogisticRegressionWithSGD.train(training, numIterations, stepSize, miniBatchFraction)

2) LBFGS 拟牛顿法

    val model = new LogisticRegressionWithLBFGS()
  .setNumClasses(2)
  .setIntercept(true)
  .run(training)

--> 两种模型的选择话官方已经不建议使用SGD,经过实际测试同一批数据,LBFGS也比SGD的效果优秀很多,所以这里没有特殊需求使用后者即可;

--> SetNumClasser是设置分为几类,这里libsvm只有两个tag,所以设置为2;

--> Intercept截距项的话就是线性公式是否添加最后的那个常数项b,实际测试下 截距项对最后结果的auc影响不大,可以设置可以不设置

5.评估计算结果

    val prediction = model.predict(test.map(_.features))
    val predictionAndLabel = prediction.zip(test.map(_.label))
    //5 计算测试误差
    val metrics = new MulticlassMetrics(predictionAndLabel)
    val precision = metrics.precision
    println("Precision = " + precision)

将第三步按比例划分出的test数据进行预测,并与原始标签进行比较,得到预测的Precision。如果想得到真实分数的话,调用下边的方法即可

    val result_new = test.map(line =>{
      val pre_label = model.predict(line.features)
      val pre_score = calDot(line.features.toArray,model.weights.toArray)
      val score = Math.pow(1+Math.pow(Math.E, -2 * pre_score), -1)
      (line.label, pre_label,score)
    })

可以通过导出LR模型参数,即各个参数的系数,与libsvm数据先求内积再求sigmoid,就能得到最终分数

6.模型存储与加载

    model.save(sc,output)
    val Lr = LogisticRegressionModel.load(sc,output)

可以通过output 将模型存在固定位置,下次使用时只需要通过spark加载该模型,获取模型的weights,即可使用。尝试了一下加载模型后,一些Api无法使用,不过model.weights方法没有问题,所以有weights,lr模型也就有了,可以自己写预测的逻辑。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章