2

Birden çok sınıflı bir modele eğitim vermek için LogisticRegressionWithLBFGS() kullanıyorum.Çok sınıflı sınıflandırma için Spark LogisticRegressionWithLBFGS kullanarak tahminlerin olasılığı

mllib belgesindeki belgelere göre, clearThreshold() yalnızca sınıflandırma ikili ise kullanılabilir. Modelde belirli bir girdide her bir sınıfın olasılıklarını çıkarmak için çok sınıflı sınıflandırma için benzer bir şey kullanma yolu var mıdır?

cevap

0

Bunu gerçekleştirmenin iki yolu vardır. Biri sadece biraz farklı özgün yönteminden olduğunu LogisticRegression.scala

object ClassificationUtility { 
    def predictPoint(dataMatrix: Vector, model: LogisticRegressionModel): 
    (Double, Array[Double]) = { 
    require(dataMatrix.size == model.numFeatures) 
    val dataWithBiasSize: Int = model.weights.size/(model.numClasses - 1) 
    val weightsArray: Array[Double] = model.weights match { 
     case dv: DenseVector => dv.values 
     case _ => 
     throw new IllegalArgumentException(s"weights only supports dense vector but got type ${model.weights.getClass}.") 
    } 
    var bestClass = 0 
    var maxMargin = 0.0 
    val withBias = dataMatrix.size + 1 == dataWithBiasSize 
    val classProbabilities: Array[Double] = new Array[Double (model.numClasses) 
    (0 until model.numClasses - 1).foreach { i => 
     var margin = 0.0 
     dataMatrix.foreachActive { (index, value) => 
     if (value != 0.0) margin += value * weightsArray((i * dataWithBiasSize) + index) 
     } 
     // Intercept is required to be added into margin. 
     if (withBias) { 
     margin += weightsArray((i * dataWithBiasSize) + dataMatrix.size) 
     } 
     if (margin > maxMargin) { 
     maxMargin = margin 
     bestClass = i + 1 
     } 
     classProbabilities(i+1) = 1.0/(1.0 + Math.exp(-margin)) 
    } 
    return (bestClass.toDouble, classProbabilities) 
    } 
} 

Not predictPoint sorumluluğunu üstlenir bir yöntem oluşturmaktır, sadece giriş özelliklerinin bir fonksiyonu olarak lojistik hesaplar. Ayrıca orijinal olarak özel olan ve bu yöntemin dışında yer alan bazı val ve varyantları da tanımlar. Sonuçta, bir Array'daki skorları endeksler ve en iyi cevapla birlikte döndürür. Öyle gibi benim yöntemini çağırın: Ancak

// Compute raw scores on the test set. 
val predictionAndLabelsAndProbabilities = test 
    .map { case LabeledPoint(label, features) => 
val (prediction, probabilities) = ClassificationUtility 
    .predictPoint(features, model) 
(prediction, label, probabilities)} 

:

O Kıvılcım katkıda ML lehine MLlib kullanımını azaltmaya görünüyor. ML lojistik regresyon API'si şu anda çok sınıflı sınıflandırmayı desteklemiyor. Şimdi tüm sınıflandırmalara karşı bir sarıcı olarak davranan OneVsRest kullanıyorum. Sen modelleri yineleme ile ham puanlar elde edebilirsiniz: Artık bireysel modelleri var olduğunu

val lr = new LogisticRegression().setFitIntercept(true) 
val ovr = new OneVsRest() 
ovr.setClassifier(lr) 
val ovrModel = ovr.fit(training) 
ovrModel.models.zipWithIndex.foreach { 
    case (model: LogisticRegressionModel, i: Int) => 
    model.save(s"model-${model.uid}-$i") 
} 

val model0 = LogisticRegressionModel.load("model-logreg_457c82141c06-0") 
val model1 = LogisticRegressionModel.load("model-logreg_457c82141c06-1") 
val model2 = LogisticRegressionModel.load("model-logreg_457c82141c06-2") 

, sen rawPrediction

def sigmoid(x: Double): Double = { 
    1.0/(1.0 + Math.exp(-x)) 
} 

val newPredictionAndLabels0 = model0.transform(newRescaledData) 
    .select("prediction", "rawPrediction") 
    .map(row => (row.getDouble(0), 
    sigmoid(row.getAs[org.apache.spark.mllib.linalg.DenseVector](1).values(1)))) 
newPredictionAndLabels0.foreach(println) 

val newPredictionAndLabels1 = model1.transform(newRescaledData) 
    .select("prediction", "rawPrediction") 
    .map(row => (row.getDouble(0), 
    sigmoid(row.getAs[org.apache.spark.mllib.linalg.DenseVector](1).values(1)))) 
newPredictionAndLabels1.foreach(println) 

val newPredictionAndLabels2 = model2.transform(newRescaledData) 
    .select("prediction", "rawPrediction") 
    .map(row => (row.getDouble(0), 
    sigmoid(row.getAs[org.apache.spark.mllib.linalg.DenseVector](1).values(1)))) 
newPredictionAndLabels2.foreach(println) 
ait sigmoid hesaplayarak olasılıkları elde edebilirsiniz