class_docstr: Bayesian or-of-and algorithm.
  Generates patterns that satisfy the minimum support and maximum length and then select the Nrules rules that have the highest entropy.
  In function SA_patternbased, each local maximum is stored in maps and the best BOA is returned.
  Remember here the BOA contains only the index of selected rules from Nrules self.rules_
class_docstr_tok: ["Bayesian","or-of-and","algorithm",".","Generates","patterns","that","satisfy","the","minimum","support","and","maximum","length","and","then","select","the","Nrules","rules","that","have","the","highest","entropy",".","In","function","SA_patternbased",",","each","local","maximum","is","stored","in","maps","and","the","best","BOA","is","returned",".","Remember","here","the","BOA","contains","only","the","index","of","selected","rules","from","Nrules","self.rules_"]
docstr: Screening rules using information gain
          
docstr_tok: ["Screening","rules","using","information","gain"]
code: def _screen_rules(self, df, y, verbose):
      """Screening rules using information gain"""
      item_ind_dict = {}
      for i, name in enumerate(df.columns):
          item_ind_dict[name] = i
      indices = np.array(
          list(
              itertools.chain.from_iterable(
                  [
                      [item_ind_dict[x] for x in rule]
                      for rule in self.rules_
                  ]
              )
          )
      )
      len_rules = [len(rule) for rule in self.rules_]
      indptr = list(_accumulate(len_rules))
      indptr.insert(0, 0)
      indptr = np.array(indptr)
      data = np.ones(len(indices))
      rule_matrix = csc_matrix(
          (data, indices, indptr),
          shape=(len(df.columns), len(self.rules_)),
      )
      mat = df.values @ rule_matrix
      print("mat.shape", mat.shape)
      len_matrix = np.array([len_rules] * df.shape[0])
      Z = (mat == len_matrix).astype(int)
      Zpos = [Z[i] for i in np.where(y > 0)][0]
      TP = np.sum(Zpos, axis=0)
      supp_select = np.where(TP >= self.supp * sum(y) / 100)[0]
      FP = np.sum(Z, axis=0) - TP
      TN = len(y) - np.sum(y) - FP
      FN = np.sum(y) - TP
      p1 = TP.astype(float) / (TP + FP)
      p2 = FN.astype(float) / (FN + TN)
      pp = (TP + FP).astype(float) / (TP + FP + TN + FN)
      # p1 = np.clip(p1, a_min=1e-10, a_max=1-1e-10)
      print(
          "\n\n\n\np1.shape",
          p1.shape,
          "pp.shape",
          pp.shape,
          "cond_entropy.shape",
      )  # , cond_entropy.shape)
      with warnings.catch_warnings():
          if not verbose:
              warnings.simplefilter(
                  "ignore"
              )  # ignore warnings about invalid values (e.g. log(0))
          cond_entropy = -pp * (
              p1 * np.log(p1) + (1 - p1) * np.log(1 - p1)
          ) - (1 - pp) * (p2 * np.log(p2) + (1 - p2) * np.log(1 - p2))
          cond_entropy[p1 * (1 - p1) == 0] = -(
              (1 - pp) * (p2 * np.log(p2) + (1 - p2) * np.log(1 - p2))
          )[p1 * (1 - p1) == 0]
          cond_entropy[p2 * (1 - p2) == 0] = -(
              pp * (p1 * np.log(p1) + (1 - p1) * np.log(1 - p1))
          )[p2 * (1 - p2) == 0]
          cond_entropy[p1 * (1 - p1) * p2 * (1 - p2) == 0] = 0
      select = np.argsort(cond_entropy[supp_select])[::-1][
          -self.n_rules :
      ]
      self.rules_ = [self.rules_[i] for i in supp_select[select]]
      self.RMatrix = np.array(Z[:, supp_select[select]])
  
imports: import itertools
  import operator
  import os
  import warnings
  from os.path import join
  from bisect import bisect_left
  from collections import defaultdict
  from copy import deepcopy
  from itertools import combinations
  from random import sample
  import numpy
  import pandas
  from mlxtend.frequent_patterns import fpgrowth
  from numpy.random import random
  from pandas import read_csv
  from scipy.sparse import csc_matrix
  from sklearn.base import BaseEstimator, ClassifierMixin
  from sklearn.ensemble import RandomForestClassifier
  from sklearn.utils.multiclass import check_classification_targets
  from sklearn.utils.validation import check_X_y, check_is_fitted
  from imodels.rule_set.rule_set import RuleSet
  from imodels.util.arguments import check_fit_arguments
label_desc: Use image node_id 8 for calling the BayesianRuleSetClassifier obj's underlying member method code with example usage: obj._screen_rules(df, y, verbose) without return types