docstr: Add information of hyperparameter tuning to the report.
  
  Args:
      notes(str): Explain the block
      history(:dict of dict): a dict of training log dict.
          key: iteration index
          value: hyperparameter tuning information
                  Each dict has two keys:
                      - params: a dict of which key is the parameter name
                                  and value is parameter value
                      - val_scores: a dict of which key is the metric name
                                  and value is metric value
      best_idx(str):
          - the best idx based on benchmark metric, corresponding the `history` dict key
      search_space(:dict): parameter name and the search space for each parameter
      benchmark_metric(:str): the metric used for benchmarking during hyperparameter tuning
      benchmark_threshold(:float, Optional): the benchmarking threshold to accept the training
      non_hyperopt_score(:float, Optional): the training metric without hyperparameter tuning
docstr_tok: ["Add","information","of","hyperparameter","tuning","to","the","report",".","Args",":","notes","(","str",")",":","Explain","the","block","history","(",":","dict","of","dict",")",":","a","dict","of","training","log","dict",".","key",":","iteration","index","value",":","hyperparameter","tuning","information","Each","dict","has","two","keys",":","-","params",":","a","dict","of","which","key","is","the","parameter","name","and","value","is","parameter","value","-","val_scores",":","a","dict","of","which","key","is","the","metric","name","and","value","is","metric","value","best_idx","(","str",")",":","-","the","best","idx","based","on","benchmark","metric",",","corresponding","the","`","history","`","dict","key","search_space","(",":","dict",")",":","parameter","name","and","the","search","space","for","each","parameter","benchmark_metric","(",":","str",")",":","the","metric","used","for","benchmarking","during","hyperparameter","tuning","benchmark_threshold","(",":","float",",","Optional",")",":","the","benchmarking","threshold","to","accept","the","training","non_hyperopt_score","(",":","float",",","Optional",")",":","the","training","metric","without","hyperparameter","tuning"]
code: def draw_hyperparameter_tuning(
      self,
      notes: str,
      *,
      history: dict,
      best_idx: str,
      search_space=None,
      benchmark_metric=None,
      benchmark_threshold=None,
      non_hyperopt_score=None,
  ):
      """
      Add information of hyperparameter tuning to the report.
  
      Args:
          notes(str): Explain the block
          history(:dict of dict): a dict of training log dict.
              key: iteration index
              value: hyperparameter tuning information
                      Each dict has two keys:
                          - params: a dict of which key is the parameter name
                                      and value is parameter value
                          - val_scores: a dict of which key is the metric name
                                      and value is metric value
          best_idx(str):
              - the best idx based on benchmark metric, corresponding the `history` dict key
          search_space(:dict): parameter name and the search space for each parameter
          benchmark_metric(:str): the metric used for benchmarking during hyperparameter tuning
          benchmark_threshold(:float, Optional): the benchmarking threshold to accept the training
          non_hyperopt_score(:float, Optional): the training metric without hyperparameter tuning
      """
      from xai.graphs import graph_generator
  
      # -- Draw Content --
      if not (notes is None):
          self.pdf.add_new_line(notes)
      # tuning search space
      self.pdf.add_new_line(
          "Hyperparameter Tuning Search Space", style="BI"
      )
      self.pdf.start_itemize()
      for params, params_search_space in search_space.items():
          self.pdf.add_key_value_pair(params, params_search_space)
      self.pdf.end_itemize()
      self.pdf.ln(5)
  
      # tuning history result
      self.pdf.add_new_line(
          "Hyperparameter Tuning History Result", style="BI"
      )
      self.pdf.add_new_line(
          "The metric results from hyperparameter tuning are shown in the figure."
      )
      self.pdf.start_itemize()
      self.pdf.add_key_value_pair("Benchmark metric", benchmark_metric)
      self.pdf.add_key_value_pair(
          "Benchmark value", benchmark_threshold
      )
      self.pdf.end_itemize()
      image_path = "%s/hyperopt_history.png" % self.figure_path
      image_path = graph_generator.EvaluationLinePlot(
          figure_path=image_path,
          data=history,
          title="hyper_history",
          x_label="Iterations",
          y_label="Metrics Score",
      ).draw(
          benchmark_metric=benchmark_metric,
          benchmark_value=benchmark_threshold,
      )
      self.pdf.add_large_image(image_path)
      self.pdf.ln()
  
      # best result for hyperopt
      self.pdf.add_new_line(
          "Best Result from Hyperparameter Tuning", style="BI"
      )
      self.pdf.add_key_value_pair("The best iteration is ", best_idx)
      self.pdf.add_new_line("Parameters:", style="B")
  
      self.pdf.start_itemize()
      for param_name, param_value in history[best_idx][
          "params"
      ].items():
          self.pdf.add_key_value_pair("%s" % param_name, param_value)
      self.pdf.end_itemize()
      self.pdf.ln()
  
      self.pdf.add_new_line("Validation Results:", style="B")
  
      self.pdf.start_itemize()
      final_metric_value = 0
      for param_name, param_value in history[best_idx][
          "val_scores"
      ].items():
          if param_name == benchmark_metric:
              self.pdf.add_key_value_pair(
                  "%s" % param_name.capitalize(),
                  "%s (benchmarking metric)" % param_value,
              )
              final_metric_value = param_value
          else:
              self.pdf.add_key_value_pair(
                  "%s" % param_name.capitalize(), "%s" % param_value
              )
      self.pdf.end_itemize()
      self.pdf.ln(5)
  
      # Tuning final conclusion
      self.pdf.add_new_line(
          "Hyperparameter Tuning Final Conclusion", style="BI"
      )
      if non_hyperopt_score is None:
          self.pdf.add_new_line(
              "There is no benchmarking conducted in this training. "
          )
          self.pdf.add_new_line(
              "We will accept the best result from hyperparameter tuning as final parameter set."
          )
      else:
          if final_metric_value > non_hyperopt_score:
              self.pdf.add_text(
                  "Hyperparameter tuning best result (%.4f) is better than benchmark score (%.4f),"
                  % (final_metric_value, non_hyperopt_score)
              )
              if final_metric_value > benchmark_threshold:
                  self.pdf.add_new_line(
                      " and it is better than acceptance benchmark scoring (%.4f)."
                      % benchmark_threshold
                  )
                  self.pdf.add_new_line(
                      "<BR>We accept it as the final parameter setting for the trained model."
                  )
              else:
                  self.pdf.add_new_line(
                      " but it fails to meet the acceptance benchmark scoring (%.4f)."
                      % benchmark_threshold
                  )
                  self.pdf.add_new_line(
                      "We still accept it as the final parameter setting for the trained model, "
                      "but will continue to improve it."
                  )
  
          else:
              self.pdf.add_text(
                  "Hyperparameter tuning best result (%.4f) is worse than benchmark score (%.4f), "
                  % (final_metric_value, non_hyperopt_score)
              )
  
              if final_metric_value > benchmark_threshold:
                  self.pdf.add_new_line(
                      "and benchmarking result is better than acceptance benchmark scoring (%.4f)."
                      % benchmark_threshold
                  )
                  self.pdf.add_new_line(
                      "We accept default parameters as the final solution for the trained model."
                  )
              else:
                  self.pdf.add_new_line(
                      "but it fails to meet the acceptance benchmark scoring (%.4f)."
                      % benchmark_threshold
                  )
                  self.pdf.add_new_line(
                      "We still accept default parameters as the final solution for the trained model, "
                      "but will continue to improve it."
                  )
      self.pdf.ln(5)
  
imports: from __future__ import absolute_import
  from __future__ import division
  from __future__ import print_function
  import copy
  import os
  import tempfile
  import warnings
  import numpy
  import shutil
  from typing import Tuple, Dict, List
  from xai import MODE
  from xai.data.constants import DatetimeResolution
  from xai.data.explorer import CategoricalStats, NumericalStats, TextStats, DatetimeStats
  from xai.formatter.contents import Title, SectionTitle, Header
  from xai.formatter.portable_document.publisher import CustomPdf
  from xai.formatter.report.section import OverviewSection, DetailSection
  from xai.formatter.writer import Writer
label_desc: Use image node_id 25 for calling the PdfWriter obj's underlying member method code with example usage: obj.draw_hyperparameter_tuning(notes) without return types