From 467028db2937e59ae62442bf5398711c98cd6227 Mon Sep 17 00:00:00 2001 From: Adrien Ball Date: Mon, 6 May 2019 17:16:41 +0200 Subject: [PATCH] Accept ambiguous results from DeterministicIntentParser when confidence score is above 0.5 (#797) --- CHANGELOG.md | 1 + .../deterministic_intent_parser.py | 2 +- .../tests/test_deterministic_intent_parser.py | 46 ++++++++++++++++--- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87bcacd23..ad50985f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Changed - Re-score ambiguous `DeterministicIntentParser` results based on slots [#791](https://github.com/snipsco/snips-nlu/pull/791) +- Accept ambiguous results from `DeterministicIntentParser` when confidence score is above 0.5 [#797](https://github.com/snipsco/snips-nlu/pull/797) ## [0.19.6] ### Fixed diff --git a/snips_nlu/intent_parser/deterministic_intent_parser.py b/snips_nlu/intent_parser/deterministic_intent_parser.py index d683cb708..496c49ea1 100644 --- a/snips_nlu/intent_parser/deterministic_intent_parser.py +++ b/snips_nlu/intent_parser/deterministic_intent_parser.py @@ -203,7 +203,7 @@ def parse(self, text, intents=None, top_n=None): if top_intents: intent = top_intents[0][RES_INTENT] slots = top_intents[0][RES_SLOTS] - if intent[RES_PROBA] < 1.0: + if intent[RES_PROBA] <= 0.5: # return None in case of ambiguity return empty_result(text, probability=1.0) return parsing_result(text, intent, slots) diff --git a/snips_nlu/tests/test_deterministic_intent_parser.py b/snips_nlu/tests/test_deterministic_intent_parser.py index fff82927b..a01305eb0 100644 --- a/snips_nlu/tests/test_deterministic_intent_parser.py +++ b/snips_nlu/tests/test_deterministic_intent_parser.py @@ -17,7 +17,7 @@ from snips_nlu.pipeline.configs import DeterministicIntentParserConfig from snips_nlu.result import ( extraction_result, intent_classification_result, unresolved_slot, - empty_result) + empty_result, parsing_result) from snips_nlu.tests.utils import FixtureTest, TEST_PATH @@ -244,7 +244,7 @@ def test_should_parse_intent_with_duplicated_slot_names(self): self.assertDictEqual(expected_intent, parsing[RES_INTENT]) self.assertListEqual(expected_slots, parsing[RES_SLOTS]) - def test_should_ignore_ambiguous_utterances(self): + def test_should_ignore_completely_ambiguous_utterances(self): # Given dataset_stream = io.StringIO(""" --- @@ -268,23 +268,30 @@ def test_should_ignore_ambiguous_utterances(self): # Then self.assertEqual(empty_result(text, 1.0), res) - def test_should_ignore_subtly_ambiguous_utterances(self): + def test_should_ignore_very_ambiguous_utterances(self): # Given dataset_stream = io.StringIO(""" --- type: intent name: intent_1 utterances: - - meeting tomorrow + - "[event_type](meeting) tomorrow" --- type: intent name: intent_2 utterances: - - meeting [time:snips/datetime](today)""") + - call [time:snips/datetime](today) + +--- +type: entity +name: event_type +values: + - call + - diner""") dataset = Dataset.from_yaml_files("en", [dataset_stream]).json parser = DeterministicIntentParser().fit(dataset) - text = "meeting tomorrow" + text = "call tomorrow" # When res = parser.parse(text) @@ -292,6 +299,33 @@ def test_should_ignore_subtly_ambiguous_utterances(self): # Then self.assertEqual(empty_result(text, 1.0), res) + def test_should_parse_slightly_ambiguous_utterances(self): + # Given + dataset_stream = io.StringIO(""" +--- +type: intent +name: intent_1 +utterances: + - call tomorrow + +--- +type: intent +name: intent_2 +utterances: + - call [time:snips/datetime](today)""") + dataset = Dataset.from_yaml_files("en", [dataset_stream]).json + parser = DeterministicIntentParser().fit(dataset) + text = "call tomorrow" + + # When + res = parser.parse(text) + + # Then + expected_intent = intent_classification_result( + intent_name="intent_1", probability=2. / 3.) + expected_result = parsing_result(text, expected_intent, []) + self.assertEqual(expected_result, res) + def test_should_not_parse_when_not_fitted(self): # Given parser = DeterministicIntentParser()