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模型也就有了,可以自己寫預測的邏輯。