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模型也就有了,可以自己写预测的逻辑。