(self, model_instance, ascending=True, filter_classes=None, n_jobs=-1,
                           progressbar=True, n_samples=5000, method='prediction-variance', scorer_type='default',
                           use_scaling=False)
return importances
Computes feature importance of all features related to a model instance.
        Supports classification, multi-class classification, and regression.


        Parameters
        ----------
        model_instance: skater.model.model.Model subtype
            the machine learning model "prediction" function to explain, such that
            predictions = predict_fn(data).
        ascending: boolean, default True
            Helps with ordering Ascending vs Descending
        filter_classes: array type
            The classes to run partial dependence on. Default None invokes all classes.
            Only used in classification models.
        n_jobs: int
            How many concurrent processes to use. Defaults -1, which grabs as many as are available.
            Use 1 to avoid multiprocessing altogether.
        progressbar: bool
            Whether to display progress. This affects which function we use to operate on the pool
            of processes, where including the progress bar results in 10-20% slowdowns.
        n_samples: int
            How many samples to use when computing importance.
        method: string (default 'prediction-variance'; 'model-scoring' for estimator specific scoring metric
            How to compute feature importance. 'model-scoring' requires Interpretation.training_labels.
            Note this choice should only rarely makes any significant differences
            prediction-variance: mean absolute value of changes in predictions, given perturbations.
            model-scoring: difference in log_loss or MAE of training_labels given perturbations.
        scorer_type: string
            only used when method='model-scoring', and in this case defines which scoring function to use.
            Default value is 'default', which evaluates to:
                regressors: mean absolute error
                classifiers with probabilities: cross entropy
                classifiers without probabilities: f1 score
            See Skater.model.scorers for details.
        use_scaling: bool
            Whether to weight the importance values by the strength of the perturbations.
            Generally doesn't effect results unless n_samples is very small.


        Returns
        -------
        importances : Sorted Series


        References
        ----------
        Wei, Pengfei, Zhenzhou Lu, and Jingwen Song. "Variable Importance Analysis: A Comprehensive Review".
        Reliability Engineering & System Safety 142 (2015): 399-432.

        Examples
        --------

            >>> from skater.model import InMemoryModel
            >>> from skater.core.explanations import Interpretation
            >>> from sklearn.ensemble import RandomForestClassifier
            >>> rf = RandomForestClassifier()
            >>> rf.fit(X,y)
            >>> model = InMemoryModel(rf.predict_proba, examples = X)
            >>> interpreter = Interpretation()
            >>> interpreter.load_data(X)
            >>> interpreter.feature_importance.feature_importance(model)
Computes feature importance of all features related to a model instance.
        Supports classification, multi-class classification, and regression.
Computes feature importance of all features related to a model instance . Supports classification multi - class classification and regression .
def feature_importance(self, model_instance, ascending=True, filter_classes=None, n_jobs=-1,
                           progressbar=True, n_samples=5000, method='prediction-variance', scorer_type='default',
                           use_scaling=False):

        """
        Computes feature importance of all features related to a model instance.
        Supports classification, multi-class classification, and regression.


        Parameters
        ----------
        model_instance: skater.model.model.Model subtype
            the machine learning model "prediction" function to explain, such that
            predictions = predict_fn(data).
        ascending: boolean, default True
            Helps with ordering Ascending vs Descending
        filter_classes: array type
            The classes to run partial dependence on. Default None invokes all classes.
            Only used in classification models.
        n_jobs: int
            How many concurrent processes to use. Defaults -1, which grabs as many as are available.
            Use 1 to avoid multiprocessing altogether.
        progressbar: bool
            Whether to display progress. This affects which function we use to operate on the pool
            of processes, where including the progress bar results in 10-20% slowdowns.
        n_samples: int
            How many samples to use when computing importance.
        method: string (default 'prediction-variance'; 'model-scoring' for estimator specific scoring metric
            How to compute feature importance. 'model-scoring' requires Interpretation.training_labels.
            Note this choice should only rarely makes any significant differences
            prediction-variance: mean absolute value of changes in predictions, given perturbations.
            model-scoring: difference in log_loss or MAE of training_labels given perturbations.
        scorer_type: string
            only used when method='model-scoring', and in this case defines which scoring function to use.
            Default value is 'default', which evaluates to:
                regressors: mean absolute error
                classifiers with probabilities: cross entropy
                classifiers without probabilities: f1 score
            See Skater.model.scorers for details.
        use_scaling: bool
            Whether to weight the importance values by the strength of the perturbations.
            Generally doesn't effect results unless n_samples is very small.


        Returns
        -------
        importances : Sorted Series


        References
        ----------
        Wei, Pengfei, Zhenzhou Lu, and Jingwen Song. "Variable Importance Analysis: A Comprehensive Review".
        Reliability Engineering & System Safety 142 (2015): 399-432.

        Examples
        --------

            >>> from skater.model import InMemoryModel
            >>> from skater.core.explanations import Interpretation
            >>> from sklearn.ensemble import RandomForestClassifier
            >>> rf = RandomForestClassifier()
            >>> rf.fit(X,y)
            >>> model = InMemoryModel(rf.predict_proba, examples = X)
            >>> interpreter = Interpretation()
            >>> interpreter.load_data(X)
            >>> interpreter.feature_importance.feature_importance(model)


        """

        if filter_classes:
            err_msg = "members of filter classes must be" \
                      "members of model_instance.classes." \
                      "Expected members of: {0}\n" \
                      "got: {1}".format(model_instance.target_names,
                                        filter_classes)
            filter_classes = list(filter_classes)
            assert all([i in model_instance.target_names for i in filter_classes]), err_msg

        if n_samples <= self.data_set.n_rows:
            inputs, labels = self.data_set.generate_sample(strategy='random-choice',
                                                           include_y=True,
                                                           sample=True,
                                                           n_samples=n_samples)
        else:
            inputs, labels = self.data_set.X, self.data_set.y

        if method == 'model-scoring' and labels is None:
            raise FeatureImportanceError("If labels are not set, you"
                                         "can only use feature importance methods that do "
                                         "not require ground truth labels")

        original_predictions = model_instance.predict(inputs)
        n_jobs = None if n_jobs < 0 else n_jobs
        predict_fn = model_instance._get_static_predictor()
        
        # Changes made to skater class due to multiprocessing incompatibility with GRPC when using docker
        # Changes begin here

        arg_list = self.data_set.feature_ids
        scorer = model_instance.scorers.get_scorer_function(scorer_type=scorer_type)

        if progressbar:
            self.interpreter.logger.warn("Progress bars slow down runs by 10-20%. For slightly \n"
                                         "faster runs, do progress_bar=False")
            n_iter = len(self.data_set.feature_ids)
            p = ProgressBar(n_iter, units='features')

        fi_func = partial(compute_feature_importance,
                          input_data=inputs,
                          estimator_fn=predict_fn,
                          original_predictions=original_predictions,
                          feature_info=self.data_set.feature_info,
                          feature_names=self.data_set.feature_ids,
                          training_labels=labels,
                          method=method,
                          scaled=use_scaling,
                          scorer=scorer)

        # Multiprocessing results in issues with GRPC when using Docker, using single process
        # More information here: https://github.com/grpc/grpc/blob/master/doc/fork_support.md

        importances = {}
        importance_dicts = []
        for importance in map(fi_func, arg_list):
            importance_dicts.append(importance)
            if progressbar:
                p.animate()

        # Changes end here

        # Original code

        #executor_instance = Pool(n_jobs)
        #arg_list = self.data_set.feature_ids
        #scorer = model_instance.scorers.get_scorer_function(scorer_type=scorer_type)

        #if progressbar:
         #   self.interpreter.logger.warn("Progress bars slow down runs by 10-20%. For slightly \n"
          #                               "faster runs, do progress_bar=False")
           # n_iter = len(self.data_set.feature_ids)
            #p = ProgressBar(n_iter, units='features')
            #mapper = executor_instance.imap
        #else:
            #mapper = executor_instance.map

        #fi_func = partial(compute_feature_importance,
         #                 input_data=inputs,
          #                estimator_fn=predict_fn,
           #               original_predictions=original_predictions,
            #              feature_info=self.data_set.feature_info,
             #             feature_names=self.data_set.feature_ids,
              #            training_labels=labels,
               #           method=method,
                #          scaled=use_scaling,
                 #         scorer=scorer)

        #importances = {}
        #try:
         #   if n_jobs == 1:
          #      raise ValueError("Skipping to single processing")
           # importance_dicts = []
            #for importance in mapper(fi_func, arg_list):
             #   importance_dicts.append(importance)
              #  if progressbar:
               #     p.animate()
        #except:
         #   self.interpreter.logger.warn("Multiprocessing failed, going single process")
          #  importance_dicts = []
           # for importance in map(fi_func, arg_list):
            #    importance_dicts.append(importance)
             #   if progressbar:
              #      p.animate()
        #finally:
         #   executor_instance.close()
          #  executor_instance.join()
           # executor_instance.terminate()

        for i in importance_dicts:
            importances.update(i)

        importances = pd.Series(importances).sort_values(ascending=ascending)

        if not importances.sum() > 0:
            self.interpreter.logger.debug("Importances that caused a bug: {}".format(importances))
            raise(FeatureImportanceError("Something went wrong. Importances do not sum to a positive value\n"
                                         "This could be due to:\n"
                                         "1) 0 or infinite divisions\n"
                                         "2) perturbed values == original values\n"
                                         "3) feature is a constant\n"
                                         "Please submit an issue here:\n"
                                         "https://github.com/datascienceinc/Skater/issues"))

        importances = divide_zerosafe(importances, (np.ones(importances.shape[0]) * importances.sum()))
        return importances
def feature_importance ( self , model_instance , ascending = True , filter_classes = None , n_jobs = - 1 , progressbar = True , n_samples = 5000 , method = 'prediction-variance' , scorer_type = 'default' , use_scaling = False ) : if filter_classes : err_msg = "members of filter classes must be" "members of model_instance.classes." "Expected members of: {0}\n" "got: {1}" . format ( model_instance . target_names , filter_classes ) filter_classes = list ( filter_classes ) assert all ( [ i in model_instance . target_names for i in filter_classes ] ) , err_msg if n_samples <= self . data_set . n_rows : inputs , labels = self . data_set . generate_sample ( strategy = 'random-choice' , include_y = True , sample = True , n_samples = n_samples ) else : inputs , labels = self . data_set . X , self . data_set . y if method == 'model-scoring' and labels is None : raise FeatureImportanceError ( "If labels are not set, you" "can only use feature importance methods that do " "not require ground truth labels" ) original_predictions = model_instance . predict ( inputs ) n_jobs = None if n_jobs < 0 else n_jobs predict_fn = model_instance . _get_static_predictor ( ) # Changes made to skater class due to multiprocessing incompatibility with GRPC when using docker # Changes begin here arg_list = self . data_set . feature_ids scorer = model_instance . scorers . get_scorer_function ( scorer_type = scorer_type ) if progressbar : self . interpreter . logger . warn ( "Progress bars slow down runs by 10-20%. For slightly \n" "faster runs, do progress_bar=False" ) n_iter = len ( self . data_set . feature_ids ) p = ProgressBar ( n_iter , units = 'features' ) fi_func = partial ( compute_feature_importance , input_data = inputs , estimator_fn = predict_fn , original_predictions = original_predictions , feature_info = self . data_set . feature_info , feature_names = self . data_set . feature_ids , training_labels = labels , method = method , scaled = use_scaling , scorer = scorer ) # Multiprocessing results in issues with GRPC when using Docker, using single process # More information here: https://github.com/grpc/grpc/blob/master/doc/fork_support.md importances = { } importance_dicts = [ ] for importance in map ( fi_func , arg_list ) : importance_dicts . append ( importance ) if progressbar : p . animate ( ) # Changes end here # Original code #executor_instance = Pool(n_jobs) #arg_list = self.data_set.feature_ids #scorer = model_instance.scorers.get_scorer_function(scorer_type=scorer_type) #if progressbar: #   self.interpreter.logger.warn("Progress bars slow down runs by 10-20%. For slightly \n" #                               "faster runs, do progress_bar=False") # n_iter = len(self.data_set.feature_ids) #p = ProgressBar(n_iter, units='features') #mapper = executor_instance.imap #else: #mapper = executor_instance.map #fi_func = partial(compute_feature_importance, #                 input_data=inputs, #                estimator_fn=predict_fn, #               original_predictions=original_predictions, #              feature_info=self.data_set.feature_info, #             feature_names=self.data_set.feature_ids, #            training_labels=labels, #           method=method, #          scaled=use_scaling, #         scorer=scorer) #importances = {} #try: #   if n_jobs == 1: #      raise ValueError("Skipping to single processing") # importance_dicts = [] #for importance in mapper(fi_func, arg_list): #   importance_dicts.append(importance) #  if progressbar: #     p.animate() #except: #   self.interpreter.logger.warn("Multiprocessing failed, going single process") #  importance_dicts = [] # for importance in map(fi_func, arg_list): #    importance_dicts.append(importance) #   if progressbar: #      p.animate() #finally: #   executor_instance.close() #  executor_instance.join() # executor_instance.terminate() for i in importance_dicts : importances . update ( i ) importances = pd . Series ( importances ) . sort_values ( ascending = ascending ) if not importances . sum ( ) > 0 : self . interpreter . logger . debug ( "Importances that caused a bug: {}" . format ( importances ) ) raise ( FeatureImportanceError ( "Something went wrong. Importances do not sum to a positive value\n" "This could be due to:\n" "1) 0 or infinite divisions\n" "2) perturbed values == original values\n" "3) feature is a constant\n" "Please submit an issue here:\n" "https://github.com/datascienceinc/Skater/issues" ) ) importances = divide_zerosafe ( importances , ( np . ones ( importances . shape [ 0 ] ) * importances . sum ( ) ) ) return importances