class_docstr: Accumulator which maintains summary statistics describing an anomaly
  detection algorithm's performance. Can be used to compute many different
  time series anomaly detection metrics.
docstr: Computes the NAB score, given the accumulated performance metrics and
  the specified weights for different types of errors. The score is
  described in section II.C of https://arxiv.org/pdf/1510.03336.pdf.
  At a high level, this score is a cost-sensitive, recency-weighted
  accuracy measure for time series anomaly detection.
  
  NAB uses the following profiles for benchmarking
  (https://github.com/numenta/NAB/blob/master/config/profiles.json):
  
  -   standard (default)
      -   tp_weight = 1.0, fp_weight = 0.11, fn_weight = 1.0
  -   reward low false positive rate
      -   tp_weight = 1.0, fp_weight = 0.22, fn_weight = 1.0
  -   reward low false negative rate
      -   tp_weight = 1.0, fp_weight = 0.11, fn_weight = 2.0
  
  Note that tn_weight is ignored.
  
  :param tp_weight: relative weight of true positives.
  :param fp_weight: relative weight of false positives.
  :param fn_weight: relative weight of false negatives.
  :param tn_weight: relative weight of true negatives. Ignored, but
      included for completeness.
  :return: NAB score
code: def nab_score(
      self, tp_weight=1.0, fp_weight=0.11, fn_weight=1.0, tn_weight=0.0
  ):
      """
      Computes the NAB score, given the accumulated performance metrics and
      the specified weights for different types of errors. The score is
      described in section II.C of https://arxiv.org/pdf/1510.03336.pdf.
      At a high level, this score is a cost-sensitive, recency-weighted
      accuracy measure for time series anomaly detection.
  
      NAB uses the following profiles for benchmarking
      (https://github.com/numenta/NAB/blob/master/config/profiles.json):
  
      -   standard (default)
          -   tp_weight = 1.0, fp_weight = 0.11, fn_weight = 1.0
      -   reward low false positive rate
          -   tp_weight = 1.0, fp_weight = 0.22, fn_weight = 1.0
      -   reward low false negative rate
          -   tp_weight = 1.0, fp_weight = 0.11, fn_weight = 2.0
  
      Note that tn_weight is ignored.
  
      :param tp_weight: relative weight of true positives.
      :param fp_weight: relative weight of false positives.
      :param fn_weight: relative weight of false negatives.
      :param tn_weight: relative weight of true negatives. Ignored, but
          included for completeness.
      :return: NAB score
      """
      # null: label everything as negative
      null_score = -(self.num_tp_anom + self.num_fn_anom) * fn_weight
      # perfect: detect all anomalies as early as possible, no false positives
      perfect_score = (self.num_tp_anom + self.num_fn_anom) * tp_weight
      # our score is based on our model's performance
      score = (
          self.tp_score * tp_weight
          - self.fp_score * fp_weight
          - self.num_fn_anom * fn_weight
      )
      return (score - null_score) / (perfect_score - null_score + 1e-8)
  
imports: from bisect import bisect_left
  from enum import Enum
  from functools import partial
  from typing import Tuple, Union
  import numpy
  import pandas
  from merlion.evaluate.base import EvaluatorBase, EvaluatorConfig
  from merlion.utils import TimeSeries, UnivariateTimeSeries
  from merlion.utils.misc import call_with_accepted_kwargs
label_desc: Use image node_id 10 for calling the TSADScoreAccumulator obj's underlying member method code with example usage: obj.nab_score(tp_weight, fp_weight, fn_weight, tn_weight) and returns: unknown