class_docstr: An estimator that supports building rules as described in
  A Simple, Fast, and Effective Rule Learner (1999). Intended to be used
  as part of the SlipperRulesClassifier.
class_docstr_tok: ["An","estimator","that","supports","building","rules","as","described","in","A","Simple",",","Fast",",","and","Effective","Rule","Learner","(","1999",")",".","Intended","to","be","used","as","part","of","the","SlipperRulesClassifier","."]
docstr: Starts with empty conjunction of conditions and
  greedily adds rules to maximize Z_tilde
docstr_tok: ["Starts","with","empty","conjunction","of","conditions","and","greedily","adds","rules","to","maximize","Z_tilde"]
code: def _grow_rule(self, X, y):
      """Starts with empty conjunction of conditions and
      greedily adds rules to maximize Z_tilde
      """
  
      stop_condition = False
      features = list(range(X.shape[1]))
  
      # rule is stored as a list of dictionaries, each dictionary is a condition
      curr_rule = []
  
      while not stop_condition:
          candidate_rule = curr_rule.copy()
          for feat in features:
              try:
                  pivots = np.percentile(
                      X[:, feat], range(0, 100, 4), method="linear"
                  )
              except:
                  pivots = np.percentile(
                      X[:, feat],
                      range(0, 100, 4),  # deprecated
                      interpolation="midpoint",
                  )
              # get a list of possible rules
              feature_candidates = [
                  self._make_candidate(X, y, curr_rule, feat, A_c)
                  for A_c in pivots
              ]
  
              # get max Z_tilde and update candidate accordingly
              tildes = [
                  self._grow_rule_obj(X, y, r)
                  for r in feature_candidates
              ]
              if max(tildes) > self._grow_rule_obj(
                  X, y, candidate_rule
              ):
                  candidate_rule = feature_candidates[
                      tildes.index(max(tildes))
                  ]
  
          preds = self._rule_predict(X, candidate_rule)
          negative_coverage = np.where((preds == y) & (y == 0))
  
          if (
              self._grow_rule_obj(X, y, curr_rule)
              >= self._grow_rule_obj(X, y, candidate_rule)
              or len(negative_coverage) == 0
          ):
              stop_condition = True
          else:
              curr_rule = candidate_rule.copy()
  
      return curr_rule
  
imports: import random
  import numpy
  from sklearn.base import BaseEstimator, ClassifierMixin
  from sklearn.model_selection import train_test_split
  from imodels.util.arguments import check_fit_arguments
label_desc: Use image node_id 8 for calling the SlipperBaseEstimator obj's underlying member method code with example usage: obj._grow_rule(X, y) and returns: curr_rule