class_docstr: Creates a one-hot-encoding for binary class data. Assume two arbitrary categories :math:`A` and :math:`B`; representation for them will be as such:
  
   .. math::
  
      A &= [1, 0] \
      B &= [0, 1]
  
   This encoder is a specialized case of one-hot encoding (OHE); unknown categories are explicitly handled as [0, 0]. Unknowns may only be reported if the input row value is NULL (or python `None` type) or if new data, after the encoder is prepared, has examples outside the feature map.
  
   When data is typed with Lightwood, this class is only deployed if an input data type is explicitly recognized as binary (i.e. the column has only 2 unique values like True/False). If future data shows a new category (thus the data is no longer truly binary), this encoder will no longer be appropriate unless you are comfortable mapping ALL new classes as [0, 0].
  
   An encoder can represent a feature column or target column; in this case it represents a target, `is_target` is `True`, and `target_weights`. The `target_weights` parameter enables users to specify how heavily each class should be weighted within a mixer - useful in imbalanced classes. 
  
   By default, `dataprep_ml.StatisticalAnalysis` phase will provide `target_weights` as the relative fraction of each class in the data which is important for imbalanced populations; for example, suppose there is a 80/20 imbalanced representation across 3 different classes - `target_weights` will be a vector as such::
  
   target_weights = {"class1": 0.8, "class2": 0.2}
  
   Users should note that models will be presented with the inverse of the target weights, `inv_target_weights`, which will perform the 1/target_value_per_class operation. **This means large values will result in small weights for the model**.
   
docstr: Given priming data, create a map/inverse-map corresponding category name to index (and vice versa).
  
  :param priming_data: Binary data to encode
docstr_tok: ["Given","priming","data",",","create","a","map\/inverse-map","corresponding","category","name","to","index","(","and","vice","versa",")",".",":","param","priming_data",":","Binary","data","to","encode"]
code: def prepare(self, priming_data: Iterable[str]):
      """
      Given priming data, create a map/inverse-map corresponding category name to index (and vice versa).
  
      :param priming_data: Binary data to encode
      """  # noqa
      if self.is_prepared:
          raise Exception(
              'You can only call "prepare" once for a given encoder.'
          )
  
      unq_cats = np.unique(
          [i for i in priming_data if i is not None]
      ).tolist()
  
      self.map = {cat: indx for indx, cat in enumerate(unq_cats)}
      self.rev_map = {indx: cat for cat, indx in self.map.items()}
  
      # Enforce only binary; map must have exactly 2 classes.
      if (
          len(self.map) > 2
          and self.handle_unknown == "use_encoded_value"
      ):
          log.warning(
              "Warning: dtype for binary encoder has > 2 classes. Extra classes will be pointed to an invalid token. Try overriding this encoder with a multi-class categorical encoder, otherwise performance may not be optimal."
          )  # noqa
          log.warning(f"Observed classes are: {self.map}.")
      elif self.handle_unknown == "error":
          raise ValueError(
              f"Data has > 2 classes and encoder is in strict mode. Aborting. All classes are: {self.map}."
          )  # noqa
  
      # For target-only, report on relative weights of classes
      if self.is_target:
          self.index_weights = torch.ones(
              self.output_size
          )  # Equally wt. both classes
  
          # If target weights provided, weight by inverse
          if self.target_weights is not None:
              # Check target weights properly specified
              if (
                  sum(
                      [
                          np.isclose(i, 0)
                          for i in self.target_weights.values()
                      ]
                  )
                  > 0
              ):
                  raise ValueError("Target weights cannot be 0")
  
              # Ensure all classes are specified in the weights criteria
              assert set(self.target_weights.keys()) == set(
                  self.map.keys()
              )
  
              for cat in self.map.keys():
                  self.index_weights[
                      self.map[cat]
                  ] = self.target_weights[cat]
  
      self.is_prepared = True
  
file_path: lightwood/lightwood/encoder/categorical/binary.py
imports: from copy import deepcopy
  from typing import Dict, List, Iterable, Tuple
  import torch
  import numpy
  from scipy.special import softmax
  from lightwood.encoder.base import BaseEncoder
  from lightwood.helpers.constants import _UNCOMMON_WORD
  from lightwood.helpers.log import log
label_desc: Use image node_id 2 for calling the BinaryEncoder obj's underlying member method code with example usage: obj.prepare(priming_data) without return types