From 8f10a7c6ca883ca06318ff85aea98012e5ad30b3 Mon Sep 17 00:00:00 2001 From: David Kyle Date: Fri, 7 Feb 2020 10:07:18 +0000 Subject: [PATCH] [ML] Make Ensemble feature names optional (#51996) The featureNames field is requisite in individual models but is not required by the Ensemble. --- .../ml/inference/trainedmodel/ensemble/Ensemble.java | 4 ++-- .../ml/inference/trainedmodel/ensemble/EnsembleTests.java | 2 +- docs/reference/ml/df-analytics/apis/put-inference.asciidoc | 4 ++-- .../core/ml/inference/trainedmodel/ensemble/Ensemble.java | 7 +++++-- .../ml/inference/trainedmodel/ensemble/EnsembleTests.java | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/inference/trainedmodel/ensemble/Ensemble.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/inference/trainedmodel/ensemble/Ensemble.java index 60ffde6e35f..45d8afb32e6 100644 --- a/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/inference/trainedmodel/ensemble/Ensemble.java +++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/ml/inference/trainedmodel/ensemble/Ensemble.java @@ -103,7 +103,7 @@ public class Ensemble implements TrainedModel { @Override public XContentBuilder toXContent(XContentBuilder builder, ToXContent.Params params) throws IOException { builder.startObject(); - if (featureNames != null) { + if (featureNames != null && featureNames.isEmpty() == false) { builder.field(FEATURE_NAMES.getPreferredName(), featureNames); } if (models != null) { @@ -157,7 +157,7 @@ public class Ensemble implements TrainedModel { } public static class Builder { - private List featureNames; + private List featureNames = Collections.emptyList(); private List trainedModels; private OutputAggregator outputAggregator; private TargetType targetType; diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/inference/trainedmodel/ensemble/EnsembleTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/inference/trainedmodel/ensemble/EnsembleTests.java index a0470ea2500..318d390de7c 100644 --- a/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/inference/trainedmodel/ensemble/EnsembleTests.java +++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/ml/inference/trainedmodel/ensemble/EnsembleTests.java @@ -86,7 +86,7 @@ public class EnsembleTests extends AbstractXContentTestCase { .toArray() : null; - return new Ensemble(featureNames, + return new Ensemble(randomBoolean() ? featureNames : Collections.emptyList(), models, outputAggregator, targetType, diff --git a/docs/reference/ml/df-analytics/apis/put-inference.asciidoc b/docs/reference/ml/df-analytics/apis/put-inference.asciidoc index c6a4781e6d9..44ccfc445b8 100644 --- a/docs/reference/ml/df-analytics/apis/put-inference.asciidoc +++ b/docs/reference/ml/df-analytics/apis/put-inference.asciidoc @@ -150,7 +150,7 @@ See <> for more details. The definition for a binary decision tree. `tree`.`feature_names`::: -(Required, string) +(Required, string) Features expected by the tree, in their expected order. `tree`.`tree_structure`::: @@ -221,7 +221,7 @@ children). The definition for an ensemble model. `ensemble`.`feature_names`::: -(Required, string) +(Optional, string) Features expected by the ensemble, in their expected order. `ensemble`.`trained_models`::: diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/inference/trainedmodel/ensemble/Ensemble.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/inference/trainedmodel/ensemble/Ensemble.java index aad85143f39..8539d0fcc5f 100644 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/inference/trainedmodel/ensemble/Ensemble.java +++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/ml/inference/trainedmodel/ensemble/Ensemble.java @@ -207,7 +207,9 @@ public class Ensemble implements LenientlyParsedTrainedModel, StrictlyParsedTrai @Override public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { builder.startObject(); - builder.field(FEATURE_NAMES.getPreferredName(), featureNames); + if (featureNames.isEmpty() == false) { + builder.field(FEATURE_NAMES.getPreferredName(), featureNames); + } NamedXContentObjectHelper.writeNamedObjects(builder, params, true, TRAINED_MODELS.getPreferredName(), models); NamedXContentObjectHelper.writeNamedObjects(builder, params, @@ -327,8 +329,9 @@ public class Ensemble implements LenientlyParsedTrainedModel, StrictlyParsedTrai private double[] classificationWeights; private boolean modelsAreOrdered; - private Builder (boolean modelsAreOrdered) { + private Builder(boolean modelsAreOrdered) { this.modelsAreOrdered = modelsAreOrdered; + this.featureNames = Collections.emptyList(); } private static Builder builderForParser() { diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/inference/trainedmodel/ensemble/EnsembleTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/inference/trainedmodel/ensemble/EnsembleTests.java index 195ab3cf2b9..a4833da6933 100644 --- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/inference/trainedmodel/ensemble/EnsembleTests.java +++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/ml/inference/trainedmodel/ensemble/EnsembleTests.java @@ -92,7 +92,7 @@ public class EnsembleTests extends AbstractSerializingTestCase { .toArray() : null; - return new Ensemble(featureNames, + return new Ensemble(randomBoolean() ? featureNames : Collections.emptyList(), models, outputAggregator, targetType,