2016-05-18 19 views
5

का उपयोग कर स्पार्क में ग्रेडियेंट बूस्टिंग पेड़ के मामले में कक्षाओं की संभावनाओं की भविष्यवाणी करना यह ज्ञात है कि स्पार्क में जीबीटी एस आपको अब तक लेबल की भविष्यवाणी करता है।वृक्ष उत्पादन

मैं एक वर्ग के लिए भविष्यवाणी की संभावनाओं की गणना करने की कोशिश कर के बारे में सोच रहा था (जैसे कि सभी उदाहरणों एक निश्चित पत्ती के अंतर्गत आने वाले)

कोड का निर्माण करने के GBT के

import org.apache.spark.SparkContext 
import org.apache.spark.mllib.regression.LabeledPoint 
import org.apache.spark.mllib.linalg.Vectors 
import org.apache.spark.mllib.tree.GradientBoostedTrees 
import org.apache.spark.mllib.tree.configuration.BoostingStrategy 
import org.apache.spark.mllib.tree.model.GradientBoostedTreesModel 
import org.apache.spark.mllib.util.MLUtils 

//Importing the data 
val data = sc.textFile("data/mllib/credit_approval_2_attr.csv") //using the credit approval data set from UCI machine learning repository 

//Parsing the data 
val parsedData = data.map { line => 
    val parts = line.split(',').map(_.toDouble) 
    LabeledPoint(parts(0), Vectors.dense(parts.tail)) 
} 

//Splitting the data 
val splits = parsedData.randomSplit(Array(0.7, 0.3), seed = 11L) 
val training = splits(0).cache() 
val test = splits(1) 

// Train a GradientBoostedTrees model. 
// The defaultParams for Classification use LogLoss by default. 
val boostingStrategy = BoostingStrategy.defaultParams("Classification") 
boostingStrategy.numIterations = 2 // We can use more iterations in practice. 
boostingStrategy.treeStrategy.numClasses = 2 
boostingStrategy.treeStrategy.maxDepth = 2 
boostingStrategy.treeStrategy.maxBins = 32 
boostingStrategy.treeStrategy.subsamplingRate = 0.5 
boostingStrategy.treeStrategy.maxMemoryInMB =1024 
boostingStrategy.learningRate = 0.1 

// Empty categoricalFeaturesInfo indicates all features are continuous. 
boostingStrategy.treeStrategy.categoricalFeaturesInfo = Map[Int, Int]() 

val model = GradientBoostedTrees.train(training, boostingStrategy) 

model.toDebugString 

यह मैं गहराई के 2 पेड़ देता है सादगी के लिए नीचे के रूप में 2:

Tree 0: 
    If (feature 3 <= 2.0) 
    If (feature 2 <= 1.25) 
     Predict: -0.5752212389380531 
    Else (feature 2 > 1.25) 
     Predict: 0.07462686567164178 
    Else (feature 3 > 2.0) 
    If (feature 0 <= 30.17) 
     Predict: 0.7272727272727273 
    Else (feature 0 > 30.17) 
     Predict: 1.0 
    Tree 1: 
    If (feature 5 <= 67.0) 
    If (feature 4 <= 100.0) 
     Predict: 0.5739387416147804 
    Else (feature 4 > 100.0) 
     Predict: -0.550117566730937 
    Else (feature 5 > 67.0) 
    If (feature 2 <= 0.0) 
     Predict: 3.0383669122382835 
    Else (feature 2 > 0.0) 
     Predict: 0.4332824083446489 

मेरे सवाल यह है: मैं ऊपर पेड़ की तरह उपयोग कर सकते हैं भविष्यवाणी की संभावनाओं की गणना करने के:

पेड़ 1 से पेड़ 0 + पत्ती स्कोर से/(1 + exp (पत्ता स्कोर (पेड़ 1 से पेड़ 0 + पत्ती स्कोर से पत्ती स्कोर) भविष्यवाणी

exp के लिए इस्तेमाल किया सुविधा सेट में हर मामले के संबंध में))

