[Python] कार्य से जावा / स्कला समारोह को कॉल करना


Answers

Question

पृष्ठभूमि

मेरा मूल प्रश्न यहां बताया गया था कि डिज़िशनट्रीमोडेल का प्रयोग क्यों किया जा रहा है। और एमएलबीबी के साथ स्पार्क पर ट्यूप्ले (मूल लाले, भविष्यवाणी की गई लेबल) को कैसे उत्पन्न किया जाता है?

जब हम स्काला एपीआई का उपयोग करते हैं तो RDD[LabeledPoint] लिए पूर्वानुमान तय करने का एक अनुशंसित तरीका DecisionTreeModel RDD[LabeledPoint] का उपयोग करना है, ताकि वह केवल RDD पर मैप कर RDD[LabeledPoint] :

val labelAndPreds = testData.map { point =>
  val prediction = model.predict(point.features)
  (point.label, prediction)
}

दुर्भाग्य से PySpark में समान दृष्टिकोण बहुत अच्छा काम नहीं करता है:

labelsAndPredictions = testData.map(
    lambda lp: (lp.label, model.predict(lp.features))
labelsAndPredictions.first()

अपवाद: ऐसा प्रतीत होता है कि आप स्पर्क कॉन्टैक्ट को किसी प्रसारण वेरिएबल, एक्शन या ट्रांसफॉर्ममेंट से संदर्भित करने का प्रयास कर रहे हैं। स्पार्ककॉन्टेक्स्ट का इस्तेमाल केवल चालक पर ही किया जा सकता है, कोड में नहीं, जो कि श्रमिकों पर चलता है। अधिक जानकारी के लिए, SPARK-5063 देखें।

उस आधिकारिक दस्तावेज के बजाय कुछ ऐसा सुझाव दिया जाता है:

predictions = model.predict(testData.map(lambda x: x.features))
labelsAndPredictions = testData.map(lambda lp: lp.label).zip(predictions)

तो यहां पर क्या हो रहा है? यहां कोई प्रसारण चर नहीं है और स्काला एपीआई predict को परिभाषित करता है:

/**
 * Predict values for a single data point using the model trained.
 *
 * @param features array representing a single data point
 * @return Double prediction from the trained model
 */
def predict(features: Vector): Double = {
  topNode.predict(features)
}

/**
 * Predict values for the given data set using the model trained.
 *
 * @param features RDD representing data points to be predicted
 * @return RDD of predictions for each of the given data points
 */
def predict(features: RDD[Vector]): RDD[Double] = {
  features.map(x => predict(x))
}

इसलिए कम से कम कार्रवाई या परिवर्तन से बुला रही पहली नज़र में कोई समस्या नहीं है क्योंकि भविष्यवाणी एक स्थानीय ऑपरेशन लगता है

व्याख्या

कुछ खुदाई के बाद मुझे पता चला कि समस्या का स्रोत एक JavaModelWrapper.call विधि है जो कि DecisionTreeModel.predict से लागू होता है। यह SparkContext एक्सेस है, जिसे जावा फ़ंक्शन पर कॉल करना आवश्यक है:

callJavaFunc(self._sc, getattr(self._java_model, name), *a)

सवाल

DecisionTreeModel.predict मामले में एक अनुशंसित समाधान है और सभी आवश्यक कोड पहले से ही स्काला एपीआई का एक हिस्सा है लेकिन सामान्य रूप से इस तरह की समस्या को निपटाने के लिए कोई शानदार तरीका है?

केवल समाधान मैं अभी सोच सकता है बल्कि हेवीवेट हैं:

  • सब कुछ नीचे JVM या तो स्पष्ट रूपांतरणों के माध्यम से स्पार्क कक्षाएं बढ़ाकर या किसी प्रकार के रैपर को जोड़कर
  • सीधे Py4j प्रवेश द्वार का उपयोग कर