def test_sort_eligible_features(self): features_list = [{'name': 'feat1'}, {'name': 'feat2'}] chart_data = { 'feat1': { 'chartType': 'numeric', 'data': [[ { 'series1': [{ 'scalar': .2 }, { 'scalar': .1 }, { 'scalar': .3 }] }, { 'series2': [{ 'scalar': .2 }, { 'scalar': .1 }, { 'scalar': .4 }] }, ]] }, 'feat2': { 'chartType': 'categorical', 'data': [[ { 'series1': [{ 'scalar': .2 }, { 'scalar': .1 }, { 'scalar': .3 }] }, { 'series2': [{ 'scalar': .2 }, { 'scalar': .1 }, { 'scalar': .9 }] }, ]] } } sorted_list = inference_utils.sort_eligible_features( features_list, chart_data) print(sorted_list) self.assertEqual('feat2', sorted_list[0]['name']) self.assertEqual(.8, sorted_list[0]['interestingness']) self.assertEqual('feat1', sorted_list[1]['name']) self.assertEqual(.4, sorted_list[1]['interestingness'])
def _sort_eligible_features_handler(self, request): """Returns a sorted list of JSON objects for each feature in the example. The list is sorted by interestingness in terms of the resulting change in inference values across feature values, for partial dependence plots. Args: request: A request for sorted features. Returns: A sorted list with a JSON object for each feature. Numeric features are represented as {name: observedMin: observedMax: interestingness:}. Categorical features are repesented as {name: samples:[] interestingness:}. """ try: features_list = inference_utils.get_eligible_features( self.examples[0:NUM_EXAMPLES_TO_SCAN], NUM_MUTANTS) example_index = int(request.args.get('example_index', '0')) (inference_addresses, model_names, model_versions, model_signatures) = self._parse_request_arguments(request) chart_data = {} for feat in features_list: chart_data[feat['name']] = self._infer_mutants_impl( feat['name'], example_index, inference_addresses, model_names, request.args.get('model_type'), model_versions, model_signatures, request.args.get('use_predict') == 'true', request.args.get('predict_input_tensor'), request.args.get('predict_output_tensor'), feat['observedMin'] if 'observedMin' in feat else 0, feat['observedMax'] if 'observedMin' in feat else 0, None, custom_predict_fn=self.custom_predict_fn) features_list = inference_utils.sort_eligible_features( features_list, chart_data) return http_util.Respond(request, features_list, 'application/json') except common_utils.InvalidUserInputError as e: return http_util.Respond(request, e.message, 'application/json', code=400) except Exception as e: return http_util.Respond(request, str(e), 'application/json', code=400)
def sort_eligible_features_impl(self, info): """Returns sorted list of interesting features for mutant inference.""" features_list = info['features'] chart_data = {} for feat in features_list: chart_data[feat['name']] = self.infer_mutants_impl({ 'x_min': feat['observedMin'] if 'observedMin' in feat else 0, 'x_max': feat['observedMax'] if 'observedMin' in feat else 0, 'feature_index_pattern': None, 'feature_name': feat['name'], 'example_index': info['example_index'], }) return inference_utils.sort_eligible_features( features_list, chart_data)