यह मुझे एक प्रकार की संभावना देता है। लेकिन यह सुनिश्चित नहीं है कि यह करने का सही तरीका है या नहीं। इसके अलावा यदि कोई दस्तावेज समझाता है कि कैसे पत्ता स्कोर (भविष्यवाणी) की गणना की जाती है। अगर कोई साझा कर सकता है तो मैं वास्तव में आभारी रहूंगा।

कोई भी सुझाव शानदार होगा।

उत्तर

0

असल में मैं पेड़ का उपयोग करके संभाव्यताओं की भविष्यवाणी करने और प्रश्न में दिए गए पेड़ के निर्माण की भविष्यवाणी करने में सक्षम था। मैंने वास्तव में जीबीटी भविष्यवाणी लेबल आउटपुट के साथ जांच की। जब मैं थ्रेसहोल्ड 0.5 के रूप में उपयोग करता हूं तो यह ठीक से मेल खाता है।

तो हम थोड़ा बदलाव के साथ ऐसा ही करते हैं।

भविष्यवाणी के लिए इस्तेमाल किया सुविधा सेट में हर मामले के संबंध में

:

exp (पेड़ से पत्ता स्कोर 0 + (learning_rate) * पेड़ 1 से पत्ती स्कोर) पेड़ से/(1 + exp (पत्ता स्कोर 0 + (learning_rate) * पेड़ से पत्ती स्कोर 1))

यह अनिवार्य रूप से मुझे पूर्वानुमानित संभावनाएं देता है।

मैंने 3 पेड़ों पर गहराई से परीक्षण किया 3. यह काम किया। और विभिन्न डेटा सेट के साथ भी।

यह जानना बहुत अच्छा होगा कि किसी और ने पहले ही यह कोशिश की है या नहीं। यदि नहीं, तो वे इसे आजमा सकते हैं और टिप्पणी कर सकते हैं।

+1

आप यहां संभाव्यता गणना कोड क्यों पेस्ट नहीं करते हैं। इससे समुदाय की मदद मिलेगी – Run2

+1

बस – Run2

+0

से ऊपर कुछ कोड जोड़ा गया यह एक्स (x)/(1 + exp (x)) = 1/(1 + exp (-x)) के बाद अन्य उत्तरों के समान है, और वजन पेड़ 0 के लिए सीखने की दर – Brian

1
def score(features: Vector,gbdt: GradientBoostedTreesModel): Double = { 
    val treePredictions = gbdt.trees.map(_.predict(features)) 
    blas.ddot(gbdt.numTrees, treePredictions, 1, gbdt.treeWeights, 1) 
} 
def sigmoid(v : Double) : Double = { 
    1/(1+Math.exp(-v)) 
} 
// model is output of GradientBoostedTrees.train(...,...) 
// testData is libSVM format 
val labelAndPreds = testData.map { point => 
     var prediction = score(point.features,model) 
     prediction = sigmoid(prediction) 
     (point.label, Vectors.dense(1.0-prediction, prediction)) 
} 
2

स्पार्क आंतरिक निर्भरताओं का उपयोग करके मेरा दृष्टिकोण यहां है। आपको बाद में मैट्रिक्स ऑपरेशन के लिए रैखिक बीजगणित लाइब्रेरी आयात करने की आवश्यकता होगी, यानी, सीखने की दर के साथ पेड़ की भविष्यवाणियों को गुणा करना।

// Get the log odds predictions from each tree 
val treePredictions = testData.map { point => model.trees.map(_.predict(point.features)) } 

// Transform the arrays into matrices for multiplication 
val treePredictionsVector = treePredictions.map(array => Vectors.dense(array)) 
val treePredictionsMatrix = new RowMatrix(treePredictionsVector) 
val learningRate = model.treeWeights 
val learningRateMatrix = Matrices.dense(learningRate.size, 1, learningRate) 
val weightedTreePredictions = treePredictionsMatrix.multiply(learningRateMatrix) 

// Calculate probability by ensembling the log odds 
val classProb = weightedTreePredictions.rows.flatMap(_.toArray).map(x => 1/(1 + Math.exp(-1 * x))) 
classProb.collect 

