fix: make EnsembleByKey transformSchema match output#2575
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
Hey @fallintoplace 👋! We use semantic commit messages to streamline the release process. Examples of commit messages with semantic prefixes:
To test your commit locally, please follow our guild on building from source. |
There was a problem hiding this comment.
Pull request overview
This PR updates EnsembleByKey’s transformSchema logic so it matches the actual output schema produced by transform, across both collapseGroup=true and collapseGroup=false modes, and adds a regression test to validate schema consistency.
Changes:
- Rebuild
transformSchemaoutput fields usingkeysfor grouping fields and consistent output ordering for both collapse modes. - In non-collapsing mode, model Spark join column ordering and drop/replace conflicting output column names in the predicted schema.
- Add a test asserting
transformSchema(schema)equalstransform(df).schemafor both collapse modes.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| core/src/main/scala/com/microsoft/azure/synapse/ml/stages/EnsembleByKey.scala | Adjusts transformSchema field selection and ordering to align with transform behavior. |
| core/src/test/scala/com/microsoft/azure/synapse/ml/stages/EnsembleByKeySuite.scala | Adds schema-equality coverage for both collapseGroup modes. |
| val aggregateFields = getCols.zip(getColNames).map { case (inputName, outputName) => | ||
| val inputField = schema(inputName) | ||
| inputField.dataType match { | ||
| case _: DoubleType => StructField(outputName, inputField.dataType) | ||
| case _: FloatType => StructField(outputName, inputField.dataType) |
| val scoreDF = spark.createDataFrame( | ||
| Seq((0, "foo", 1.0), | ||
| (1, "bar", 4.0), | ||
| (1, "bar", 0.0))) | ||
| .toDF("id", "group", "score") | ||
|
|
||
| Seq(true, false).foreach { collapseGroup => | ||
| val transformer = new EnsembleByKey() | ||
| .setKey("group") | ||
| .setCol("score") | ||
| .setColName("averageScore") | ||
| .setCollapseGroup(collapseGroup) | ||
| val transformed = transformer.transform(scoreDF) | ||
|
|
||
| assert(transformed.schema === transformer.transformSchema(scoreDF.schema)) | ||
| } |
32aee3b to
0f15e8c
Compare
0f15e8c to
bdc39f9
Compare
Problem
EnsembleByKey.transformSchemadescribes the opposite shape fromtransform:collapseGroup=true,transformreturns grouping keys and aggregate columns, whiletransformSchemakeeps every input columncollapseGroup=false,transformjoins aggregates back to the input, whiletransformSchemakeeps only fields selected from the aggregation column setThis can break pipeline schema validation because the declared schema differs from the DataFrame produced at runtime. The old implementation also fails when
transformSchemais called beforetransformwithout explicitcolNames, and declaresFloatTypefor scalar means that Spark produces asDoubleType.Changes
transformandtransformSchemakeysDoubleTypefor both float and double inputsTesting
core/testOnly com.microsoft.azure.synapse.ml.stages.EnsembleByKeySuite(9 tests passed)core/Test/scalastyle(0 findings)core/Compile/scalastyle(0 findings)