class_docstr: Bayesian online change point detection algorithm described by
  `Adams & MacKay (2007) <https://arxiv.org/abs/0710.3742>`__.
  At a high level, this algorithm models the observed data using Bayesian conjugate priors. If an observed value
  deviates too much from the current posterior distribution, it is likely a change point, and we should start
  modeling the time series from that point forwards with a freshly initialized Bayesian conjugate prior.
  
  The ``get_anomaly_score()`` method returns a z-score corresponding to the probability of each point being
  a change point. The ``forecast()`` method returns the predicted values (and standard error) of the underlying
  piecewise model on the relevant data.
class_docstr_tok: ["Bayesian","online","change","point","detection","algorithm","described","by","`","Adams","&","MacKay","(","2007",")","<","https",":","\/\/arxiv.org\/abs\/0710.3742",">","`","__",".","At","a","high","level",",","this","algorithm","models","the","observed","data","using","Bayesian","conjugate","priors",".","If","an","observed","value","deviates","too","much","from","the","current","posterior","distribution",",","it","is","likely","a","change","point",",","and","we","should","start","modeling","the","time","series","from","that","point","forwards","with","a","freshly","initialized","Bayesian","conjugate","prior",".","The","``","get_anomaly_score","(",")","``","method","returns","a","z-score","corresponding","to","the","probability","of","each","point","being","a","change","point",".","The","``","forecast","(",")","``","method","returns","the","predicted","values","(","and","standard","error",")","of","the","underlying","piecewise","model","on","the","relevant","data","."]
code: def last_train_time(self):
      return (
          None
          if len(self.train_timestamps) == 0
          else to_pd_datetime(self.train_timestamps[-1])
      )
  
imports: import bisect
  import copy
  from enum import Enum
  import logging
  from typing import List, Tuple, Union
  import warnings
  import numpy
  import pandas
  import scipy.sparse
  from scipy.special import logsumexp
  from scipy.stats import norm
  from tqdm import tqdm
  from merlion.models.anomaly.base import NoCalibrationDetectorConfig, DetectorBase
  from merlion.models.anomaly.forecast_based.base import ForecastingDetectorBase
  from merlion.models.forecast.base import ForecasterConfig
  from merlion.plot import Figure
  from merlion.post_process.threshold import AggregateAlarms
  from merlion.utils.conj_priors import ConjPrior, MVNormInvWishart, BayesianMVLinReg
  from merlion.utils.time_series import TimeSeries, UnivariateTimeSeries, to_pd_datetime
label_desc: Use image node_id 6 for calling the BOCPD obj's underlying member method code with example usage: obj.last_train_time() and returns: unknown