// You may tweak your decision boundary for different class labels 
val classLabel = classProb.map(x => if (x > 0.5) 1.0 else 0.0) 
classLabel.collect 

यहाँ छोटा सा अंश है एक कोड आप & कॉपी कर सकते हैं:

val model = GradientBoostedTrees.train(trainingData, boostingStrategy) 

मॉडल वस्तु का उपयोग कर प्रायिकता की गणना करने के लिए:

import org.apache.spark.mllib.linalg.{Vectors, Matrices} 
import org.apache.spark.mllib.linalg.distributed.{RowMatrix} 

आप GBT के साथ एक मॉडल बनाने कहो सीधे स्पार्क-खोल में पेस्ट करें:

import org.apache.spark.mllib.regression.LabeledPoint 
import org.apache.spark.mllib.linalg.{Vectors, Matrices} 
import org.apache.spark.mllib.linalg.distributed.{RowMatrix} 
import org.apache.spark.mllib.tree.GradientBoostedTrees 
import org.apache.spark.mllib.tree.configuration.BoostingStrategy 
import org.apache.spark.mllib.tree.model.GradientBoostedTreesModel 

// Load and parse the data file. 
val csvData = sc.textFile("data/mllib/sample_tree_data.csv") 
val data = csvData.map { line => 
    val parts = line.split(',').map(_.toDouble) 
    LabeledPoint(parts(0), Vectors.dense(parts.tail)) 
} 
// Split the data into training and test sets (30% held out for testing) 
val splits = data.randomSplit(Array(0.7, 0.3)) 
val (trainingData, testData) = (splits(0), splits(1)) 

// Train a GBT model. 
val boostingStrategy = BoostingStrategy.defaultParams("Classification") 
boostingStrategy.numIterations = 50 
boostingStrategy.treeStrategy.numClasses = 2 
boostingStrategy.treeStrategy.maxDepth = 6 
boostingStrategy.treeStrategy.categoricalFeaturesInfo = Map[Int, Int]() 

val model = GradientBoostedTrees.train(trainingData, boostingStrategy) 

// Get class label from raw predict function 
val predictedLabels = model.predict(testData.map(_.features)) 
predictedLabels.collect 

// Get class probability 
val treePredictions = testData.map { point => model.trees.map(_.predict(point.features)) } 
val treePredictionsVector = treePredictions.map(array => Vectors.dense(array)) 
val treePredictionsMatrix = new RowMatrix(treePredictionsVector) 
val learningRate = model.treeWeights 
val learningRateMatrix = Matrices.dense(learningRate.size, 1, learningRate) 
val weightedTreePredictions = treePredictionsMatrix.multiply(learningRateMatrix) 
val classProb = weightedTreePredictions.rows.flatMap(_.toArray).map(x => 1/(1 + Math.exp(-1 * x))) 
val classLabel = classProb.map(x => if (x > 0.5) 1.0 else 0.0) 
classLabel.collect 
0

वास्तव में, उपर्युक्त उत्तर गलत है, इस स्थिति में स्पार्क अनुवाद लेबल के लिए सिग्मोइड फ़ंक्शन झूठा है {-1,1}।

def score(features: Vector,gbdt: GradientBoostedTreesModel): Double = { 
    val treePredictions = gbdt.trees.map(_.predict(features)) 
    blas.ddot(gbdt.numTrees, treePredictions, 1, gbdt.treeWeights, 1) 
} 
val labelAndPreds = testData.map { point => 
     var prediction = score(point.features,model) 
     prediction = 1.0/(1.0 + math.exp(-2.0 * prediction)) 
     (point.label, Vectors.dense(1.0-prediction, prediction)) 
} 

और अधिक विस्तार के पेज 9 में देखा जा सकता "लालची समारोह सन्निकटन एक ढाल बढ़ाने मशीन?": आप इस तरह एक कोड का उपयोग करना चाहिए। और स्पार्क में एक पुल अनुरोध: https://github.com/apache/spark/pull/16441

संबंधित मुद्दे