def classify_hard_rule(state, params, input_type, normalized_answer, fs): """Find the first hard rule that matches.""" best_matched_answer_group = None best_matched_answer_group_index = len(state.interaction.answer_groups) best_matched_rule_spec_index = None best_matched_truth_value = rule_domain.CERTAIN_FALSE_VALUE for (answer_group_index, answer_group) in enumerate( state.interaction.answer_groups): ored_truth_value = rule_domain.CERTAIN_FALSE_VALUE for (rule_spec_index, rule_spec) in enumerate( answer_group.rule_specs): if rule_spec.rule_type != rule_domain.FUZZY_RULE_TYPE: evaluated_truth_value = rule_domain.evaluate_rule( rule_spec, input_type, params, normalized_answer, fs) if evaluated_truth_value > ored_truth_value: ored_truth_value = evaluated_truth_value best_rule_spec_index = rule_spec_index if ored_truth_value == rule_domain.CERTAIN_TRUE_VALUE: best_matched_truth_value = ored_truth_value best_matched_answer_group = answer_group best_matched_answer_group_index = answer_group_index best_matched_rule_spec_index = best_rule_spec_index return { 'outcome': best_matched_answer_group.outcome.to_dict(), 'answer_group_index': best_matched_answer_group_index, 'classification_certainty': best_matched_truth_value, 'rule_spec_index': best_matched_rule_spec_index, } return None
def classify_soft_rule(state, params, input_type, normalized_answer, fs): """Find the maximum soft rule that matches. This is done by ORing (maximizing) all truth values of all rules over all answer groups. The group with the highest truth value is considered the best match. """ best_matched_answer_group = None best_matched_answer_group_index = len(state.interaction.answer_groups) best_matched_rule_spec_index = None best_matched_truth_value = rule_domain.CERTAIN_FALSE_VALUE for (answer_group_index, answer_group) in enumerate( state.interaction.answer_groups): fuzzy_rule_spec_index = answer_group.get_fuzzy_rule_index() if fuzzy_rule_spec_index is not None: fuzzy_rule_spec = answer_group.rule_specs[fuzzy_rule_spec_index] else: fuzzy_rule_spec = None if fuzzy_rule_spec is not None: evaluated_truth_value = rule_domain.evaluate_rule( fuzzy_rule_spec, input_type, params, normalized_answer, fs) if evaluated_truth_value == rule_domain.CERTAIN_TRUE_VALUE: best_matched_truth_value = evaluated_truth_value best_matched_rule_spec_index = fuzzy_rule_spec_index best_matched_answer_group = answer_group best_matched_answer_group_index = answer_group_index return { 'outcome': best_matched_answer_group.outcome.to_dict(), 'answer_group_index': best_matched_answer_group_index, 'classification_certainty': best_matched_truth_value, 'rule_spec_index': best_matched_rule_spec_index, } return None
def classify( exp_id, exp_param_specs, state, handler_name, answer, params): """Normalize the answer and return the first rulespec that it satisfies.""" interaction_instance = interaction_registry.Registry.get_interaction_by_id( state.interaction.id) normalized_answer = interaction_instance.normalize_answer( answer, handler_name) handler = next( h for h in state.interaction.handlers if h.name == handler_name) fs = fs_domain.AbstractFileSystem(fs_domain.ExplorationFileSystem(exp_id)) input_type = interaction_instance.get_handler_by_name( handler_name).obj_type for rule_spec in handler.rule_specs: if rule_domain.evaluate_rule( rule_spec.definition, exp_param_specs, input_type, params, normalized_answer, fs): return rule_spec raise Exception( 'No matching rule found for handler %s. Rule specs are %s.' % ( handler.name, [rule_spec.to_dict() for rule_spec in handler.rule_specs] ) )
def classify(self, state_name, handler_name, answer, params): """Return the first rule that is satisfied by a reader's answer.""" state = self.states[state_name] # Get the widget to determine the input type. generic_handler = widget_registry.Registry.get_widget_by_id( feconf.INTERACTIVE_PREFIX, state.widget.widget_id ).get_handler_by_name(handler_name) handler = next( h for h in state.widget.handlers if h.name == handler_name) fs = fs_domain.AbstractFileSystem( fs_domain.ExplorationFileSystem(self.id)) for rule_spec in handler.rule_specs: if rule_domain.evaluate_rule( rule_spec.definition, self.param_specs, generic_handler.obj_type, params, answer, fs): return rule_spec raise Exception( 'No matching rule found for handler %s. Rule specs are %s.' % ( handler.name, [rule_spec.to_dict() for rule_spec in handler.rule_specs] ) )
def classify_hard_rule(state, params, input_type, normalized_answer, fs): """Find the first hard rule that matches.""" best_matched_answer_group = None best_matched_answer_group_index = len(state.interaction.answer_groups) best_matched_rule_spec_index = None best_matched_truth_value = rule_domain.CERTAIN_FALSE_VALUE for (answer_group_index, answer_group) in enumerate(state.interaction.answer_groups): ored_truth_value = rule_domain.CERTAIN_FALSE_VALUE for (rule_spec_index, rule_spec) in enumerate(answer_group.rule_specs): if rule_spec.rule_type != rule_domain.FUZZY_RULE_TYPE: evaluated_truth_value = rule_domain.evaluate_rule( rule_spec, input_type, params, normalized_answer, fs) if evaluated_truth_value > ored_truth_value: ored_truth_value = evaluated_truth_value best_rule_spec_index = rule_spec_index if ored_truth_value == rule_domain.CERTAIN_TRUE_VALUE: best_matched_truth_value = ored_truth_value best_matched_answer_group = answer_group best_matched_answer_group_index = answer_group_index best_matched_rule_spec_index = best_rule_spec_index return { 'outcome': best_matched_answer_group.outcome.to_dict(), 'answer_group_index': best_matched_answer_group_index, 'classification_certainty': best_matched_truth_value, 'rule_spec_index': best_matched_rule_spec_index, } return None
def classify_soft_rule(state, params, input_type, normalized_answer, fs): """Find the maximum soft rule that matches. This is done by ORing (maximizing) all truth values of all rules over all answer groups. The group with the highest truth value is considered the best match. """ best_matched_answer_group = None best_matched_answer_group_index = len(state.interaction.answer_groups) best_matched_rule_spec_index = None best_matched_truth_value = rule_domain.CERTAIN_FALSE_VALUE for (answer_group_index, answer_group) in enumerate(state.interaction.answer_groups): fuzzy_rule_spec_index = answer_group.get_fuzzy_rule_index() if fuzzy_rule_spec_index is not None: fuzzy_rule_spec = answer_group.rule_specs[fuzzy_rule_spec_index] else: fuzzy_rule_spec = None if fuzzy_rule_spec is not None: evaluated_truth_value = rule_domain.evaluate_rule( fuzzy_rule_spec, input_type, params, normalized_answer, fs) if evaluated_truth_value == rule_domain.CERTAIN_TRUE_VALUE: best_matched_truth_value = evaluated_truth_value best_matched_rule_spec_index = fuzzy_rule_spec_index best_matched_answer_group = answer_group best_matched_answer_group_index = answer_group_index return { 'outcome': best_matched_answer_group.outcome.to_dict(), 'answer_group_index': best_matched_answer_group_index, 'classification_certainty': best_matched_truth_value, 'rule_spec_index': best_matched_rule_spec_index, } return None
def classify(exp_id, state, answer, params): """Normalize the answer and select among the answer groups the group in which the answer best belongs. The best group is decided by finding the first rule best satisfied by the answer. Returns a dict with the following keys: 'outcome': A dict representing the outcome of the answer group matched. 'rule_spec_string': A descriptive string representation of the rule matched. When the default rule is matched, outcome is the default_outcome of the state's interaction and the rule_spec_string is just 'Default.' """ interaction_instance = interaction_registry.Registry.get_interaction_by_id( state.interaction.id) normalized_answer = interaction_instance.normalize_answer(answer) # Find the first group which best matches the given answer. for answer_group in state.interaction.answer_groups: fs = fs_domain.AbstractFileSystem( fs_domain.ExplorationFileSystem(exp_id)) input_type = interaction_instance.answer_type matched_rule_spec = None for rule_spec in answer_group.rule_specs: if rule_domain.evaluate_rule(rule_spec, input_type, params, normalized_answer, fs): matched_rule_spec = rule_spec break if matched_rule_spec is not None: return { 'outcome': answer_group.outcome.to_dict(), 'rule_spec_string': (matched_rule_spec.stringify_classified_rule()) } # If no other groups match, then the default group automatically matches # (if there is one present). if state.interaction.default_outcome is not None: return { 'outcome': state.interaction.default_outcome.to_dict(), 'rule_spec_string': exp_domain.DEFAULT_RULESPEC_STR } raise Exception( 'Something has seriously gone wrong with the exploration. ' 'Oppia does not know what to do with this answer. Please contact the ' 'exploration owner.')
def classify(exp_id, state, answer, params): """Normalize the answer and select among the answer groups the group in which the answer best belongs. The best group is decided by finding the first rule best satisfied by the answer. Returns a dict with the following keys: 'outcome': A dict representing the outcome of the answer group matched. 'rule_spec_string': A descriptive string representation of the rule matched. When the default rule is matched, outcome is the default_outcome of the state's interaction and the rule_spec_string is just 'Default.' """ interaction_instance = interaction_registry.Registry.get_interaction_by_id( state.interaction.id) normalized_answer = interaction_instance.normalize_answer(answer) # Find the first group which best matches the given answer. for answer_group in state.interaction.answer_groups: fs = fs_domain.AbstractFileSystem( fs_domain.ExplorationFileSystem(exp_id)) input_type = interaction_instance.answer_type matched_rule_spec = None for rule_spec in answer_group.rule_specs: if rule_domain.evaluate_rule( rule_spec, input_type, params, normalized_answer, fs): matched_rule_spec = rule_spec break if matched_rule_spec is not None: return { 'outcome': answer_group.outcome.to_dict(), 'rule_spec_string': ( matched_rule_spec.stringify_classified_rule()) } # If no other groups match, then the default group automatically matches # (if there is one present). if state.interaction.default_outcome is not None: return { 'outcome': state.interaction.default_outcome.to_dict(), 'rule_spec_string': exp_domain.DEFAULT_RULESPEC_STR } raise Exception('Something has seriously gone wrong with the exploration. ' 'Oppia does not know what to do with this answer. Please contact the ' 'exploration owner.')
def classify(exploration_id, state_id, handler_name, answer, params): """Return the first rule that is satisfied by a reader's answer.""" exploration = get_exploration_by_id(exploration_id) state = get_state_by_id(exploration_id, state_id) # Get the widget to determine the input type. generic_handler = widget_domain.Registry.get_widget_by_id( feconf.INTERACTIVE_PREFIX, state.widget.widget_id ).get_handler_by_name(handler_name) handler = next(h for h in state.widget.handlers if h.name == handler_name) if generic_handler.input_type is None: return handler.rule_specs[0] else: for rule_spec in handler.rule_specs: if rule_domain.evaluate_rule( rule_spec.definition, exploration.param_specs, generic_handler.input_type, params, answer): return rule_spec raise Exception( 'No matching rule found for handler %s.' % handler.name)
def classify(exp_id, state, answer, params): """Normalize the answer and select among the answer groups the group in which the answer best belongs. The best group is decided by finding the first rule best satisfied by the answer. Returns a dict with the following keys: 'outcome': A dict representing the outcome of the answer group matched. 'rule_spec_string': A descriptive string representation of the rule matched. 'answer_group_index': An index into the answer groups list indicating which one was selected as the group which this answer belongs to. This is equal to the number of answer groups if the default outcome was matched. 'classification_certainty': A normalized value within the range of [0, 1] representing at which confidence level the answer belongs in the chosen answer group. A certainty of 1 means it is the best possible match. A certainty of 0 means it is matched to the default outcome. When the default rule is matched, outcome is the default_outcome of the state's interaction and the rule_spec_string is just 'Default.' """ interaction_instance = interaction_registry.Registry.get_interaction_by_id( state.interaction.id) normalized_answer = interaction_instance.normalize_answer(answer) # Find the first group that satisfactorily matches the given answer. This is # done by ORing (maximizing) all truth values of all rules over all answer # groups. The group with the highest truth value is considered the best # match. best_matched_answer_group = None best_matched_answer_group_index = len(state.interaction.answer_groups) best_matched_rule_spec = None best_matched_truth_value = 0.0 for (i, answer_group) in enumerate(state.interaction.answer_groups): fs = fs_domain.AbstractFileSystem( fs_domain.ExplorationFileSystem(exp_id)) input_type = interaction_instance.answer_type ored_truth_value = 0.0 best_rule_spec = None for rule_spec in answer_group.rule_specs: evaluated_truth_value = rule_domain.evaluate_rule( rule_spec, input_type, params, normalized_answer, fs) if evaluated_truth_value > ored_truth_value: ored_truth_value = evaluated_truth_value best_rule_spec = rule_spec if ored_truth_value > best_matched_truth_value: best_matched_truth_value = ored_truth_value best_matched_rule_spec = best_rule_spec best_matched_answer_group = answer_group best_matched_answer_group_index = i # The best matched group must match above a certain threshold. If no group # meets this requirement, then the default 'group' automatically matches # resulting in the outcome of the answer being the default outcome of the # state. if (best_matched_truth_value >= feconf.DEFAULT_ANSWER_GROUP_CLASSIFICATION_THRESHOLD): return { 'outcome': best_matched_answer_group.outcome.to_dict(), 'rule_spec_string': ( best_matched_rule_spec.stringify_classified_rule()), 'answer_group_index': best_matched_answer_group_index, 'classification_certainty': best_matched_truth_value } elif state.interaction.default_outcome is not None: return { 'outcome': state.interaction.default_outcome.to_dict(), 'rule_spec_string': exp_domain.DEFAULT_RULESPEC_STR, 'answer_group_index': len(state.interaction.answer_groups), 'classification_certainty': 0.0 } raise Exception('Something has seriously gone wrong with the exploration. ' 'Oppia does not know what to do with this answer. Please contact the ' 'exploration owner.')