2016-02-08 28 views
4

我正在使用Spark 1.6運行多級Logistic迴歸(帶有LBFGS)model.predictProbabilities()for LogisticRegression in Spark?

給出X和可能的標籤{} 1.0,2.0,3.0 最終的模型將輸出什麼是最好的預測,說2.0

如果我有興趣知道第二好的預測是什麼,比如3.0,我怎麼能檢索到這些信息?

在NaiveBayes中,我將使用model.predictProbabilities()函數,該函數爲每個樣本輸出一個具有所有可能結果概率的向量。

回答

3

有兩種方法可以在Spark中進行邏輯迴歸:spark.mlspark.mllib

隨着DataFrames您可以使用spark.ml

import org.apache.spark 
import sqlContext.implicits._ 

def p(label: Double, a: Double, b: Double) = 
    new spark.mllib.regression.LabeledPoint(
    label, new spark.mllib.linalg.DenseVector(Array(a, b))) 

val data = sc.parallelize(Seq(p(1.0, 0.0, 0.5), p(0.0, 0.5, 1.0))) 
val df = data.toDF 

val model = new spark.ml.classification.LogisticRegression().fit(df) 
model.transform(df).show 

你得到的原始預測和概率:

+-----+---------+--------------------+--------------------+----------+ 
|label| features|  rawPrediction|   probability|prediction| 
+-----+---------+--------------------+--------------------+----------+ 
| 1.0|[0.0,0.5]|[-19.037302860930...|[5.39764620520461...|  1.0| 
| 0.0|[0.5,1.0]|[18.9861466274786...|[0.99999999431904...|  0.0| 
+-----+---------+--------------------+--------------------+----------+ 

隨着RDDS您可以使用spark.mllib

val model = new spark.mllib.classification.LogisticRegressionWithLBFGS().run(data) 

這種模式確實不公開原始預測和概率。你可以看看predictPoint。它乘以向量並選擇最高預測的類。權重是可公開訪問的,因此您可以複製該算法並保存預測,而不是僅返回最高的那個。

+0

感謝您的回答。雖然,我正在努力理解如何使用ProbabilisticClassificationModel。 1)我不確定LogisticRegressionWithLBFGS是ProbabilisticClassificationModel的子類。 2)網上沒有關於如何使用ProbabilisticClassificationModel的例子 3)什麼是將數據幀傳遞給轉換函數?我用於LogisticRegression的訓練集? 對不起,有很大的困惑。 – bobo32

+1

你說得對,這並不明顯。我會在幾個小時內回來一個完整的例子! –

+0

關於此@Daniel Darabos的任何更新 – bobo32

2

在從@Daniel Darabos建議:

  1. 我試圖用邏輯迴歸函數從毫升,而不是mllib 遺憾的是它不支持多類Logistic迴歸,但只有二進制。
  2. 我看了一下PredictedPoint 並對其進行了修改,以便它打印每個類的所有概率。這是它的樣子:
def predictPointForMulticlass(featurizedVector:Vector,weightsArray:Vector,intercept:Double,numClasses:Int,numFeatures:Int) : Seq[(String, Double)] = { 

     val weightsArraySize = weightsArray.size 
     val dataWithBiasSize = weightsArraySize/(numClasses - 1) 
     val withBias = false 

     var bestClass = 0 
     var maxMargin = 0.0 
     var margins = new Array[Double](numClasses - 1) 
     var temp_marginMap = new HashMap[Int, Double]() 
     var res = new HashMap[Int, Double]() 

     (0 until numClasses - 1).foreach { i => 
      var margin = 0.0 
      var index = 0 
      featurizedVector.toArray.foreach(value => { 
      if (value != 0.0) { 
       margin += value * weightsArray((i * dataWithBiasSize) + index) 
      } 
      index += 1 
      } 
     ) 
     // Intercept is required to be added into margin. 
     if (withBias) { 
      margin += weightsArray((i * dataWithBiasSize) + featurizedVector.size) 
     } 
     val prob = 1.0/(1.0 + Math.exp(-margin)) 
     margins(i) = margin 

     temp_marginMap += (i -> margin) 

     if(margin > maxMargin) { 
      maxMargin = margin 
      bestClass = i + 1 
      } 
     } 

     for ((k,v) <- temp_marginMap){ 
      val calc =probCalc(maxMargin,v) 
      res += (k -> calc) 
     } 

     return res 
    } 

其中probCalc()被簡單地定義爲:

 def probCalc(maxMargin:Double,margin:Double) :Double ={ 
     val res = 1.0/(1.0 + Math.exp(-(margin - maxMargin))) 
     res 
     } 

我返回一個HashMap [詮釋,雙]但是這是可以改變的如你所願。

希望這有助於!