diff --git a/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifier.java b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifier.java index 4b0f6a4fd1f..3d191b5ff3b 100644 --- a/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifier.java +++ b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifier.java @@ -16,8 +16,10 @@ import com.ibm.watson.developer_cloud.http.RequestBuilder; import com.ibm.watson.developer_cloud.http.ServiceCall; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.Classification; +import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassificationCollection; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.Classifier; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifierList; +import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifyCollectionOptions; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifyOptions; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.CreateClassifierOptions; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.DeleteClassifierOptions; @@ -94,6 +96,27 @@ public ServiceCall classify(ClassifyOptions classifyOptions) { return createServiceCall(builder.build(), ResponseConverterUtils.getObject(Classification.class)); } + /** + * Classify multiple phrases. + * + * Returns label information for multiple phrases. The status must be `Available` before you can use the classifier to + * classify text. Note that classifying Japanese texts is a beta feature. + * + * @param classifyCollectionOptions the {@link ClassifyCollectionOptions} containing the options for the call + * @return a {@link ServiceCall} with a response type of {@link ClassificationCollection} + */ + public ServiceCall classifyCollection(ClassifyCollectionOptions classifyCollectionOptions) { + Validator.notNull(classifyCollectionOptions, "classifyCollectionOptions cannot be null"); + String[] pathSegments = { "v1/classifiers", "classify_collection" }; + String[] pathParameters = { classifyCollectionOptions.classifierId() }; + RequestBuilder builder = RequestBuilder.post(RequestBuilder.constructHttpUrl(getEndPoint(), pathSegments, + pathParameters)); + final JsonObject contentJson = new JsonObject(); + contentJson.add("collection", GsonSingleton.getGson().toJsonTree(classifyCollectionOptions.collection())); + builder.bodyJson(contentJson); + return createServiceCall(builder.build(), ResponseConverterUtils.getObject(ClassificationCollection.class)); + } + /** * Create classifier. * diff --git a/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassificationCollection.java b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassificationCollection.java new file mode 100644 index 00000000000..c47ef4fe6e4 --- /dev/null +++ b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassificationCollection.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018 IBM Corp. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.ibm.watson.developer_cloud.natural_language_classifier.v1.model; + +import java.util.List; + +import com.google.gson.annotations.SerializedName; +import com.ibm.watson.developer_cloud.service.model.GenericModel; + +/** + * Response from the classifier for multiple phrases. + */ +public class ClassificationCollection extends GenericModel { + + @SerializedName("classifier_id") + private String classifierId; + private String url; + private List collection; + + /** + * Gets the classifierId. + * + * Unique identifier for this classifier. + * + * @return the classifierId + */ + public String getClassifierId() { + return classifierId; + } + + /** + * Gets the url. + * + * Link to the classifier. + * + * @return the url + */ + public String getUrl() { + return url; + } + + /** + * Gets the collection. + * + * An array of classifier responses for each submitted phrase. + * + * @return the collection + */ + public List getCollection() { + return collection; + } +} diff --git a/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassifyCollectionOptions.java b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassifyCollectionOptions.java new file mode 100644 index 00000000000..ae4f5df6559 --- /dev/null +++ b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassifyCollectionOptions.java @@ -0,0 +1,143 @@ +/* + * Copyright 2018 IBM Corp. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.ibm.watson.developer_cloud.natural_language_classifier.v1.model; + +import java.util.ArrayList; +import java.util.List; + +import com.ibm.watson.developer_cloud.service.model.GenericModel; +import com.ibm.watson.developer_cloud.util.Validator; + +/** + * The classifyCollection options. + */ +public class ClassifyCollectionOptions extends GenericModel { + + private String classifierId; + private List collection; + + /** + * Builder. + */ + public static class Builder { + private String classifierId; + private List collection; + + private Builder(ClassifyCollectionOptions classifyCollectionOptions) { + classifierId = classifyCollectionOptions.classifierId; + collection = classifyCollectionOptions.collection; + } + + /** + * Instantiates a new builder. + */ + public Builder() { + } + + /** + * Instantiates a new builder with required properties. + * + * @param classifierId the classifierId + * @param collection the collection + */ + public Builder(String classifierId, List collection) { + this.classifierId = classifierId; + this.collection = collection; + } + + /** + * Builds a ClassifyCollectionOptions. + * + * @return the classifyCollectionOptions + */ + public ClassifyCollectionOptions build() { + return new ClassifyCollectionOptions(this); + } + + /** + * Adds an classifyInput to collection. + * + * @param classifyInput the new classifyInput + * @return the ClassifyCollectionOptions builder + */ + public Builder addClassifyInput(ClassifyInput classifyInput) { + Validator.notNull(classifyInput, "classifyInput cannot be null"); + if (this.collection == null) { + this.collection = new ArrayList(); + } + this.collection.add(classifyInput); + return this; + } + + /** + * Set the classifierId. + * + * @param classifierId the classifierId + * @return the ClassifyCollectionOptions builder + */ + public Builder classifierId(String classifierId) { + this.classifierId = classifierId; + return this; + } + + /** + * Set the collection. + * Existing collection will be replaced. + * + * @param collection the collection + * @return the ClassifyCollectionOptions builder + */ + public Builder collection(List collection) { + this.collection = collection; + return this; + } + } + + private ClassifyCollectionOptions(Builder builder) { + Validator.notEmpty(builder.classifierId, "classifierId cannot be empty"); + Validator.notNull(builder.collection, "collection cannot be null"); + classifierId = builder.classifierId; + collection = builder.collection; + } + + /** + * New builder. + * + * @return a ClassifyCollectionOptions builder + */ + public Builder newBuilder() { + return new Builder(this); + } + + /** + * Gets the classifierId. + * + * Classifier ID to use. + * + * @return the classifierId + */ + public String classifierId() { + return classifierId; + } + + /** + * Gets the collection. + * + * The submitted phrases. + * + * @return the collection + */ + public List collection() { + return collection; + } +} diff --git a/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassifyInput.java b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassifyInput.java new file mode 100644 index 00000000000..1730425994c --- /dev/null +++ b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/ClassifyInput.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 IBM Corp. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.ibm.watson.developer_cloud.natural_language_classifier.v1.model; + +import com.ibm.watson.developer_cloud.service.model.GenericModel; + +/** + * Request payload to classify. + */ +public class ClassifyInput extends GenericModel { + + private String text; + + /** + * Gets the text. + * + * The submitted phrase. + * + * @return the text + */ + public String getText() { + return text; + } + + /** + * Sets the text. + * + * @param text the new text + */ + public void setText(final String text) { + this.text = text; + } +} diff --git a/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/CollectionItem.java b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/CollectionItem.java new file mode 100644 index 00000000000..e8d1cd627e7 --- /dev/null +++ b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/CollectionItem.java @@ -0,0 +1,62 @@ +/* + * Copyright 2018 IBM Corp. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on + * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the + * specific language governing permissions and limitations under the License. + */ +package com.ibm.watson.developer_cloud.natural_language_classifier.v1.model; + +import java.util.List; + +import com.google.gson.annotations.SerializedName; +import com.ibm.watson.developer_cloud.service.model.GenericModel; + +/** + * Response from the classifier for a phrase in a collection. + */ +public class CollectionItem extends GenericModel { + + private String text; + @SerializedName("top_class") + private String topClass; + private List classes; + + /** + * Gets the text. + * + * The submitted phrase. + * + * @return the text + */ + public String getText() { + return text; + } + + /** + * Gets the topClass. + * + * The class with the highest confidence. + * + * @return the topClass + */ + public String getTopClass() { + return topClass; + } + + /** + * Gets the classes. + * + * An array of up to ten class-confidence pairs sorted in descending order of confidence. + * + * @return the classes + */ + public List getClasses() { + return classes; + } +} diff --git a/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/CreateClassifierOptions.java b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/CreateClassifierOptions.java index 971098f7646..81b7f0f5df7 100644 --- a/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/CreateClassifierOptions.java +++ b/natural-language-classifier/src/main/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/model/CreateClassifierOptions.java @@ -167,7 +167,9 @@ public Builder newBuilder() { * Gets the metadata. * * Metadata in JSON format. The metadata identifies the language of the data, and an optional name to identify the - * classifier. + * classifier. Specify the language with the 2-letter primary language code as assigned in ISO standard 639. Supported + * languages are English (`en`), Arabic (`ar`), French (`fr`), German, (`de`), Italian (`it`), Japanese (`ja`), Korean + * (`ko`), Brazilian Portuguese (`pt`), and Spanish (`es`). * * @return the metadata */ @@ -189,9 +191,9 @@ public String metadataFilename() { /** * Gets the trainingData. * - * Training data in CSV format. Each text value must have at least one class. The data can include up to 15,000 - * records. For details, see [Using your own - * data](https://console.bluemix.net/docs/services/natural-language-classifier/using-your-data.html). + * Training data in CSV format. Each text value must have at least one class. The data can include up to 20,000 + * records. For details, see [Data + * preparation](https://console.bluemix.net/docs/services/natural-language-classifier/using-your-data.html). * * @return the trainingData */ diff --git a/natural-language-classifier/src/test/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifierIT.java b/natural-language-classifier/src/test/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifierIT.java index 20781174034..83f8e144cbf 100644 --- a/natural-language-classifier/src/test/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifierIT.java +++ b/natural-language-classifier/src/test/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifierIT.java @@ -14,9 +14,12 @@ import com.ibm.watson.developer_cloud.WatsonServiceTest; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.Classification; +import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassificationCollection; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.Classifier; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.Classifier.Status; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifierList; +import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifyCollectionOptions; +import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifyInput; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifyOptions; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.CreateClassifierOptions; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.DeleteClassifierOptions; @@ -176,4 +179,33 @@ public void eDelete() { } } + /** + * Test classifyCollection. Use the pre created classifier to avoid waiting for availability + */ + @Test + public void fClassifyCollection() { + ClassificationCollection classificationCollection = null; + ClassifyInput input1 = new ClassifyInput(); + input1.setText("How hot will it be today?"); + ClassifyInput input2 = new ClassifyInput(); + input2.setText("Is it hot outside?"); + + try { + ClassifyCollectionOptions classifyOptions = new ClassifyCollectionOptions.Builder() + .classifierId(preCreatedClassifierId) + .addClassifyInput(input1) + .addClassifyInput(input2) + .build(); + classificationCollection = service.classifyCollection(classifyOptions).execute(); + } catch (NotFoundException e) { + // #324: Classifiers may be empty, because of other tests interfering. + // The build should not fail here, because this is out of our control. + throw new AssumptionViolatedException(e.getMessage(), e); + } + + assertNotNull(classificationCollection); + assertEquals("temperature", classificationCollection.getCollection().get(0).getTopClass()); + assertEquals("temperature", classificationCollection.getCollection().get(1).getTopClass()); + } + } diff --git a/natural-language-classifier/src/test/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifierTest.java b/natural-language-classifier/src/test/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifierTest.java index ab0978fe363..d9ba993067e 100644 --- a/natural-language-classifier/src/test/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifierTest.java +++ b/natural-language-classifier/src/test/java/com/ibm/watson/developer_cloud/natural_language_classifier/v1/NaturalLanguageClassifierTest.java @@ -15,8 +15,11 @@ import com.google.gson.JsonObject; import com.ibm.watson.developer_cloud.WatsonServiceUnitTest; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.Classification; +import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassificationCollection; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.Classifier; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifierList; +import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifyCollectionOptions; +import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifyInput; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.ClassifyOptions; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.CreateClassifierOptions; import com.ibm.watson.developer_cloud.natural_language_classifier.v1.model.DeleteClassifierOptions; @@ -27,6 +30,8 @@ import java.io.File; import java.io.FileNotFoundException; +import java.util.Arrays; +import java.util.List; import static org.junit.Assert.assertEquals; @@ -37,11 +42,13 @@ public class NaturalLanguageClassifierTest extends WatsonServiceUnitTest { private static final String TEXT = "text"; private static final String CLASSIFIERS_PATH = "/v1/classifiers"; private static final String CLASSIFY_PATH = "/v1/classifiers/%s/classify"; + private static final String CLASSIFY_COLLECTION_PATH = "/v1/classifiers/%s/classify_collection"; private static final String RESOURCE = "src/test/resources/natural_language_classifier/"; private ClassifierList classifiers; private Classifier classifier; private Classification classification; + private ClassificationCollection classificationCollection; private String classifierId; private NaturalLanguageClassifier service; @@ -62,6 +69,8 @@ public void setUp() throws Exception { classifiers = loadFixture(RESOURCE + "classifiers.json", ClassifierList.class); classifier = loadFixture(RESOURCE + "classifier.json", Classifier.class); classification = loadFixture(RESOURCE + "classification.json", Classification.class); + classificationCollection = loadFixture(RESOURCE + "classification_collection.json", + ClassificationCollection.class); } /** @@ -90,6 +99,35 @@ public void testClassify() throws InterruptedException { assertEquals(classification, result); } + /** + * Test classifying a collection. + * + * @throws InterruptedException the interrupted exception + */ + @Test + public void testClassifyCollection() throws InterruptedException { + final String path = String.format(CLASSIFY_COLLECTION_PATH, classifierId); + + server.enqueue(jsonResponse(classificationCollection)); + + ClassifyInput input1 = new ClassifyInput(); + input1.setText("How hot will it be today?"); + ClassifyInput input2 = new ClassifyInput(); + input2.setText("Is it hot outside?"); + List inputCollection = Arrays.asList(input1, input2); + + ClassifyCollectionOptions classifyOptions = new ClassifyCollectionOptions.Builder() + .classifierId(classifierId) + .collection(inputCollection) + .build(); + final ClassificationCollection result = service.classifyCollection(classifyOptions).execute(); + final RecordedRequest request = server.takeRequest(); + + assertEquals(path, request.getPath()); + assertEquals("POST", request.getMethod()); + assertEquals(classificationCollection, result); + } + /** * Test get classifier. * diff --git a/natural-language-classifier/src/test/resources/natural_language_classifier/classification_collection.json b/natural-language-classifier/src/test/resources/natural_language_classifier/classification_collection.json new file mode 100644 index 00000000000..9ebc67cd830 --- /dev/null +++ b/natural-language-classifier/src/test/resources/natural_language_classifier/classification_collection.json @@ -0,0 +1,25 @@ +{ + "classifier_id" : "10D41B-nlc-1", + "url" : "https://gateway.watsonplatform.net/natural-language-classifier/api/v1/classifiers/10D41B-nlc-1", + "collection" : [ { + "text" : "How hot will it be today?", + "top_class" : "temperature", + "classes" : [ { + "class_name" : "temperature", + "confidence" : 0.9930558798985937 + }, { + "class_name" : "conditions", + "confidence" : 0.006944120101406304 + } ] + }, { + "text" : "Is it hot outside?", + "top_class" : "temperature", + "classes" : [ { + "class_name" : "temperature", + "confidence" : 1 + }, { + "class_name" : "conditions", + "confidence" : 0 + } ] + } ] +} \ No newline at end of file