What happened?
MachineLearningScorerOpDesc.getSelectedMetrics() returns the chosen metric names as one comma-separated, already-quoted fragment, and its return type is EncodableString:
common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/machineLearning/Scorer/MachineLearningScorerOpDesc.scala
private def getSelectedMetrics(): EncodableString = {
val metric = if (isRegression) regressionMetrics else classificationMetrics
metric.map(metric => getMetricName(metric)).mkString("'", "','", "'") // -> 'Accuracy','F1 Score'
}
It is spliced into the generated Python as a list:
metric_list = [${getSelectedMetrics()}]
Because the value is an EncodableString, the Python template builder re-encodes the whole fragment as one Python string value (rendered via self.decode_python_template(...)) instead of splicing it verbatim. The generated code becomes:
metric_list = ["'Accuracy','F1 Score'"] # ONE element: the literal string, incl. inner quotes
instead of the intended:
metric_list = ['Accuracy', 'F1 Score']
So every downstream if 'X' in metric_list and for metric in metric_list / metrics_func[metric] operates on that single malformed element — the selected metrics are never matched, and the classification path hits a KeyError on the bogus key. The Scorer produces wrong/empty output for both the classification and regression paths.
Expected: metric_list is a proper list of metric names and each selected metric is computed.
How to reproduce?
A — user-facing: Add a Machine Learning Scorer operator, select one or more metrics (e.g. Accuracy, F1 Score), give it prediction/label columns, and run. The selected metrics are not computed correctly (empty result / KeyError).
B — confirmed against main's operator directly: construct MachineLearningScorerOpDesc with isRegression = false and classificationMetrics = List(accuracy, f1Score), then call generatePythonCode(). The emitted line is:
metric_list = [self.decode_python_template('J0FjY3VyYWN5JywnRjEgU2NvcmUn')]
The base64 J0FjY3VyYWN5JywnRjEgU2NvcmUn decodes to 'Accuracy','F1 Score' — i.e. the entire quoted list collapses into a single decoded string element, so metric_list has one malformed entry rather than two metric names.
Proposed fix: change getSelectedMetrics()'s return type from EncodableString to plain String, so the builder splices it verbatim into metric_list = ['Accuracy','F1 Score']. The method body is unchanged.
Version/Branch
1.3.0-incubating-SNAPSHOT (main)
Commit Hash (Optional)
No response
What browsers are you seeing the problem on?
No response
Relevant log output
What happened?
MachineLearningScorerOpDesc.getSelectedMetrics()returns the chosen metric names as one comma-separated, already-quoted fragment, and its return type isEncodableString:common/workflow-operator/src/main/scala/org/apache/texera/amber/operator/machineLearning/Scorer/MachineLearningScorerOpDesc.scalaIt is spliced into the generated Python as a list:
Because the value is an
EncodableString, the Python template builder re-encodes the whole fragment as one Python string value (rendered viaself.decode_python_template(...)) instead of splicing it verbatim. The generated code becomes:instead of the intended:
So every downstream
if 'X' in metric_listandfor metric in metric_list/metrics_func[metric]operates on that single malformed element — the selected metrics are never matched, and the classification path hits aKeyErroron the bogus key. The Scorer produces wrong/empty output for both the classification and regression paths.Expected:
metric_listis a proper list of metric names and each selected metric is computed.How to reproduce?
A — user-facing: Add a Machine Learning Scorer operator, select one or more metrics (e.g. Accuracy, F1 Score), give it prediction/label columns, and run. The selected metrics are not computed correctly (empty result /
KeyError).B — confirmed against
main's operator directly: constructMachineLearningScorerOpDescwithisRegression = falseandclassificationMetrics = List(accuracy, f1Score), then callgeneratePythonCode(). The emitted line is:The base64
J0FjY3VyYWN5JywnRjEgU2NvcmUndecodes to'Accuracy','F1 Score'— i.e. the entire quoted list collapses into a single decoded string element, sometric_listhas one malformed entry rather than two metric names.Proposed fix: change
getSelectedMetrics()'s return type fromEncodableStringto plainString, so the builder splices it verbatim intometric_list = ['Accuracy','F1 Score']. The method body is unchanged.Version/Branch
1.3.0-incubating-SNAPSHOT (main)
Commit Hash (Optional)
No response
What browsers are you seeing the problem on?
No response
Relevant log output