class_docstr: Implementation of Fredrikson et al. white box inference attack for decision trees.
  
  Assumes that the attacked feature is discrete or categorical, with limited number of possible values. For example:
  a boolean feature.
  
  | Paper link: https://dl.acm.org/doi/10.1145/2810103.2813677
class_docstr_tok: ["Implementation","of","Fredrikson","et","al",".","white","box","inference","attack","for","decision","trees",".","Assumes","that","the","attacked","feature","is","discrete","or","categorical",",","with","limited","number","of","possible","values",".","For","example",":","a","boolean","feature",".","|","Paper","link",":","https",":","\/\/dl.acm.org\/doi\/10.1145\/2810103.2813677"]
docstr: Infer the attacked feature.
  
  :param x: Input to attack. Includes all features except the attacked feature.
  :param y: Not used.
  :param values: Possible values for attacked feature.
  :type values: list
  :param priors: Prior distributions of attacked feature values. Same size array as `values`.
  :type priors: list
  :return: The inferred feature values.
  :rtype: `np.ndarray`
docstr_tok: ["Infer","the","attacked","feature",".",":","param","x",":","Input","to","attack",".","Includes","all","features","except","the","attacked","feature",".",":","param","y",":","Not","used",".",":","param","values",":","Possible","values","for","attacked","feature",".",":","type","values",":","list",":","param","priors",":","Prior","distributions","of","attacked","feature","values",".","Same","size","array","as","`","values","`",".",":","type","priors",":","list",":","return",":","The","inferred","feature","values",".",":","rtype",":","`","np.ndarray","`"]
code: def infer(
      self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs
  ) -> np.ndarray:
      """
      Infer the attacked feature.
  
      :param x: Input to attack. Includes all features except the attacked feature.
      :param y: Not used.
      :param values: Possible values for attacked feature.
      :type values: list
      :param priors: Prior distributions of attacked feature values. Same size array as `values`.
      :type priors: list
      :return: The inferred feature values.
      :rtype: `np.ndarray`
      """
      priors: Optional[list] = kwargs.get("priors")
      values: Optional[list] = kwargs.get("values")
  
      # Checks:
      if (
          self.estimator.input_shape[0] != x.shape[1] + 1
      ):  # pragma: no cover
          raise ValueError(
              "Number of features in x + 1 does not match input_shape of classifier"
          )
      if priors is None or values is None:  # pragma: no cover
          raise ValueError(
              "`priors` and `values` are required as inputs."
          )
      if len(priors) != len(values):  # pragma: no cover
          raise ValueError(
              "Number of priors does not match number of values"
          )
      if self.attack_feature >= x.shape[1]:  # pragma: no cover
          raise ValueError(
              "attack_feature must be a valid index to a feature in x"
          )
  
      n_samples = x.shape[0]
  
      # Calculate phi for each possible value of the attacked feature
      # phi is the total number of samples in all tree leaves corresponding to this value
      phi = self._calculate_phi(x, values, n_samples)
  
      # Will contain the probability of each value
      prob_values = []
  
      for i, value in enumerate(values):
          # prepare data with the given value in the attacked feature
          v_full = np.full((n_samples, 1), value).astype(x.dtype)
          x_value = np.concatenate(
              (x[:, : self.attack_feature], v_full), axis=1
          )
          x_value = np.concatenate(
              (x_value, x[:, self.attack_feature :]), axis=1
          )
  
          # find the relative probability of this value for all samples being attacked
          prob_value = [
              (
                  (
                      self.estimator.get_samples_at_node(
                          self.estimator.get_decision_path([row])[-1]
                      )
                      / n_samples
                  )
                  * priors[i]
                  / phi[i]
              )
              for row in x_value
          ]
          prob_values.append(prob_value)
  
      # Choose the value with highest probability for each sample
      return np.array(
          [values[np.argmax(list(prob))] for prob in zip(*prob_values)]
      )
  
file_path: adversarial-robustness-toolbox/art/attacks/inference/attribute_inference/white_box_lifestyle_decision_tree.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, Union, TYPE_CHECKING
  import numpy
  from art.attacks.attack import AttributeInferenceAttack
  from art.estimators.classification.scikitlearn import ScikitlearnDecisionTreeClassifier
  from art.estimators.regression.scikitlearn import ScikitlearnDecisionTreeRegressor
label_desc: Use image node_id 2 for calling the AttributeInferenceWhiteBoxLifestyleDecisionTree obj's underlying member method code with example usage: obj.infer(x, y) and returns: np