[python] किसी कार्य से जावा / स्कैला फ़ंक्शन को कॉल करना


Answers

Question

पृष्ठभूमि

मेरा मूल सवाल यह था कि मानचित्र फ़ंक्शन के अंदर DecisionTreeModel.predict का उपयोग क्यों अपवाद उठाता है? और एमएलआईबीआईबी के साथ स्पार्क पर (मूल योग्य, अनुमानित लेबल) के tuples उत्पन्न करने के तरीके से संबंधित है ?

जब हम RDD[LabeledPoint] का उपयोग करते हैं तो RDD[LabeledPoint] का उपयोग करके RDD[LabeledPoint] लिए पूर्वानुमान प्राप्त करने का एक अनुशंसित तरीका 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 access SparkContext जिसे जावा फ़ंक्शन को कॉल करने की आवश्यकता होती है:

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

सवाल

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

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

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





Related