class_docstr: Class to build a VAR model
      
class_docstr_tok: ["Class","to","build","a","VAR","model"]
docstr: Given a dataset, finds the best parameters using the settings in the class
docstr_tok: ["Given","a","dataset",",","finds","the","best","parameters","using","the","settings","in","the","class"]
code: def find_best_parameters(self, data: pd.DataFrame):
      """
      Given a dataset, finds the best parameters using the settings in the class
      """
      #### dmax here means the column number of the data frame: it serves as a placeholder for columns
      dmax = data.shape[1]
      ###############################################################################################
      cols = data.columns.tolist()
      # TODO: #14 Make sure that we have a way to not rely on column order to determine the target
      # It is assumed that the first column of the dataframe is the target variable ####
      ### make sure that is the case before doing this program ####################
      i = 1
      results_dict = {}
  
      for d_val in range(1, dmax):
          # Takes the target column and one other endogenous column at a time
          # and makes a prediction based on that. Then selects the best
          # exogenous column at the end.
          y_train = data.iloc[:, [0, d_val]]
          print("\nAdditional Variable in VAR model = %s" % cols[d_val])
          info_criteria = pd.DataFrame(
              index=[
                  "AR{}".format(i) for i in range(0, self.p_max + 1)
              ],
              columns=[
                  "MA{}".format(i) for i in range(0, self.q_max + 1)
              ],
          )
          for p_val, q_val in itertools.product(
              range(0, self.p_max + 1), range(0, self.q_max + 1)
          ):
              if p_val == 0 and q_val == 0:
                  info_criteria.loc[
                      "AR{}".format(p_val), "MA{}".format(q_val)
                  ] = np.nan
                  print(" Iteration %d completed" % i)
                  i += 1
              else:
                  try:
                      model = VARMAX(
                          y_train, order=(p_val, q_val), trend="c"
                      )
                      model = model.fit(max_iter=1000, disp=False)
                      info_criteria.loc[
                          "AR{}".format(p_val), "MA{}".format(q_val)
                      ] = eval("model." + self.scoring)
                      print(" Iteration %d completed" % i)
                      i += 1
                  except Exception:
                      i += 1
                      print(" Iteration %d completed" % i)
          info_criteria = info_criteria[info_criteria.columns].astype(
              float
          )
          interim_d = copy.deepcopy(d_val)
          interim_p, interim_q, interim_bic = find_lowest_pq(
              info_criteria
          )
          if self.verbose == 1:
              _, axis = plt.subplots(figsize=(20, 10))
              axis = sns.heatmap(
                  info_criteria,
                  mask=info_criteria.isnull(),
                  ax=axis,
                  annot=True,
                  fmt=".0f",
              )
              axis.set_title(self.scoring)
          results_dict[
              str(interim_p)
              + " "
              + str(interim_d)
              + " "
              + str(interim_q)
          ] = interim_bic
      best_bic = min(results_dict.items(), key=operator.itemgetter(1))[
          1
      ]
      best_pdq = min(results_dict.items(), key=operator.itemgetter(1))[
          0
      ]
      self.best_p = int(best_pdq.split(" ")[0])
      self.best_d = int(best_pdq.split(" ")[1])
      self.best_q = int(best_pdq.split(" ")[2])
  
      print(
          "Best variable selected for VAR: %s"
          % data.columns.tolist()[self.best_d]
      )
  
imports: import pdb
  from typing import Optional
  import warnings
  import itertools
  import operator
  import copy
  import numpy
  import pandas
  from pandas.core.generic import NDFrame
  import dask
  import dask.dataframe
  import matplotlib.pyplot
  import seaborn
  from statsmodels.tsa.statespace.varmax import VARMAX
  from sklearn.model_selection import TimeSeriesSplit
  from ...utils import print_dynamic_rmse
  from ...models.ar_based.param_finder import find_lowest_pq
  from ..build_base import BuildBase
label_desc: Use image node_id 4 for calling the BuildVAR obj's underlying member method code with example usage: obj.find_best_parameters(data) without return types